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

From: Trent Buck <trentbuck>
Date: Sat Sep 30 00:59:12 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 (_at_ . ,as) (p (image . ,xs) . ,ys) ,z)
           (body (transform `(h (_at_ . ,as) ,z))
                 (transform `(p (image . ,xs) . ,ys)))]
          #;
          [(p (image . ,xs) . ,ys)
           (body (transform (cons 'image xs))
                 (transform (cons 'p ys)))]
    
    
          [(h (_at_ (level ,n)) ,(x) ...)
           (h (string->number n) (string-append x ...))]
    
          [(a (_at_ (href ,(href)) . ,attributes) ,(name))
           (if (string-ci=? href name)
               href
               (a href name))]
    
          [(image (_at_ (href ,(url)) . ,attributes))
           (image url)]
    
          [(date (_at_ (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
Received on Sat Sep 30 2006 - 00:58:30 UTC

This archive was generated by hypermail 2.3.0 : Wed Oct 23 2024 - 09:15:01 UTC