<p>Almost all languages have comments, but the syntax for comments can vary wildly between them. What are commonly used options for comment syntax, and what are their advantages and disadvantages?</p>

<syntax><comments>
What are common options for comment syntax?
<h2>Python-style comments</h2>
<ul>
<li><p><code>#</code> starts a single-line comment. It's only one character, so it's quick and easy to type.</p>
</li>
<li><p><code>&quot;&quot;&quot;</code> or <code>'''</code> delimit multi-line comments. These are actually &quot;docstrings&quot;, but they can also be used as comments. They are three characters on each side, so it's a bit longer to type. They are also ambiguous, since they can also be used for multi-line strings.</p>
</li>
</ul>
<p><strong>Examples:</strong></p>
<pre class="lang-python prettyprint-override"><code># comment

&quot;&quot;&quot;multi
line
comment&quot;&quot;&quot;

'''
this as well
'''
</code></pre>

CC BY-SA 4.0
2023-05-19T16:55:43.707Z
2023-05-19T16:55:43.707Z
The Thonnu
CC BY-SA 4.0
2023-07-05T11:17:06.320Z
Note that docstrings are *not* comments. They are syntactic sugar for assigning to an attribute named `__doc__`. The whole point of docstrings is that, unlike comments, they are *not* ignored but kept around at runtime so you can query them at runtime.
Jörg W Mittag
CC BY-SA 4.0
2023-07-05T14:48:18.490Z
@JörgWMittag I know, but they are essentially used as multi-line comments
The Thonnu
CC BY-SA 4.0
2023-12-19T15:47:27.153Z
`'''` and `"""` enclose multiline string literals. Docstrings in Python are simply when _any_ string literal forms the first statement of a module, class or function.
Jasmijn
<p>The choice of comments should come down to basically one thing: What language or family of languages are you emulating?</p>
<p>C and its enormous family of languages generally use <code>//</code> for single line comments and <code>/* */</code> for block comments. I would recommend this style of comments because they are the most widespread. They'll also let you play with JavaDoc documentation, which is usually implemented as <code>/** */</code> or <code>///</code> in some cases.</p>
<p>The other most common style of comment is to use <code>#</code>. This is usually found in older languages like ShellScript and languages that borrow from them like Python. Most of this languages only support single line comments, however, so this style of comments may feel slightly limited. You could maybe implement your own block comments by using <code>###</code> or any combination of characters that you fancy.</p>
<p>I wouldn't recommend using outlandish comment syntaxes just to keep the language approachable.</p>
<p>P.S.:
I'll give XML and its many children a mention for only having block comments (denoted with <code>&lt;!-- --&gt;</code>). Having only block comments might be something interesting to try out in a more esoteric language.</p>

CC BY-SA 4.0
2023-05-21T06:56:04.880Z
2023-05-21T06:56:04.880Z
just Paul
CC BY-SA 4.0
2024-01-12T11:51:27.643Z
Technically speaking, `<!` is the start of a *directive* and `>` is the end of a directive. `--` is a *comment toggle*, meaning it *toggles between comment and non-comment mode*. This means that `<!-- This is a comment--I think -->` does not do what you expect!
Jörg W Mittag
<p><a href="https://newspeaklanguage.org/" rel="nofollow noreferrer">Newspeak</a> has <a href="https://newspeaklanguage.org/spec/newspeak-spec.pdf" rel="nofollow noreferrer"><em>nested metadata</em></a> which looks like this:</p>
<pre class="lang-smalltalk prettyprint-override"><code>(*:id: xyz *)
</code></pre>
<p>This associates the metadata <em>payload</em> <code>xyz</code> under the metadata <em>tag</em> <code>id</code> with whatever runtime language element follows the metadata comment. This information is kept both in the compiled code and at runtime and can be queried using reflective mirrors. The metadata tag identifies a specific metadata <em>interpreter</em>. (This is, for example, how Newspeak does its optional type annotations.)</p>
<p>In other words, these are similar to <a href="https://wikipedia.org/wiki/Java_annotation" rel="nofollow noreferrer">Java-style <em>annotations</em></a>, <a href="https://learn.microsoft.com/dotnet/csharp/advanced-topics/reflection-and-attributes/" rel="nofollow noreferrer">C#-/.NET-style <em>attributes</em></a>, C++-style attributes, but also have aspects of Python- and ECMAScript-style <em>decorators</em>.</p>
<p>Metadata can <em>nest</em>, i.e. I can annotate metadata with metadata.</p>
<p><em>Comments</em> are simply metadata without a tag:</p>
<pre class="lang-smalltalk prettyprint-override"><code>(* This is a comment (* And this is another, which comments on the outer comment *) *)
</code></pre>
<p>Since they are still metadata, they are attached to the runtime language element which follows them. And this applies to nested comments as well, so the above inner comment is a comment attached to the outer comment.</p>
<p>Since they are attached to actual runtime language elements, it is easy to keep them around and reconstruct them even through large-scale complex automated refactorings. You can do cool stuff like: when catching an <code>ArgumentError</code>, retrieve the documentation comment for the method which raised the exception and show it together with the stack trace. Since the comment is an actual object attached to the actual method object, you can literally just grab it from the stack trace object.</p>

CC BY-SA 4.0
2023-07-05T11:38:44.827Z
2023-07-05T11:38:44.827Z
Jörg W Mittag
<h2>The <code>/*  */</code> notation</h2>
<p>This is what CSS uses.</p>
<p>Example:</p>
<pre><code>/* Some text */
</code></pre>
<p>This method has a number of advantages:</p>
<ul>
<li>Due to it not automatically going to the end of the line (it stops at <code>*/</code>), it can be midway-through a line</li>
<li>It can span several lines if needed:</li>
</ul>
<pre><code>/* Some test
   Some other information
   Even more stuff
 */
</code></pre>

CC BY-SA 4.0
2023-05-19T16:51:51.440Z
2023-05-19T16:52:46.993Z
2023-05-19T16:52:46.993Z
cocomac
CC BY-SA 4.0
2023-05-20T03:18:15.280Z
Not just CSS ─ this comment syntax exists in C, C++, C#, Java, Javascript, PHP, and many more languages. Particularly languages which borrow their syntax from C tend to have this kind of comment.
kaya3
<p>If you use either # or #! as a comment starter, then your file can run directly on Unix via a so-called <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)" rel="nofollow noreferrer">Shebang</a>. That is, on Unix, a file starting with <code>#!</code>(path) will run the file as code under the interpreter at (path). If # or #! is a comment, the interpreter will then skip over the shebang line and all is well</p>
<p>Of course, if you prefer alternative syntax for comments, you could still include a special case for skipping a shebang</p>

CC BY-SA 4.0
2023-05-21T11:35:38.900Z
2023-05-21T11:35:38.900Z
cat-sofia
CC BY-SA 4.0
2023-07-05T11:09:54.153Z
This is very annoying in ECMAScript. Hashbangs only became legal with the June 2023 release.
Jörg W Mittag
CC BY-SA 4.0
2023-07-05T14:46:59.983Z
@JörgWMittag I'll note that it was supported by Node for much longer, even if it wasn't part of the standard.
Bbrk24
<h1>Using the line ending character <code>;</code> as a comment marker</h1>
<p>In many assembly languages, the <code>;</code>, which also marks the end of a statement, also marks the rest of the line a comment, eg:</p>
<pre><code>MOV aex abx  ; move the value to the other register
ADD aex 2    ;   add 2
SUB dex mix  ; I don't think these are even real registers
BNEQ         ; branch not equals
</code></pre>
<p>This is nice since you need one less syntax element</p>

CC BY-SA 4.0
2023-05-19T16:58:12.090Z
2023-05-19T17:00:00.887Z
2023-05-19T17:00:00.887Z
mousetail 'he-him'
CC BY-SA 4.0
2023-05-19T17:33:40.023Z
I don't think I've ever used the semicolon as a line ender in assembly, only as a comment starter. Is there an assembly dialect where this is *required* as a line terminator?
Silvio Mayolo
CC BY-SA 4.0
2023-10-14T17:38:40.363Z
@SilvioMayolo [D's Inline Assembler](https://dlang.org/spec/iasm.html) does require it, and uses `//`, `/*`, `/+` and friends for comments, to be syntactically compatible with higher-level D.
Longinus
CC BY-SA 4.0
2023-10-20T16:01:43.190Z
I wonder if this is what inspired the Lisp designers to use `;` as its comment prefix.
Barmar
CC BY-SA 4.0
2023-11-30T23:01:24.863Z
@Barmar Yes, it was. Maclisp borrowed the notation from PDP-10 assembly.
texdr.aft
<p>Comments generally fall into two flavors: single line comments, which end with a newline, and comments with multi-line support, which typically end with the reverse of the opening token or something similar.</p>
<p>For the former, some of the most common opening tokens are <code>//</code> (Java, C, C++, C#, Rust, etc.), <code>#</code> (Python, Perl, Ruby, various Unix shell languages, etc.) and <code>%</code> (LaTeX, etc.); for the latter, <code>/*</code> (at least for languages inspired by C). Some languages use special exportable (think documentation) comments when the last symbol is repeated (e.g. <code>///</code> for C# and Rust, <code>/**</code> for Java).</p>
<p>A disadvantage of the implementation of multi-line comments in many current languages is that they can't be nested. If you commented out a small part of your code by surrounding it with <code>/*</code> and <code>*/</code>, and want to comment out a larger part which includes the smaller part, that requires some extra attention, because the end token of the inner comment will also finish the outermost one. Still, your language may be able to solve that by requiring a <code>*/</code> for <em>every</em> <code>/*</code> (or equivalently, interpret every <code>/*</code> as starting a new comment, even if it's within another one, and require it to be properly terminated).</p>

CC BY-SA 4.0
2023-05-19T17:00:35.307Z
2023-12-19T12:22:48.940Z
2023-12-19T12:22:48.940Z
Glorfindel
CC BY-SA 4.0
2023-05-19T17:15:33.260Z
Some languages do handle nested `/* */` comments properly. T-SQL is one example.
DLosc
CC BY-SA 4.0
2023-05-19T17:20:13.873Z
Scala also handles nested `/* */` comments properly. There's other styles of nested multiline comments too: `#[ ]#` (Nim), `{- -}` (Haskell), `(* *)` (OCaml), and probably plenty others. OCaml in particular is interesting because it forces comments to contain only valid lexical tokens (no unterminated strings and stuff). I think this is to help with the nesting, but I'm not sure
user
CC BY-SA 4.0
2023-05-19T17:21:37.293Z
Matlab block comment: `%{ %}`, but iirc the open and close comment markers need to be on their own lines.
Bbrk24
CC BY-SA 4.0
2023-05-20T12:39:58.253Z
D uses `/+ +/` for nestable block comments (I don't recommend this, make `/* */` nestable instead). `#= =#` is apparently used by Julia for nestable block comments to complement the `#` for line comments. And of course we have `<!-- -->` in XML.
Nuoji
CC BY-SA 4.0
2023-07-05T17:40:34.340Z
Worth noting that `#` is kind of "special", since it lets you use `#!` in your language without any extra help, which is probably part of the reason it's so common for scripting languages.
CoffeeTableEspresso
CC BY-SA 4.0
2023-07-05T18:09:06.593Z
@user: Yeah, OCaml doesn’t require that nestable block comments’ contents be lexically valid overall, but straight quotes do need to be paired. So you can’t write `(* London Latitude: 51°30'35" N *)`. It means OCaml doesn’t suffer from the corner case in, say, Haskell, where `{- a comment ends with "-}" even in quotes -}`. OCaml’s compromise lets you use block comments both for temporarily disabling code, and for writing documentation that contains code, at the cost of a different, maybe slightly less pointy corner case.
Jon Purdy
<h1>Slashdash Comments</h1>
<p>Along with single line and multi-line comments, the <a href="https://kdl.dev/" rel="noreferrer">document language KDL</a> supports a novel, scope/syntax aware form of comment syntax called &quot;slashdash&quot; comments. In KDL, the token <code>/-</code> will treat the following node, argument, property or children block as a comment, even if it spreads across multiple lines.</p>
<p>In this example, the argument <code>&quot;commented&quot;</code>, the property <code>key=&quot;value&quot;</code>, and the children block <code>{ a; b }</code> are commented out.</p>
<pre><code>mynode /-&quot;commented&quot; &quot;not commented&quot; /-key=&quot;value&quot; /-{
  a
  b
}
</code></pre>
<p>Application of this comment style will obviously somewhat depend on consistency in the language grammar. For example, this could readily be applied to S-expression syntax.</p>
<pre class="lang-lisp prettyprint-override"><code>; the arguments `3` and `(/ 1 0)` are commented out
(+ 1 2 /- 3 4 /- (/ 1 0)) ; yields 1 + 2 + 4 = 7
</code></pre>
<p><a href="https://stitcher.io/blog/slashdash" rel="noreferrer">Brent Roose in this blog post</a> suggests (AFAICT) a <code>/--</code> variant that comments out an entire scope of code for use in less homogeneous languages.</p>
<pre class="lang-php prettyprint-override"><code>// `final` and `implements Bar` are commented out
/-final class Foo /-implements Bar {
    ...
}

// The entire declaration of `Foo` is commented out
/--final class Foo implements Bar {
    ...
}
</code></pre>
<p>Slashdash comments can be an easier and more elegant way of commenting out code. However, it might not be immediately clear what is being commented out. Also, being fairly unknown, it will require some time to explain to users before the concept clicks.</p>

CC BY-SA 4.0
2023-05-20T07:37:31.907Z
2023-05-20T07:37:31.907Z
Olive
CC BY-SA 4.0
2023-07-05T17:39:42.007Z
Racket does something similar, I believe the notation is `#;` but I may be misremembering
CoffeeTableEspresso
<h1>Comments by way of an identity function</h1>
<p>A unique type of comments is through the availability of an infix operator which returns one of its arguments, e.g. <code>⊢</code> in APL which returns its right argument. This allows comments as strings <em>inside</em> expressions:</p>
<pre><code>      2+'comment'⊢5×8
42
</code></pre>

CC BY-SA 4.0
2023-05-19T17:11:01.480Z
2023-05-19T17:11:01.480Z
Adám
CC BY-SA 4.0
2023-10-14T22:59:42.797Z
Could this be emulated in C or C++ by exploiting the comma operator?
Karl Knechtel
CC BY-SA 4.0
2023-10-15T23:20:20.273Z
@KarlKnechtel: It appears that is possible, such as `printf("%d\n", ("number",5));`. However, I would say "abusing" instead of "exploiting", and honestly I've never seen a comment written that way in any C language family code.
Greg Hewgill
<h2>Words</h2>
<p>Batch and BASIC allow you to use <code>REM</code> for comments (although Batch also has <code>::</code> and some implementations of BASIC also have <code>'</code> (see comment by Steffan below)). J has <code>NB.</code>. I'd recommend against using words for comments, though, it keeps people from using useful identifiers and it just looks verbose and weird.</p>

CC BY-SA 4.0
2023-05-19T17:04:17.683Z
2023-05-19T17:46:15.543Z
2023-05-19T17:46:15.543Z
user
CC BY-SA 4.0
2023-05-19T17:26:49.960Z
BASIC also uses `REM`, but it's aliased as `'` in some implementations
naffetS
CC BY-SA 4.0
2023-05-19T18:26:19.377Z
The REM is for REMOVE. This it could be implemented as an operator or otherwise a keyword in the language. Makes sense in something like a shell script (batch files) where lines can be commands anyway `cd temp` or `move from to` are all series of words that start with the command then the parameters. And the parameters can be just arbitrary amount of parameters `touch one two three four` for example. Thus a `rem` command can just be a simple no-op - takes any amount of "parameters" that can be strings and numbers but does not do anything at all.
VLAZ
CC BY-SA 4.0
2023-05-20T22:44:26.653Z
I alwaus thought REM stood for "remark", as a synonym for comment
abel1502
CC BY-SA 4.0
2023-05-21T08:32:47.170Z
@abel1502 that REM stood for remark has always been my understanding also, since learning COMAL80 - a Danish structured BASIC with strong influence from Pascal and Algol 68 - in 1982. COMAL itself iirc supported both REM and // as line comment.
LHP
<h1>Double Slash, Single Line <code>// Comments</code></h1>
<p>This is what languages such as Java use, in addition to multi-line comments. The comment ends at the end of the line and any text immediately after the <code>//</code> will be ignored.</p>
<p>This comment is useful for quick, one line explanations of a certain piece of code. They can easily be placed next to or immediately above a small line of code to show that the comment explains that one line.</p>
<p>As a simplistic example:</p>
<pre class="lang-java prettyprint-override"><code>// Declares a variable 'a' with the value 100
var a = 100;
var b = a * 10; // Declares a variable 'b' with the value 1000
</code></pre>
<p>However, one disadvantage with this syntax, which is true of single line comments as a whole, is that is harder to comment out entire sections of code you want to ignore. Each line must be individually commented out.</p>
<p>This becomes tedious and generally very messy visually.</p>
<pre class="lang-java prettyprint-override"><code>// Ignored code
// for (int i = 0; i &lt; 10; i++) {
//    System.out.println(i);
// }
</code></pre>

CC BY-SA 4.0
2023-05-19T16:57:38.687Z
2023-05-20T11:41:28.413Z
2023-05-20T11:41:28.413Z
FireTheLost
CC BY-SA 4.0
2023-05-19T17:23:00.833Z
Commenting out individual lines is less of a problem in IDEs that have a keyboard shortcut for it (often Ctrl-/).
Bbrk24
<h1>Strings as comments</h1>
<p>This is often seen in Python (see &quot;Python multi-line string&quot; and &quot;Python tripple quoted string&quot;).</p>
<p>With this, programmers can simply use a string as a comment. For example,</p>
<pre class="lang-python prettyprint-override"><code>&quot;&quot;&quot;
Some text here
Some more text
Even more text
&quot;&quot;&quot;
print(&quot;&quot;&quot;Hello world&quot;&quot;&quot;)
</code></pre>
<p>This can be nice as separate syntax isn't needed (though Python has real comments too), but with the trade-off that it might be considered (ab)using a feature. In the case of Python specifically, this is specifically documented in <a href="https://peps.python.org/pep-0257/" rel="noreferrer">PEP 257</a>, so it isn't really abuse there.</p>

CC BY-SA 4.0
2023-05-19T16:57:25.490Z
2023-05-19T16:57:25.490Z
cocomac
CC BY-SA 4.0
2023-05-19T17:46:51.027Z
Personally I dislike this, because it degrades performance.
CPlus
CC BY-SA 4.0
2023-05-19T19:39:16.523Z
@user16217248 How would this degrade performance? The strings would just be initialized and then left untouched for the rest of execution, right?
Ginger
CC BY-SA 4.0
2023-05-19T19:50:16.513Z
@Ginger Initialized is still overhead. Whereas comments are ignored entirely.
CPlus
CC BY-SA 4.0
2023-05-19T20:05:24.437Z
@user16217248 Is the performance loss actually _measurable_, though? Worrying about that feels like worrying that one day a tree will grow where I'm standing.
Ginger
CC BY-SA 4.0
2023-05-20T20:23:43.167Z
A string that is not assigned to anything - or any constant expression in "void context" for that matter - would be trivial to compile into nothing at all. No performance hit whatsoever.

One (minor) disadvantage would be that such a comment can't easily be placed inside an expression. Also, in a language with a statement terminator or separator (typically semicolon), it might look a little awkward.
LHP
CC BY-SA 4.0
2023-07-05T11:16:28.287Z
Note that docstrings are *not* comments. They are syntactic sugar for assigning to an attribute named `__doc__`. The whole point of docstrings is that, unlike comments, they are *not* ignored but kept around at runtime so you can query them at runtime.
Jörg W Mittag
CC BY-SA 4.0
2023-10-14T16:18:03.923Z
This doesn't degrade performance at all, at least beyond the cost of parsing the string literal (which is one-off and negligible, possibly not even more expensive than parsing a comment beginning with `#`). CPython absolutely recognises a string literal on its own as a noop and doesn't emit any bytecode instructions for it.
kaya3
CC BY-SA 4.0
2023-10-15T11:17:41.020Z
Python is a language that is commonly used in ways that execute each line of code only once. In such use cases, it does degrade performance as compilation is a major part in these cases.
feldentm
CC BY-SA 4.0
2023-10-20T16:03:13.637Z
I think Python adopted this from Common Lisp.
Barmar
CC BY-SA 4.0
2023-10-20T16:06:25.920Z
@JörgWMittag They serve a similar purpose as comments, since they explain/describe the code in some way. The fact that they're preserved at runtime doesn't negate that. You can also use string literals outside definitions, and then they really are ignored like comments. Since Python doesn't have multi-line comments like `/* ... */`, triple-quoted strings are often used as a replacement.
Barmar
CC BY-SA 4.0
2023-10-20T16:07:07.027Z
And only a string literal at the beginning of a definition is preserved as a docstring; any others will be ignored.
Barmar
<p>I'm surprised that Lua hasn't been discussed:</p>
<pre class="lang-lua prettyprint-override"><code>-- Singleline

--[[
Multiline with delimiters.
]]

--[=[
[[Delimiters]]
]=]

--[==[
[[can be]] [=[arbitrarily long]=].
]==]
</code></pre>
<p>These delimiters are called <a href="https://www.lua.org/manual/5.4/manual.html#3.1" rel="nofollow noreferrer"><em>opening</em> and <em>closing long brackets</em></a>. The comment nesting problem mentioned by other answers can be easily avoided by increasing the level of the long brackets, as shown in the example above.</p>
<p>What's more, these brackets are also used to delimit (multiline) string literals:</p>
<pre class="lang-lua prettyprint-override"><code>local s = [=[
Foo[[bar]]baz[==[qux]==]
]=]
</code></pre>

CC BY-SA 4.0
2023-10-14T14:14:09.090Z
2023-12-19T21:25:00.543Z
2023-12-19T21:25:00.543Z
InSync
<p>It shouldn't be difficult to list the major comment conventions in use or used in the past. Going back to punch card times, there is the '*' in column 7 for COBOL.</p>
<p>FORTRAN had (has?) a similar convention '*' (or 'C', 'c', 'd', 'D' or '!'?) in column 1 to make a comment line.</p>
<p>Many assembler languages, and I believe also (early?) LISP regard a semicolon and anything following it, until line break, as a comment.</p>
<p>This &quot;remainder-of-line&quot; comment style is also used in BASIC, either with a keyword &quot;REM&quot;, or sometimes a single quote, and in Unix shells and Perl, where the character is '#'.</p>
<p>Non-line oriented (free form) languages, probably beginning with Algol, need a delimiter in both ends. In Algol 60 a comment begins with <strong>comment</strong> and extends to the following ';'. As only another <strong>end</strong> or a ';' can follow an <strong>end</strong> of a block, any text after <strong>end</strong>, up to a ';' (or another <strong>end</strong>?) is also considered a comment. Obviously this may lead to errors. Algol68 introduced comments beginning and ending with the comment symbol, often written as a '¢', but sometimes also '#'. Pascal uses '{' and '}' (or '(<em>' and '</em>)' when the character set does not have curly braces. Originally they didn't nest, but I think some implementations and perhaps recent standards allow comments to nest.</p>
<p>PL/1 uses '/*' and '*/', which was also used by C. (I believe BCPL and B had remainder-of-line comments?) C++ reintroduced '//' remainder-of-line comments. Both types are common in C-inspired languages.</p>
<p>Ada, SQL, SGML (and XML?), ASN.1 and maybe a few more use '--' , I think at least one of them allows another '--' on the same line to end the comment, allowing a comment inside a statement, others use it for remainder-of-line.</p>
<p>Some consider the nesting of comments to be a feature, because it allows commented code to be &quot;commented out&quot;. With &quot;modern&quot; (ie decades old) version control, this argument seems somewhat dated to me.</p>
<p>One problem with comment delimiters is that they may conflict with the plain syntax. In C for example 'x/ *divp' is a valid division expression with the divisor being a dereferenced pointer, but if the space is removed, a comment would be expected instead. This is of course not a problem in PL/1 and Pascal, where '*' is not a prefix operator. The same applies to '--' with unary '-', although a binary or unary '-' followed by unary '-' is probably not really needed in any code.</p>
<p>&quot;Literate programming&quot; turns the idea of comments upside-down (or inside-out), as the main text is &quot;comment&quot;, with code interspersed. Perl has POD section comments, beginning with a '=pod' line and ending with '=cut', which contain POD markup text, used by Perl documentation tools. Python implements something similar with docstrings, and Java uses Javadoc annotations (although embedded in &quot;normal&quot; comments) for a similar purpose.</p>
<p>All the comment styles above share one major disadvantage: they might lie! As they normally allow free, uninterpreted text, there is no way to ensure that the content of a comment is true or meaningful. Sometimes code gets revised without updating the comment. And sometimes comments are just not very useful, like comments that just repeat in words what a statement does.</p>
<p>Some languages therefore have more useful types of &quot;comment&quot;, in the shape of assertions and pre/postconditions. Bertrand Meyer's Eiffel was probably an early example of taking this to the extreme, with <strong>require</strong>, <strong>ensure</strong>, and loop and class <strong>invariant</strong>s. I think this is based or Hoare logic, where the notation {P}S{Q} (with P, Q being predicates expressing pre and postconditions for the statement S) is used. I guess Pascal may have taken its comment delimiters from this (but without semantic significance.) Other languages have some form of 'assert' statement.</p>
<p>One thing that made a big impression on me in my second year of CS, was the notion of &quot;auxiliary variables&quot; introduced by Susan Owicki and David Gries in their paper on conditional critical regions. Auxiliary variables may be assigned from (side-effect free) expressions, but may not themselves be assigned to non-auxiliary variables. Therefore all assignments to aux vars may be deleted without changing the meaning of a program. However, the aux variables may be useful in assertions, pre- and postconditions and other ways for proving correctness of the program.</p>
<p>I guess this is the point where comments cross over and become more expressive forms of programming with declarative programming styles and type systems at the same time being &quot;comments&quot; about the code, and the code itself.</p>
<p>If I should describe the form of comments I would like to use, it would be a combination of free-form text, with code embedded using indentation (ie unindented lines are comments, indented lines are code), and Hoare Logic notation, with all Boolean expressions occuring in &quot;void context&quot; being seen as assertions. Likewise, string expressions (with formatted interpolations) in &quot;void context&quot; would either be ignored or taken as debug print statements.</p>

CC BY-SA 4.0
2023-05-20T22:18:06.900Z
2023-05-21T08:35:26.783Z
2023-05-21T08:35:26.783Z
LHP
# What are common options for comment syntax?
Posted by: username_0 on 2023-05-19
Almost all languages have comments, but the syntax for comments can vary wildly between them. What are commonly used options for comment syntax, and what are their advantages and disadvantages?
**Tags:** syntax comments
---
## 14 answers
### Answer by username_14 on 2023-05-19. Score: 17
Comments generally fall into two flavors: single line comments, which end with a newline, and comments with multi-line support, which typically end with the reverse of the opening token or something similar.

For the former, some of the most common opening tokens are `//` (Java, C, C++, C#, Rust, etc.), `#` (Python, Perl, Ruby, various Unix shell languages, etc.) and `%` (LaTeX, etc.); for the latter, `/*` (at least for languages inspired by C). Some languages use special exportable (think documentation) comments when the last symbol is repeated (e.g. `///` for C# and Rust, `/**` for Java).

A disadvantage of the implementation of multi-line comments in many current languages is that they can't be nested. If you commented out a small part of your code by surrounding it with `/*` and `*/`, and want to comment out a larger part which includes the smaller part, that requires some extra attention, because the end token of the inner comment will also finish the outermost one. Still, your language may be able to solve that by requiring a `*/` for *every* `/*` (or equivalently, interpret every `/*` as starting a new comment, even if it's within another one, and require it to be properly terminated).
> **Comments:**
> **username_15** (2023-05-19): Some languages do handle nested `/* */` comments properly. T-SQL is one example.  
> **username_16** (2023-05-19): Scala also handles nested `/* */` comments properly. There's other styles of nested multiline comments too: `#[ ]#` (Nim), `{- -}` (Haskell), `(* *)` (OCaml), and probably plenty others. OCaml in particular is interesting because it forces comments to contain only valid lexical tokens (no unterminated strings and stuff). I think this is to help with the nesting, but I'm not sure  
> **username_8** (2023-05-19): Matlab block comment: `%{ %}`, but iirc the open and close comment markers need to be on their own lines.  
> **username_17** (2023-05-20): D uses `/+ +/` for nestable block comments (I don't recommend this, make `/* */` nestable instead). `#= =#` is apparently used by Julia for nestable block comments to complement the `#` for line comments. And of course we have `<!-- -->` in XML.  
> **username_18** (2023-07-05): Worth noting that `#` is kind of "special", since it lets you use `#!` in your language without any extra help, which is probably part of the reason it's so common for scripting languages.  
> **username_19** (2023-07-05): @user: Yeah, OCaml doesn’t require that nestable block comments’ contents be lexically valid overall, but straight quotes do need to be paired. So you can’t write `(* London Latitude: 51°30'35" N *)`. It means OCaml doesn’t suffer from the corner case in, say, Haskell, where `{- a comment ends with "-}" even in quotes -}`. OCaml’s compromise lets you use block comments both for temporarily disabling code, and for writing documentation that contains code, at the cost of a different, maybe slightly less pointy corner case.  
---
### Answer by username_9 on 2023-05-19. Score: 11
Using the line ending character ; as a comment marker
In many assembly languages, the ;, which also marks the end of a statement, also marks the rest of the line a comment, eg:
MOV aex abx  ; move the value to the other register
ADD aex 2    ;   add 2
SUB dex mix  ; I don't think these are even real registers
BNEQ         ; branch not equals

This is nice since you need one less syntax element
> **Comments:**
> **username_10** (2023-05-19): I don't think I've ever used the semicolon as a line ender in assembly, only as a comment starter. Is there an assembly dialect where this is *required* as a line terminator?  
> **username_11** (2023-10-14): @SilvioMayolo [D's Inline Assembler](https://dlang.org/spec/iasm.html) does require it, and uses `//`, `/*`, `/+` and friends for comments, to be syntactically compatible with higher-level D.  
> **username_12** (2023-10-20): I wonder if this is what inspired the Lisp designers to use `;` as its comment prefix.  
> **username_13** (2023-11-30): @Barmar Yes, it was. Maclisp borrowed the notation from PDP-10 assembly.  
---
### Answer by username_20 on 2023-05-20. Score: 7
Slashdash Comments
Along with single line and multi-line comments, the document language KDL supports a novel, scope/syntax aware form of comment syntax called "slashdash" comments. In KDL, the token /- will treat the following node, argument, property or children block as a comment, even if it spreads across multiple lines.
In this example, the argument "commented", the property key="value", and the children block { a; b } are commented out.
mynode /-"commented" "not commented" /-key="value" /-{
  a
  b
}

Application of this comment style will obviously somewhat depend on consistency in the language grammar. For example, this could readily be applied to S-expression syntax.
; the arguments `3` and `(/ 1 0)` are commented out
(+ 1 2 /- 3 4 /- (/ 1 0)) ; yields 1 + 2 + 4 = 7

Brent Roose in this blog post suggests (AFAICT) a /-- variant that comments out an entire scope of code for use in less homogeneous languages.
// `final` and `implements Bar` are commented out
/-final class Foo /-implements Bar {
    ...
}

// The entire declaration of `Foo` is commented out
/--final class Foo implements Bar {
    ...
}

Slashdash comments can be an easier and more elegant way of commenting out code. However, it might not be immediately clear what is being commented out. Also, being fairly unknown, it will require some time to explain to users before the concept clicks.
> **Comments:**
> **username_18** (2023-07-05): Racket does something similar, I believe the notation is `#;` but I may be misremembering  
---
### Answer by username_21 on 2023-05-19. Score: 7
Comments by way of an identity function
A unique type of comments is through the availability of an infix operator which returns one of its arguments, e.g. ⊢ in APL which returns its right argument. This allows comments as strings inside expressions:
      2+'comment'⊢5×8
42
> **Comments:**
> **username_22** (2023-10-14): Could this be emulated in C or C++ by exploiting the comma operator?  
> **username_23** (2023-10-15): @KarlKnechtel: It appears that is possible, such as `printf("%d\n", ("number",5));`. However, I would say "abusing" instead of "exploiting", and honestly I've never seen a comment written that way in any C language family code.  
---
### Answer by username_16 on 2023-05-19. Score: 7
## Words

Batch and BASIC allow you to use `REM` for comments (although Batch also has `::` and some implementations of BASIC also have `'` (see comment by Steffan below)). J has `NB.`. I'd recommend against using words for comments, though, it keeps people from using useful identifiers and it just looks verbose and weird.
> **Comments:**
> **username_24** (2023-05-19): BASIC also uses `REM`, but it's aliased as `'` in some implementations  
> **username_25** (2023-05-19): The REM is for REMOVE. This it could be implemented as an operator or otherwise a keyword in the language. Makes sense in something like a shell script (batch files) where lines can be commands anyway `cd temp` or `move from to` are all series of words that start with the command then the parameters. And the parameters can be just arbitrary amount of parameters `touch one two three four` for example. Thus a `rem` command can just be a simple no-op - takes any amount of "parameters" that can be strings and numbers but does not do anything at all.  
> **username_26** (2023-05-20): I alwaus thought REM stood for "remark", as a synonym for comment  
> **username_27** (2023-05-21): @abel1502 that REM stood for remark has always been my understanding also, since learning COMAL80 - a Danish structured BASIC with strong influence from Pascal and Algol 68 - in 1982. COMAL itself iirc supported both REM and // as line comment.  
---
### Answer by username_27 on 2023-05-20. Score: 7
It shouldn't be difficult to list the major comment conventions in use or used in the past. Going back to punch card times, there is the '\*' in column 7 for COBOL.

FORTRAN had (has?) a similar convention '\*' (or 'C', 'c', 'd', 'D' or '!'?) in column 1 to make a comment line.

Many assembler languages, and I believe also (early?) LISP regard a semicolon and anything following it, until line break, as a comment.

This "remainder-of-line" comment style is also used in BASIC, either with a keyword "REM", or sometimes a single quote, and in Unix shells and Perl, where the character is '#'.

Non-line oriented (free form) languages, probably beginning with Algol, need a delimiter in both ends. In Algol 60 a comment begins with **comment** and extends to the following ';'. As only another **end** or a ';' can follow an **end** of a block, any text after **end**, up to a ';' (or another **end**?) is also considered a comment. Obviously this may lead to errors. Algol68 introduced comments beginning and ending with the comment symbol, often written as a '¢', but sometimes also '#'. Pascal uses '{' and '}' (or '(*' and '*)' when the character set does not have curly braces. Originally they didn't nest, but I think some implementations and perhaps recent standards allow comments to nest.

PL/1 uses '/\*' and '\*/', which was also used by C. (I believe BCPL and B had remainder-of-line comments?) C++ reintroduced '//' remainder-of-line comments. Both types are common in C-inspired languages.

Ada, SQL, SGML (and XML?), ASN.1 and maybe a few more use '--' , I think at least one of them allows another '--' on the same line to end the comment, allowing a comment inside a statement, others use it for remainder-of-line.

Some consider the nesting of comments to be a feature, because it allows commented code to be "commented out". With "modern" (ie decades old) version control, this argument seems somewhat dated to me.

One problem with comment delimiters is that they may conflict with the plain syntax. In C for example 'x/ \*divp' is a valid division expression with the divisor being a dereferenced pointer, but if the space is removed, a comment would be expected instead. This is of course not a problem in PL/1 and Pascal, where '\*' is not a prefix operator. The same applies to '--' with unary '-', although a binary or unary '-' followed by unary '-' is probably not really needed in any code.

"Literate programming" turns the idea of comments upside-down (or inside-out), as the main text is "comment", with code interspersed. Perl has POD section comments, beginning with a '=pod' line and ending with '=cut', which contain POD markup text, used by Perl documentation tools. Python implements something similar with docstrings, and Java uses Javadoc annotations (although embedded in "normal" comments) for a similar purpose.

All the comment styles above share one major disadvantage: they might lie! As they normally allow free, uninterpreted text, there is no way to ensure that the content of a comment is true or meaningful. Sometimes code gets revised without updating the comment. And sometimes comments are just not very useful, like comments that just repeat in words what a statement does.

Some languages therefore have more useful types of "comment", in the shape of assertions and pre/postconditions. Bertrand Meyer's Eiffel was probably an early example of taking this to the extreme, with **require**, **ensure**, and loop and class **invariant**s. I think this is based or Hoare logic, where the notation {P}S{Q} (with P, Q being predicates expressing pre and postconditions for the statement S) is used. I guess Pascal may have taken its comment delimiters from this (but without semantic significance.) Other languages have some form of 'assert' statement.

One thing that made a big impression on me in my second year of CS, was the notion of "auxiliary variables" introduced by Susan Owicki and David Gries in their paper on conditional critical regions. Auxiliary variables may be assigned from (side-effect free) expressions, but may not themselves be assigned to non-auxiliary variables. Therefore all assignments to aux vars may be deleted without changing the meaning of a program. However, the aux variables may be useful in assertions, pre- and postconditions and other ways for proving correctness of the program.

I guess this is the point where comments cross over and become more expressive forms of programming with declarative programming styles and type systems at the same time being "comments" about the code, and the code itself.

If I should describe the form of comments I would like to use, it would be a combination of free-form text, with code embedded using indentation (ie unindented lines are comments, indented lines are code), and Hoare Logic notation, with all Boolean expressions occuring in "void context" being seen as assertions. Likewise, string expressions (with formatted interpolations) in "void context" would either be ignored or taken as debug print statements.
---
### Answer by username_28 on 2023-05-19. Score: 6
Double Slash, Single Line // Comments
This is what languages such as Java use, in addition to multi-line comments. The comment ends at the end of the line and any text immediately after the // will be ignored.
This comment is useful for quick, one line explanations of a certain piece of code. They can easily be placed next to or immediately above a small line of code to show that the comment explains that one line.
As a simplistic example:
// Declares a variable 'a' with the value 100
var a = 100;
var b = a * 10; // Declares a variable 'b' with the value 1000

However, one disadvantage with this syntax, which is true of single line comments as a whole, is that is harder to comment out entire sections of code you want to ignore. Each line must be individually commented out.
This becomes tedious and generally very messy visually.
// Ignored code
// for (int i = 0; i < 10; i++) {
//    System.out.println(i);
// }
> **Comments:**
> **username_8** (2023-05-19): Commenting out individual lines is less of a problem in IDEs that have a keyboard shortcut for it (often Ctrl-/).  
---
### Answer by username_5 on 2023-05-19. Score: 5
Strings as comments
This is often seen in Python (see "Python multi-line string" and "Python tripple quoted string").
With this, programmers can simply use a string as a comment. For example,
"""
Some text here
Some more text
Even more text
"""
print("""Hello world""")

This can be nice as separate syntax isn't needed (though Python has real comments too), but with the trade-off that it might be considered (ab)using a feature. In the case of Python specifically, this is specifically documented in PEP 257, so it isn't really abuse there.
> **Comments:**
> **username_29** (2023-05-19): Personally I dislike this, because it degrades performance.  
> **username_0** (2023-05-19): @user16217248 How would this degrade performance? The strings would just be initialized and then left untouched for the rest of execution, right?  
> **username_29** (2023-05-19): @Ginger Initialized is still overhead. Whereas comments are ignored entirely.  
> **username_0** (2023-05-19): @user16217248 Is the performance loss actually _measurable_, though? Worrying about that feels like worrying that one day a tree will grow where I'm standing.  
> **username_27** (2023-05-20): A string that is not assigned to anything - or any constant expression in "void context" for that matter - would be trivial to compile into nothing at all. No performance hit whatsoever.

One (minor) disadvantage would be that such a comment can't easily be placed inside an expression. Also, in a language with a statement terminator or separator (typically semicolon), it might look a little awkward.  
> **username_2** (2023-07-05): Note that docstrings are *not* comments. They are syntactic sugar for assigning to an attribute named `__doc__`. The whole point of docstrings is that, unlike comments, they are *not* ignored but kept around at runtime so you can query them at runtime.  
> **username_6** (2023-10-14): This doesn't degrade performance at all, at least beyond the cost of parsing the string literal (which is one-off and negligible, possibly not even more expensive than parsing a comment beginning with `#`). CPython absolutely recognises a string literal on its own as a noop and doesn't emit any bytecode instructions for it.  
> **username_30** (2023-10-15): Python is a language that is commonly used in ways that execute each line of code only once. In such use cases, it does degrade performance as compilation is a major part in these cases.  
> **username_12** (2023-10-20): I think Python adopted this from Common Lisp.  
> **username_12** (2023-10-20): @JörgWMittag They serve a similar purpose as comments, since they explain/describe the code in some way. The fact that they're preserved at runtime doesn't negate that. You can also use string literals outside definitions, and then they really are ignored like comments. Since Python doesn't have multi-line comments like `/* ... */`, triple-quoted strings are often used as a replacement.  
> **username_12** (2023-10-20): And only a string literal at the beginning of a definition is preserved as a docstring; any others will be ignored.  
---
### Answer by username_31 on 2023-10-14. Score: 4
I'm surprised that Lua hasn't been discussed:
-- Singleline

--[[
Multiline with delimiters.
]]

--[=[
[[Delimiters]]
]=]

--[==[
[[can be]] [=[arbitrarily long]=].
]==]

These delimiters are called opening and closing long brackets. The comment nesting problem mentioned by other answers can be easily avoided by increasing the level of the long brackets, as shown in the example above.
What's more, these brackets are also used to delimit (multiline) string literals:
local s = [=[
Foo[[bar]]baz[==[qux]==]
]=]
---
### Answer by username_2 on 2023-07-05. Score: 3
Newspeak has nested metadata which looks like this:
(*:id: xyz *)

This associates the metadata payload xyz under the metadata tag id with whatever runtime language element follows the metadata comment. This information is kept both in the compiled code and at runtime and can be queried using reflective mirrors. The metadata tag identifies a specific metadata interpreter. (This is, for example, how Newspeak does its optional type annotations.)
In other words, these are similar to Java-style annotations, C#-/.NET-style attributes, C++-style attributes, but also have aspects of Python- and ECMAScript-style decorators.
Metadata can nest, i.e. I can annotate metadata with metadata.
Comments are simply metadata without a tag:
(* This is a comment (* And this is another, which comments on the outer comment *) *)

Since they are still metadata, they are attached to the runtime language element which follows them. And this applies to nested comments as well, so the above inner comment is a comment attached to the outer comment.
Since they are attached to actual runtime language elements, it is easy to keep them around and reconstruct them even through large-scale complex automated refactorings. You can do cool stuff like: when catching an ArgumentError, retrieve the documentation comment for the method which raised the exception and show it together with the stack trace. Since the comment is an actual object attached to the actual method object, you can literally just grab it from the stack trace object.
---
### Answer by username_5 on 2023-05-19. Score: 3
The /*  */ notation
This is what CSS uses.
Example:
/* Some text */

This method has a number of advantages:

Due to it not automatically going to the end of the line (it stops at */), it can be midway-through a line
It can span several lines if needed:

/* Some test
   Some other information
   Even more stuff
 */
> **Comments:**
> **username_6** (2023-05-20): Not just CSS ─ this comment syntax exists in C, C++, C#, Java, Javascript, PHP, and many more languages. Particularly languages which borrow their syntax from C tend to have this kind of comment.  
---
### Answer by username_7 on 2023-05-21. Score: 3
If you use either # or #! as a comment starter, then your file can run directly on Unix via a so-called [Shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)). That is, on Unix, a file starting with `#!`(path) will run the file as code under the interpreter at (path). If # or #! is a comment, the interpreter will then skip over the shebang line and all is well

Of course, if you prefer alternative syntax for comments, you could still include a special case for skipping a shebang
> **Comments:**
> **username_2** (2023-07-05): This is very annoying in ECMAScript. Hashbangs only became legal with the June 2023 release.  
> **username_8** (2023-07-05): @JörgWMittag I'll note that it was supported by Node for much longer, even if it wasn't part of the standard.  
---
### Answer by username_1 on 2023-05-19. Score: 1
Python-style comments

# starts a single-line comment. It's only one character, so it's quick and easy to type.

""" or ''' delimit multi-line comments. These are actually "docstrings", but they can also be used as comments. They are three characters on each side, so it's a bit longer to type. They are also ambiguous, since they can also be used for multi-line strings.


Examples:
# comment

"""multi
line
comment"""

'''
this as well
'''
> **Comments:**
> **username_2** (2023-07-05): Note that docstrings are *not* comments. They are syntactic sugar for assigning to an attribute named `__doc__`. The whole point of docstrings is that, unlike comments, they are *not* ignored but kept around at runtime so you can query them at runtime.  
> **username_1** (2023-07-05): @JörgWMittag I know, but they are essentially used as multi-line comments  
> **username_3** (2023-12-19): `'''` and `"""` enclose multiline string literals. Docstrings in Python are simply when _any_ string literal forms the first statement of a module, class or function.  
---
### Answer by username_4 on 2023-05-21. Score: 1
The choice of comments should come down to basically one thing: What language or family of languages are you emulating?

C and its enormous family of languages generally use `//` for single line comments and `/* */` for block comments. I would recommend this style of comments because they are the most widespread. They'll also let you play with JavaDoc documentation, which is usually implemented as `/** */` or `///` in some cases.

The other most common style of comment is to use `#`. This is usually found in older languages like ShellScript and languages that borrow from them like Python. Most of this languages only support single line comments, however, so this style of comments may feel slightly limited. You could maybe implement your own block comments by using `###` or any combination of characters that you fancy.

I wouldn't recommend using outlandish comment syntaxes just to keep the language approachable.

P.S.:
I'll give XML and its many children a mention for only having block comments (denoted with ). Having only block comments might be something interesting to try out in a more esoteric language.
> **Comments:**
> **username_2** (2024-01-12): Technically speaking, `<!` is the start of a *directive* and `>` is the end of a directive. `--` is a *comment toggle*, meaning it *toggles between comment and non-comment mode*. This means that `<!-- This is a comment--I think -->` does not do what you expect!  
---
