[r6rs-discuss] [Formal] #;<datum> comments useless

Trent Buck trentbuck at gmail.com
Sat Sep 30 00:58:30 EDT 2006


On Fri, Sep 29, 2006 at 09:06:08PM -0700, Per Bothner wrote:
> >Firstly, when the comment expression is the last subexpression, it
> >does not break up the trailing parens with the closing lexeme.  Of the
> >following two forms, I consider the former more aesthetically pleasing
> >than the latter.
> >
> >    (+
> >     (- foo
> >        bar
> >        #;
> >        (this is
> >              a
> >              long
> >              (expression (that
> >                           has
> >                           many
> >                           parens)))))
> >    
> >    
> >    (+
> >     (- foo
> >        bar
> >        #|
> >        (this is
> >              a
> >              long
> >              (expression (that
> >                           has
> >                           many
> >                           parens)))|#))
> 
> Aa I said above: you really don't want this in production code, or more
> generally anything that is 'checked in" (to a source-code repository).
> What is the purpose?

One that immediately occurs to me is when one replaces a simple
definition with an optimized definition, and you want to leave the
original definition as a comment.  A contrived example:

    (define (f x)
      #;
      (+ (* x x)
         (* x x))
      (let ((x* (* x x)))
        (+ x* x*)))

I guess ultimately I see #; as a case of say-what-you-mean.  I'm not
commenting out a paragraph of text, I'm commenting out an expression.

> If you want to comment out a fragment of production code you need to
> explain *why* it is commented out, using *text* - and so it's no
> longer an s-expr.

The comment and the elided expression don't have to be part of the
same comment.

    (define (f x)
      ;; The original version
      #;
      (+ (* x x)
         (* x x))
      ;; The optimized version
      (let ((x* (* x x)))
        (+ x* x*)))

> Furthermore, it seldom makes sense to comment out an s-expr, especially
> in a functional (or mostly-functional) language.  You comment out a
> parameter to a function, and the function suddenly has the wrong arity.
> It only makes sense for side-effecting actions whose values are ignored,
> or rare parameters to variable-arity functions.

Even without side-effects (which removes the need for variadic LAMBDA,
BEGIN and DEFINE), you still have variadic COND, CASE, AND, OR, LET,
LET* and LETREC (within the binding parameter), DO (within the binding
and test parameters), LET-SYNTAX, LETREC-SYNTAX and SYNTAX-RULES.

I hardly think these are "rare".  It's also kind of uncommon for a
Scheme document to have only one definition at the top level.

>> Secondly, because #; guarantees to comment out exactly one expression,
>> I do not need to look for the closing lexeme.  In the above example,
>> it would be quite easy for a student to accidentally write
>> 
>>     (+
>>      (- foo
>>         bar
>>         #|
>>         (this is
>>               a
>>               long
>>               (expression (that
>>                            has
>>                            many
>>                            parens))|#)))
>> 
>> producing a syntactic error that is potentially very difficult to
>> detect (without a smart editor).
> 
> But since you should always use a smart editor, this point is moot.

Except, of course, when reading a physical printout or PDF.

> It is also moot because the example is not an illustration of
> something anyone would want to do - it's a contrived example
> without motivation.

Very well, here is a real-world example, from some throwaway code to
turn OpenOffice documents into a plain text format.  Excuse the
exorbitant length.

    (define transform
      (lambda (e)
        (sxml-match e
          ;; Promote content of single-content blocks
          [(*TOP* ,(x)) x]
          [(document-content ,(x)) x]
          [(span ,(x)) x]
          [(sequence ,(x)) x]
          [(creation-date ,(x)) x]
          [(editing-cycles ,(x)) x]
          [(text-box ,(x)) x]
    
          [(body . ,xs)
           (fold body "" (map transform (reverse xs)))] ; hack to prevent stack overflow.
          #;
          [(body ,(x) ...)
           (body x ...)]
          
    
          [(p (line-break) ,x ...)          ; drop leading line-break
           (transform (list 'p x ...))]      
          [(p ,x ... (line-break))          ; drop trailing line-break
           (transform (list 'p x ...))]
          [(p (s) ,x ...)                   ; drop leading s
           (transform (list 'p x ...))]      
          [(p ,x ... (s))                   ; drop trailing s
           (transform (list 'p x ...))]
          [(p ,(x) ...)
           (p x ...)] 
    
    
          ;;; This is a hack to fix a very specific problem in a very, very stupid document.
          #;
          [(h (@ . ,as) (p (image . ,xs) . ,ys) ,z)
           (body (transform `(h (@ . ,as) ,z))
                 (transform `(p (image . ,xs) . ,ys)))]
          #;
          [(p (image . ,xs) . ,ys)
           (body (transform (cons 'image xs))
                 (transform (cons 'p ys)))]
    
    
          [(h (@ (level ,n)) ,(x) ...)
           (h (string->number n) (string-append x ...))]
    
          [(a (@ (href ,(href)) . ,attributes) ,(name))
           (if (string-ci=? href name)
               href
               (a href name))]
    
          [(image (@ (href ,(url)) . ,attributes))
           (image url)]
    
          [(date (@ (date-value ,iso-date) . ,attributes) ,x)
           iso-date]
    
          [(table-of-content)
           table-of-content]
    
          [(s) 
           s]
    
          [(line-break) line-break]
    
          [(table ,(x) ...)
           (table x ...)]
    
          [(table-row ,(x) ...)
           (table-row x ...)]
    
          [(table-cell ,(x) ...)
           (table-cell x ...)]
          
          [(ordered-list . ,xs)
           (ordered-list xs)]
    
          [(unordered-list . ,xs)
           (unordered-list xs)]
    
          ;; Everything else is unchanged
          (,x (->string x)))))

To take an excerpt, it is easy to see that

          #;
          [(body ,(x) ...)
           (body x ...)]

comments out exactly one clause, whereas

          #|
          [(body ,(x) ...)
           (body x ...)]
          |#

requires the (human) reader to look for the closing lexeme.

> >Thirdly, it is safe for an editor to assume that the expression
> >commented out by #; is a symbolic expression, rather than arbitrary
> >text.  This means it can safely provide the same indenting and
> >structured editing facilities that it provides outside of comments.
> >For example, if the buffer contains
> >
> >    #;-!- A
> >
> >then typing ( could usefully insert both opening and closing
> >parentheses:
> >
> >    #;(-!-) A
> >
> >And if the buffer contains
> >
> >    #;(foo bar-!- baz)
> >
> >then typing Return could usefully indent after adding a newline:
> >
> >    #;(foo bar
> >           -!-baz)
> >
> >In the above examples, -!- indicates the position of the cursor.
> 
> But without any meaningful examples showing the use of s-expr comments
> in real code it seems the feature should go away for lack of usefulness.

See above for such an example.

> I.e. the proponents of #; need to illustrate how using #; is better
> that #|...|# in real code, or at least during development (debugging).
> I have seen no such examples.
> -- 
> 	--Per Bothner
> per at bothner.com   http://per.bothner.com/

-- 
Trent Buck, Student Errant



More information about the r6rs-discuss mailing list