Block Comments Are a Bad Idea
futhark-lang.org
futhark-lang.org
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.
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"
-- | 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 = ... /**
* This is documentation.
*
* It spans multiple paragraphs.
*/
pub fn foo() {}
/**
This is documentation.
It spans multiple paragraphs.
*/
pub fn foo() {}
/// This is documentation.
///
/// It spans multiple paragraphs.
pub fn foo() {}
#[doc = "This is documentation."]
#[doc = ""]
#[doc = "It spans multiple paragraphs."]
pub fn foo() {}
(You can mix-and-match, too; I’ve combined doc attributes with cfg_attr before, to add doc comments if a certain feature is enabled, see the bonus section in https://chrismorgan.info/blog/rust-cfg_attr.html.)The author makes almost exactly your point regarding the (non)importance of these issues in practice.
What would the author have to write in order to be able to discuss the consequences of this language design choice, and be spared the barb of your wit.
What a major mischaracterization. It was the author that implied things were objectively bad. I stated that the subject is subjective, in that there are use cases where block comments are good.
> I will argue that block comments are unnecessary, and in fact near-impossible to design and implement correctly (for my own pedantic notion of correctness)
You might argue, subjectively or objectively, about the utility of the "notion of correctness" used here, but the author warns at the outset that this is the basis for the rest of the analysis.
I ask again, what preface would the author need to write to satisfy your criticism? I think that it's worthwhile for the author to point out that you cannot create a block comment scheme without having some un-intuitive edge cases, and I'm curious what gave you the impression that the author was claiming an unwarranted degree of objectivity.
How do you think I should have put my words, to make it clear that my opinion here is not intended as objective fact, but merely a subjective take on a language design question?
* Center your blog post around "why I don't like block comments" and not "why block comments are bad".
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.
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.
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.
If I had to distill my criticism about block comments, it would be that my inclination to read someone's multi-line block commented description of the purpose of some variable or loop approaches 0 as number of lines grows past 1, let alone some lengthy TODO blather.
I was reminded of some of the Java best practices, eg. http://www.oracle.com/technetwork/java/javase/documentation/....
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.
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.The D Programming Language - Conditional Compilation: https://dlang.org/spec/version.html
EDIT: I only now noticed it was mentioned in the article. I'll therefore add that the example from the article, of using #+nil, is actually not recommended, because it's technically possible that somebody adds a feature flag called "nil". Therefore, it's preferred to use #+(or) or #-(and) for comments (they're degenerate forms of conditional compilation expressions like #+(or flag1 flag2 flag3)).
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.
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.)
True, in a language like C these don't apply necessarily and goto still has some use -
Lisp does have block comments,
#| This is a block comment |#
You can also use feature expressions to effectively comment out code #+(or)
(defun foo ...)
The reader will skip over the following sexp if the feature expression isn't true (and `(or)` never is). (* Strings are enclosed by '"'. *)Additionally..
> This is perfectly cromulent Haskell.
I'm still impressed whenever someone can correctly use this word to embiggen the subject under discussion.
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?
I guess it could be useful if you want to temporarily debug the middle of a line for debugging purposes but in this case you could just add a line break if blockquote didn't exist.
That being said I don't feel very strongly about this topic, I let emacs handle the commenting for me so I never really have issues with nested comments. Besides commenting comments is probably only useful for temporary debugging.
I do feel strongly about people committing commented/dead code however, it's just distracting and misleading. Nowadays versioning your code is just one `git init` away so nobody should be worried about keeping old dead code "just in case".
Sample code is acceptable however, I like Rust's approach where commented sample code can actually be tested to make sure it's up to date.
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.
The extreme in your case would be `hasMagicTargeting = false` and then pass `hasMagicTargeting` instead of `false`.
However, I do not recommend using triple-quotes for comments, as git diff only shows 2 lines with quotes while the actual difference is much bigger.
--[[
commented = 123
--]]
---[[
uncommented = 456
--]]
Commenting and uncommenting blocks by adding or removing a '-'. Pretty handy for trying stuff out.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.
: <<- 'NOOP'
some
code
here
NOOP
In some languages there is a very slight performance impact to doing this, however. Especially in the shell, because it actually has to juggle file descriptors whenever a heredoc or herestring is involved — even if you're directing it into a built-in like `:`. (It only costs a few-dozen microseconds though.)Also, heredocs are irritating because they usually can't deal with indentation properly. bash and zsh support the `<<-` operator which allows you to indent the closing delimiter, but only if you use tabs. Most other languages require the delimiter to be the first thing on the line, which is tedious and confusing.
Python's triple-quotes seem to solve all of these problems, and they're one of the best things about Python's grammar IMO. I wish every language had that, combined with the ability to treat expressions as statements. It'd be a little ugly in C-like languages, but certainly usable:
'''
my comment
''';Edit: oh, wait, html comments also suck.
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.
Edit: actually I'm curious how much time it will take for my gp comment to go from "downvoted eccentricity" to obvious.
More edit: I'm not only thinking in more computing power. We know a little more on usability and user experience now than then.
I dislike doing things with every keystroke. I hate when I start typing something in an IDE and it rushes to underline the word with a disapproving red line.
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.
I meant code editors that "know" that you are writing code and make things easier for you. In other words, exactly the opposite to one that prompts absurd debates about if multiline comments are a good or a bad idea.
This sounds a lot like "do what I mean." You have to tell the editor in some way that you want to write a block comment or not, and that you want to end it.
My editor does make somethings easier for me - if I start a block comment, it automatically inserts the block comment closing character after my cursor. It does syntax highlighting of the block comments, so it's obvious at a glance where they begin and end. I can declare or remove a bunch of single-line comments by selecting a block of text and hitting a shortcut key, or by creating a multi-line cursor at the start of the lines and adding or deleting the single-line comment characters.
I find it hard to imagine an editor with an interface which is easier and faster than entering simple text, once I'm intimately familiar with the shortcuts used with the editor and the syntax of the language I'm writing in. If one exists or could exist, I'd love to know about it!
So you call "entering simple text" to the automatic managing of comments that you just described? I can't honestly agree with that ;)
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.
Personally I like having two block comment syntaxes to choose from, like Pascal's { } and (* * ); normal comments use { }, while if you want to comment out an entire block of the program and not have the comment terminate early, use (* and * ).
Most of my professional life editing Pascal code was done from command-line editors that didn't have support for commenting the current selection, other than piping the selection through a command like sed. I appreciated being able to narrow down bugs using (* and *).
* 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 luxuryOr non-visual block select...V% with cursor on the opening {.
:vmap <M-/> :s|^|//|<CR>
:vmap <M-\> :s|^//||<CR>
(writing from memory, may need tuning) [:div
[:p "hello world"]
#_ [:pre "this debug block is commented out"]]> 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.Is it new syntax of 5.3?