
Block Comments Are a Bad Idea - Athas
https://futhark-lang.org/blog/2017-10-10-block-comments-are-a-bad-idea.html
======
fortythirteen
"I don't like something, therefore it is _BAD_ "

I've never had an issue with a block comment that couldn't be fixed in a
couple seconds. The usefulness and readability of a well formatted block
comment, especially for documentation generation, far outweighs any
inconveniences in fixing a broken implementation.

~~~
stinos
_usefulness and readability of a well formatted block comment, especially for
documentation generation_

it's indeed a bit strange the OP doesn't mention that as an advantage,
accoording to the OP the first main purpose is just that it is "perceived that
line comments are impractical for long comments"

~~~
Athas
Line comments are no hindrance to documentation generation. Extracting the
contents from a paragraph line comment is a rather simple regular
expression[0]. Haskell almost exclusively uses line comments for
documentation, and it works fine. You write it like this (the '|' is to
indicate that it's a doc-comment):

    
    
        -- | Compute this and that.
        -- Parameter @x@ is the good one, and
        -- parameter @y@ is the bad one.
        --
        -- The function works well and runs in time
        -- proportional to $O(n**n**n**n)$.
        f x y = ...

~~~
stinos
Actually my point was mainly about the readability aspect, should have made
that more clear: for me there usually still is a (slight) advantage in
readability if every line is not prefixed. E.g. the code you show here looks
rather cluttered to me. It doesn't mean it does to you of course, if you are
used to it your brain just ignores those dashes. But mine doesn't, since I am
not used to it. Though it would probably take me only a couple of days.

------
struppi
You don't have to solve all edge cases for a feature to be useful. At least
not all the time.

I, am not too unhappy with the behaviour of C/C++/Java/... - That the block
comment will end at the first occurence of " * / ".

If I accidentally close a comment too early (because there already was
_another_ block comment inside the code I want to comment), then...

* The syntax highlighting of my IDE will tell me.

* The compiler will tell me.

* I can take it as an opportunity to consider whether this file is too large - That problem should not have happened at all.

~~~
ecshafer
This problem does fall under the umbrella of issues that have the obvious
solution of "don't do that"

------
StevePerkins
I really appreciate class-level and method/function-level comments, in
languages that have a special format for them to assist with generating
documentation (e.g. Javadoc, Scaladoc, JSDoc, etc).

A couple of years back, the company that I work for had a series of lunch-n-
learns where each presenter did a chapter of Robert Martin's "Clean Code". One
of the chapters deals with comments. Not using them as a crutch, and focusing
on making the code readable instead.

The presenter, and one of the more influential archs in the room, was
excessively dogmatic about it. Everyone ultimately left the meeting with the
message that ALL comments (especially BLOCK style comments!) are "a bad code
smell" _per se_. Overnight, everyone in the department all but stopped writing
code comments.

Fast forward two years, and now it's a complete and utter nightmare to touch
anyone else's code... _or even your own code that you haven 't seen in
awhile_!

Now, I understand eschewing the auto-generated blocks that your IDE might
throw on the class level (e.g. "Created by John Doe, on 2017-10-11"). I
understand not placing Javadocs on getters and setters and other trivial
methods. I understand rejecting _clutter_.

However, for any non-trivial unit of code... you owe it your peers, your
successors, your future self who has to maintain this later, and just the gods
of professionalism in general, to throw on a brief comment blurb signalling
the intent of the class or method/function.

~~~
StavrosK
It's kind of surprising to me that anyone past junior-level development
doesn't already have it hammered into them that "code is _how_ you did
something, code is _why_ you did it".

Also, if you can't possibly be any less clever in your code, then leave a
comment explaining the "how", and apologize that you couldn't make it any
simpler.

~~~
wruza
s/code is why/comment is why/, I think?

~~~
StavrosK
Doh, sorry, you are correct. I can't edit the comment any more, unfortunately.

------
wruza
One can call it BAD too, but I’ve done this several times:

    
    
      if (self-describing) {
      }
      else if (self-describing) {
      }
      else /* description */ {
      }
    

and

    
    
      void myfunc(int a, char *b /* optional */, ...)
      {
    

Block comments are not only block, but also inline. You cannot end line
comment on the same line. (Though it is easy to work around).

As of good/bad: if you don’t like it personally, then don’t use it. If in
group, then put that in group style guidelines, because these are required to
read and follow anyway, for project to be consistent. To prove something is a
bad idea _in general_ is a hard work not worth doing.

~~~
chrismorgan
Put the comments at the end of the line, introducing line breaks if necessary:

    
    
      if (…) {
      } else if (…) {
      } else {  // description
      }
    

and

    
    
      void myfunc(int a,
                  char *b, // optional
                  ...)
    

I don’t program in C or C++, but when working with the Windows API I
appreciate Microsoft’s source-code annotation language which leads to being
able to indicate input and output parameters, and optional ones, so that you’d
wind up with something like this:

    
    
      void myfunc(__in int a, __in_opt char *b, ...)
    

I don’t know how they’re implemented in MSVC, but I’m guessing they’re just
empty #defines.

~~~
wruza
Sure, I’m aware of these methods; these are obvious. But my preference is to
put else-comment that way, because its beauty makes me peaceful and calm when
I look at it. At work I’ll do what PM expects, i.e. her/his [motivated]
preferences, not mine (if you ask people what they’d like to do, work will be
hardly a popular option at all, so no problem, it is consensus between being
“busy” and having profit).

------
chhs
The D Programming language has a neat trick to block commenting out code for
debugging purposes. Wrapping code in a version(none) {} block will exclude the
block from compilation. The code inside the block must still be syntactically
valid so it avoids the problem mentioned in the linked post.

The D Programming Language - Conditional Compilation:
[https://dlang.org/spec/version.html](https://dlang.org/spec/version.html)

~~~
LeifCarrotson
In what ways is that better than "if(false) { }"?

~~~
wruza
From linked examples it is clear that version() is allowed outside of
functions. Since version() already serves a feature, there is no need to
overload the meaning of if().

------
KwanEsq
Rust had an RFC at one point that considered removing (some) block comments,
which generated a good argument in their favour (see also the longer comment 5
replies later): [https://github.com/rust-
lang/rfcs/pull/1373#issuecomment-205...](https://github.com/rust-
lang/rfcs/pull/1373#issuecomment-205864317)

Essentially it's very annoying (slash slash) for blind programmers (slash
slash) if their screen readers (slash slash) keep reading out (slash slash)
line comment delimiters (slash slash) during long comments.

~~~
yen223
This feels more like a deficiency in the screen reader than one in line
comments.

~~~
KwanEsq
I'd argue the editor rather than the reader. Readers can't be too specialised,
they have to work with a large variety of programs, so it's not going to know
it's looking at code, let alone parsing it, unless the editor tells it.
Instead the editor should have an accessible interface that only passes up the
comment text to the reader, perhaps annotated with a "comment" role or
something.

------
vortico
This is my personal preference, but from experience I prefer languages that
don't shun concepts because they're bad programming practice. I can understand
if something is difficult to implement or prevents other features from being
added, but if a feature is possible, I say add it---it might come in handy
sometimes. There's a reason languages like C, C++, Ruby, and Javascript are
immensely popular. It's because programmers can use and abuse any nook and
cranny of it when needed, because they let you mess with pointers, use goto,
redefine language keywords through macros, patch standard libary
functions/classes, etc. If programmers want to write bad code, let them write
bad code. You can't magically make a bad programmer write good code because of
restrictions of the language. I've seen some horribly written Haskell for
example, despite how "perfect" the language is designed.

For blocks comments in a functional language though, it might work because
many people would come from LISP/Scheme, where block comments were never a
thing (I think.)

~~~
phpnode
See also GOTO which is a wart 99.9% of the time but really useful for writing
e.g. parsers.

~~~
dom0
Error handling.

~~~
johannes1234321
In most languages there are better way to do this than goto. Among them \-
extracting code into smaller functions (yes, state has to passed around) \-
exceptions (yeah yeah, hate them or love them, but if used in your environment
it makes sense not to avoid them) \- RAII pattern or handling cleanup, which
allows simple return and "automatic" resource handling \- etc.

True, in a language like C these don't apply necessarily and goto still has
some use -

------
oct
OCaml actually has correct block comments by his definition (and no line
comments). This does lead to the odd fact that you can't have an unterminated
string literal in a comment, which usually isn't a problem, but can be
surprising.

~~~
Athas
Does this mean that the following comment would be a syntax error in an OCaml
program?

    
    
        (* Strings are enclosed by '"'. *)

------
rkachowski
One thing which isn't mentioned here (which i've encountered before) is when
conflict tags from source control get thrown into the middle of block
comments, and then committed - which leads to all kinds of headaches. This
wouldn't happen with line comments.

Additionally..

> This is perfectly cromulent Haskell.

I'm still impressed whenever someone can correctly use this word to embiggen
the subject under discussion.

------
iiv
How would one do inline comments without block comments?

I don't know if Python's triple-quote can be used inline, but otherwise that
seems like a good solution. I am not entirely familiar with Python comments,
does any of his arguments apply to triple-quotes?

~~~
chrismorgan
I view inline comments as a code smell in most languages; I can’t think off-
hand of having seen even one occasion where the code couldn’t be tweaked into
another nicer form that didn’t depend on inline comments.

~~~
umbrai_nation
I use them with functions that have too many arguments. It's not always
feasible to fix the problem at the source.

damageDealt = calcDamage(weaponType, monsterType, DamageType.FIRE, null /*
specialEffectFlags _/ , false /_ hasMagicTargeting */ );

It's definitely a code smell, but it's much better than nothing and I'm always
glad to see these comments when I come back to the code.

~~~
chrismorgan
Yeah, that was the closest I could think of. But in Python you’d use keyword
arguments, and in JavaScript you’d use objects with named fields in lieu of
that, and in Rust you’d commonly try to use struct fields or custom enums for
such things (I still want named arguments there).

The extreme in your case would be `hasMagicTargeting = false` and then pass
`hasMagicTargeting` instead of `false`.

------
Vaskivo
Commenting and uncommenting blocks in lua:

    
    
      --[[
      commented = 123
      --]]
    
      ---[[
      uncommented = 456
      --]]
    

Commenting and uncommenting blocks by adding or removing a '-'. Pretty handy
for trying stuff out.

[https://www.lua.org/pil/1.3.html](https://www.lua.org/pil/1.3.html)

~~~
lucozade
lua also allows you to define blocks like [=[ ... ]=] but with arbitrary,
matching counts of '=' inside.

Using this style with your comment syntax handles having nested and/or
dangling comment delimiters in the body.

It's probably the most comprehensive approach I've used. In practice, I've
never actually needed more than one level of nesting or dangling but it's not
particularly onerous to the parser to include the arbitrary levels.

------
lozenge
Surely the solution is heredocs? You effectively define your own comment
closing string at the comment opening point.

~~~
Athas
Yes, heredocs (or "here-comments", since you want them ignored, not just
stored in a string variable) would likely be a solution for all but the most
pedantic. The final recourse of the pedant would be to point out that no
single closing string would be appropriate in all cases, and you are in
principle required to read the code you want to comment out, in order to find
a closing string that is not already contained within it.

~~~
cat199
:.,+n|grep eofstr

------
chrismorgan
CSS _only_ has block comments, and they’re eager-closing rather than nested.
This makes it approximately impossible to comment out code if you add any
explanations for why things are how they are or have any other comments
inline, which makes me sad.

~~~
wruza
It is wonderful how 2 of top-3 formats of the web (css, json) went wrong on
developers from the start.

Edit: oh, wait, html comments also suck.

------
narag
This is one of the signs that we're doing it wrong with programming languages.

We're dealing with text. A program can be expressed in text, actually every
piece of information can be converted to text some way or another. The
question is if it's the right way to do it. It's not.

I know why we chose text at the time. It doesn't make sense today.

In this case, we should be using a tool that would let us write comments
without worrying about delimiters or escaped characters. That's so 20th
century.

~~~
andruby
What are you suggesting? Some kind of "rich text"? Or are you suggesting
visual programming?

~~~
wdfx
I was just thinking about some kind of code side-car file format which stores
comments/docs separately. You'd then have a vertical split view with code on
one side and the linked comments/docs on the other. You could select some code
and use that to insert/link comments in the other pane.

I'm not entirely sure if I've ever seen something like this before - maybe as
a feature in a specific language, but not as an IDE feature for all languages.

~~~
wdfx
as for using comments to disable code - you probably should have the active
code in source control and then you are free to simply delete it.

~~~
narag
This solution or simply a switch to temporarily disable some chunk of code
should be an easy-to-use part of the editor. The programmer should not be
concerned with implementation details (implementation details of the
editor/language, not the program being written) like nested comments,
indentation, etc.

------
jstewartmobile
I will second this from bitter experience.

Was translating a very old Pascal program. My editor didn't have syntax
highlighting for it. Spent a couple hours translating a very large function.
Wasn't until I finished that I realized it was wrapped in a very large block
comment.

That, and most decent editors have a "comment current selection" feature that
makes single-line comments easy enough.

~~~
RobertJacobson
Why do you fault multiline comments and not your code editor?

~~~
jstewartmobile
Colors don't feel as robust to me as syntax.

    
    
       * color blindness
       * broken syntax above typically throws-off subsequent highlighting
       * touch a lot of embedded stuff where having any kind of editor at all (even without highlighting) is a luxury

------
OscarTheGrinch
Commenting out whole sections of code incredibly useful for debugging and
rapid prototyping.

~~~
icebraining
Many editors allow you to select the section and line-comment it as a whole.

~~~
tyingq
Even vim has a visual block selection mode. <ctrl-v> at the top of the block,
then move down (j or down arrow) to the bottom. That marks the block. Then
type the I character (insert in front of cursor), type the comment character,
and press <esc>. Once you press <esc>, the inserted comment character action
is repeated for the whole block.

Or non-visual block select...V% with cursor on the opening {.

~~~
wruza
Oh, my

    
    
      :vmap <M-/> :s|^|//|<CR>
      :vmap <M-\> :s|^//||<CR>
    

(writing from memory, may need tuning)

------
moomin
Sounds like he's never heard of here-strings. Or discursive text that includes
code.

------
dustingetz
Clojure nailed this, you can throw a comment in the middle of some nested
expression, e.g. when building up React.js forms:

    
    
        [:div 
         [:p "hello world"]
         #_ [:pre "this debug block is commented out"]]

~~~
moomin
This works providing you wanted exactly one expression commented out. It's
useful, but it's not perfect.

------
LeifCarrotson
I like how Lua handles the problem, with multi-level open and close comment
strings (and string strings). From Programming in Lua [1]:

> _A comment starts anywhere with a double hyphen (--) and runs until the end
> of the line. Lua also offers block comments, which start with --[[ and run
> until the corresponding ]]. A common trick, when we want to comment out a
> piece of code, is to write the following:_
    
    
        --[[
        print(10)         -- no action (comment)
        --]]
    

> _Now, if we add a single hyphen to the first line, the code is in again:_
    
    
        ---[[
        print(10)         --> 10
        --]]
    

> _In the first example, the -- in the last line is still inside the block
> comment. In the second example, the sequence ---[[ does not start a block
> comment; so, the print is outside comments. In this case, the last line
> becomes an independent comment, as it starts with --._

Furthermore, the pairs of so-called long brackets ([[ and ]], which match the
syntax used to declare multi-line string literals) prefixed with hyphens can
be converted to 'level-n' long brackets by inserting an arbitrary number of
'=' signs between them:

    
    
        local commentDescribingString = 
        [===[Lua allows for multiple comment syntaxes.
        You can use two hyphens: '--' for single-line comments.
        Opening 'long brackets' with these hyphens (--[[) start block comments.
        Long brackets can contain '=' signs to form different bracket pairs.
        Closing long brackets must match the number of '=' signs, and do not
        require the hyphens (but they look better and are more convenient)
        These would be comments if they weren't in a string literal:
            --[[ Level 0
            --[=[ Level 1
            --[==[ Level 2
            print("this is really thoroughly commented out.")  -- It is!
            --]==]   -- Closed level 2
            --]=]    -- Closed level 1
            ]]       -- Closed level 0 without the hyphens
        I had to use level-3 long brackets to declare this string.
        ]===]
    
        print(commentDescribingString)  -- Prints above paragraph
    

Single-line comments go to the end of the line, of course, no matter how many
hyphens there are. Single-line strings can be declared with any number of
single- or double-quotes:

    
    
        local singleLineString = """This string with 'single', ''double single'', ""double"", or ""double double"" quoted words might be hard to write in other languages!"""
    

Of course, there's also 'if (false) then _(block of code)_ end' as in every
language. The code still goes through the parser, so it takes compilation time
if not execution time, and you can have scope conflicts, but that's OK IMO.
Surrounding it in an 'if (false)' block is one quick step away from changing
'false' to 'true' to re-enable it, or changing 'false' to a variable to make
it optional, which is nice.

~~~
wruza
>local singleLineString = """...

Is it new syntax of 5.3?

