Updated 2016-12-04 17:21:09 by EMJ

The dodekalogue defines one method for creating a comment in a Tcl script: If A hash character ("#") appears at a point where Tcl is expecting the first character of the first word of a command, then the hash character and the characters that follow it, up through the next newline, are treated as a comment and ignored. The comment character only has significance when it appears at the beginning of a command.

See Also  edit

re_syntax
expanded regular expression syntax includes syntax for comments
Easy Ctext Commenting
SeS 2013-07-01: 7-1-2013: how to enable easy and fast commenting inside a Ctext widget
Why can I not place unmatched braces in Tcl comments

Description  edit

Because a Tcl comment is only recognized where a command might begin, it may be tempting to suppose that it is in fact a command, but this is not the case. Comment lines are stripped out before the script is evaluated.

So that # isn't actually a command, but a directive to the interpreter? Typically, enclosing a simple name of a command in braces would be a no-op, but compare
# is this a comment

with
{#} some arguments

The first example results in nothing, since it is a true comment. The second example results in the evaluation of a command named #, or if such a command doesn't exist, an error.

Inline Comments  edit

Use ;# for inline comments:
set stuff [some kind of nonsense]  ; # That semi-colon terminates the previous
                                     # command, allowing a comment to be added

Block Comments  edit

The common idiom for block comments is to use if with a condition of 0:
if 0 {
    Any Tcl code to be commented out (with matching braces, of course!)
    or any other kind of text, will be ignored - and even [exit] won't fire
    because it's in braces, so left unevaluated!
}

Tcl is optimized for this idiom, making it a good choice.

One caveat is that the rules for braces still apply, so unmatched braces in the comment would be an error.

RS ponders this variation:
interp alias {} NB. {} if 0

Somehow "NB." feels more natural (and shorter) to me...

RS suggested that foreach could be used to create a comment, relying on the fact that foreach doesn't evaluate its body arguments at all if the associated list is empty:
foreach don't {} {#and the body is not executed, like if 0 }

Partial Block Comments  edit

Because commands such as return and tailcall terminate a script, any subsequent commands are effectively comments.
proc p1 {} {
        return {Hello from p1}
        Four score and seven years ago...
        ...shall not perish from the earth.
}

A Comment Proc  edit

At the scripting level, A comment behaves almost like a null-operation command. It's trivial to code a procedure that did something similar, albeit more slowly, since the procedure would actually run instead of just being stripped out prior to script evaluation, but notice that there is a significant difference:
proc # args {}
{#} This is a call to the new proc that does nothing, like a comment
{#} but this here still does an [exit]!! So it's not like
{#} {[exit] [exit] [exit] is ok}
# a regular [exit] comment like this will not exit, but...
{#} [exit] [exit] [exit] ... will indeed exit 

The typical usage, then, is:
{#} {
    This is a comment in braces
}

SDW PYK: If you are concerned about the comment being evaluated, enclose it in curly brackets:
{#} {

   And now I can put in comments to my heart's content. Without fear
   of the whitespace getting munched. Nor even that the my "quotes" will
   leak out of the brackets.

   and now even [exit] will not be evaluated.

}

The name of the command is pretty self-documenting: "comment in braces"... Much more intuitive than e.g. Ruby's "=begin ... =end", and available with almost zero implementation! (RS)

In the Tcl chatroom, MS pointed out: "the bytecode compiler recognizes proc whatever args {} and compiles no invocation for that; the cost is (almost) nothing. For other empty procs, an invocation will be compiled, so that you have a call/return overhead", and that if 0 {...} may raise errors on some contents (up to tcl8.3).

Dummy Variables as Comments  edit

SDW 2007-03-14: In the Tcl chatroom I also shared one of my styles, which is to write comments in dummy variables. While they do take up memory, and are not cleaned up by the compiler like the if 0 {...} comments are, well you don't have to worry about future changes in the compiler barfing up syntax errors.

I'm paranoid, largely because I have code that's been kicking around since (gasp) Tcl 8.0beta.
set comment {
    And now I can put in comments to my heart's content. Without fear
    of the whitespace getting munched. Nor even that the my "quotes" will
    leak out of the brackets.
}

A List with Comments  edit

RS 2006-07-13: In the Tcl chatroom someone asked how to have comments in lists. First answer is, lists are data, and comments apply only where commands are parsed; but the second answer is: of course! Lists in a source file come as strings (often in curly braces), and that Tcl is good at doing things with strings is well-known :^) One regsub is enough to strip substrings between # and the next newline:
set data {
    # This is an example of comments in data
    test {
         4711 # an integer
         all  # a word
    }
    date today # one more test
}
% regsub -all {#.*?\n} $data \n

test {
    4711 
    all  
}
date today 

MHo 2014-12-20: The above does not work if strings in quotes or braces by themselves contain the comment character #...

PYK 2014-12-20: That's true. See scripted list for a complete solution.

RLH 2006-07-13: Wouldn't it be nifty:
#-
  Everything in here is a comment or something similiar.
-#

FM With tcl above 8.5, the {*} idiom can be use in a list command :
set A [list \
    element1 \
    {*}[# comment
        # comment \
          comment
    ]\
    element2]

The subscript containing comments vanishes since it returns an empty string.

Historical  edit

The following information is maintained for historical purposes, but isn't particularly useful reading for modern Tcl

Any word corresponding to a bcc'ed command at the start of a line is risky ...:
% if 0 {set a b c}
% if 0 {if you want to write this, you can't}
% if 0 {while you read this, tcl errs out}

Therefore,
{#} {set any number of words; if you so wish} 

is more robust than "if 0 {...}", as long as you DO NOT forget the braces, and before 8.4. But
{#} do not [[exit]]

*will* exit ...