代码之家  ›  专栏  ›  技术社区  ›  Cam

函数式程序设计的正确注释

  •  12
  • Cam  · 技术社区  · 14 年前

    我一直在学习scheme,我刚刚意识到我真的不知道如何正确地注释我的函数scheme代码。我知道 怎样 当然,要添加评论,请添加 ; 把你的评论放在后面。我的问题是 什么 我应该在我的注释中添加注释吗?我应该在哪里添加注释,以使其他阅读我代码的程序员获得最大的可读性和可理解性?

    这是我写的一段代码。这是一个叫做 display-n . 它可以用任意数量的参数调用,并按提供的顺序将每个参数输出到屏幕。

    (define display-n
      (lambda nums
        (letrec ((display-n-inner 
                  (lambda (nums)
                    (display (car nums))
                    (if (not (equal? (cdr nums) (quote ()))
                        (display-n-inner (cdr nums))))))
          (display-n-inner nums))))
    

    '() 具有 (quote ()) 以免弄乱格式。

    我只是不知道如何/在何处添加评论以使其更易于理解。我看到的一些方案代码顶部有注释,如果您愿意的话,这非常好 使用 代码,但如果您想理解/修改它,则没有帮助。

    还有-我应该如何评论宏?

    4 回复  |  直到 14 年前
        1
  •  6
  •   Nietzche-jou    14 年前

    • 四个分号,用于注释文件的整个小节。
    • 三个分号用于引入单个过程。
    • 一个分号表示结束行注释。

    过程概述注释可能应该遵循RnRS文档的样式,因此只需按原样向过程中添加注释

    ;;; Procedure: display-n NUM ...
    ;; Output each argument to the screen in the order they are provided.
    (define 
      display-n (lambda nums
                  (letrec ((display-n-inner (lambda (nums)
                                              (display (car nums))
                                              (if (not (equal? (cdr nums) '()))
                                                  (display-n-inner (cdr nums))))))
                    (display-n-inner nums))))
    


    DISPLAY-N-INNER的参数称为NUMS并不是什么大问题,因为这个过程很短,DISPLAY-N只是直接将NUMS交给它。”不过,DISPLAY-N-INNER这个名字有点蹩脚。你可以给它一些更具语义的东西,或者给它一个简单的名字,比如“ITER”或“LOOP”。

    现在是关于 程序的一部分。第一, (equal? (cdr nums) '()) 是愚蠢的,最好是 (null? (cdr nums)) . 实际上,当您对整个列表进行操作时,最好将基本情况作为测试列表本身(而不是其CDR)是否为空的测试。这样,如果不传递任何参数,过程就不会出错(除非您希望它这样做,但我认为DISPLAY-N这样做更有意义) 什么也得不到)。此外,您应该测试是否 程序,而不是是否继续:

    (define (display-n . nums)
      (define (iter nums)
        (if (null? nums)
            #t  ; It doesn't matter what it returns.
            (begin (display (car nums))
                   (iter (cdr nums)))))
      (iter nums))
    

    但尽管如此,我要说的是,过程本身并不是完成它所做任务的最佳方式,因为它过于关注遍历列表的细节。相反,您将使用更抽象的FOR-EACH方法来完成这项工作。

    (define (display-n . nums)
      (for-each display nums))
    

        2
  •  4
  •   Eli Barzilay    14 年前

    一些随机注释:

    • 传统上,Scheme和Lisp代码使用 ;;; 对于顶级评论, ;; ; 与他们评论的代码在同一行的注释。Emacs对此有支持,对每一个都有不同的处理方式。但特别是在方案方面,这已经不像以前那么流行了,而是两者之间的区别 ;; ;

    • 大多数现代方案都采用了新的意见:有:

      • #|...|#
      • #;<expr> 是使实现忽略表达式的注释,这对调试很有用。
    • 至于要写什么的实际内容,这与任何其他语言都没有什么不同,只是使用功能性更强的方法,您通常可以在如何布局代码上有更多的选择。它还使编写更小的函数更加方便,这些函数被组合成更大的功能片段——这也改变了文档的风格,因为许多这样的小函数将是“自文档化的”(因为它们易于阅读,并且在工作方式上非常明显)。

    • 我不想听起来像一张破唱片,但我仍然认为你应该花点时间和HtDP在一起。它在设计方法中鼓励的一件事是先编写示例,然后编写文档,然后将其扩展到实际代码。此外,这个方法留给您的代码有一组非常标准的注释:输入/输出类型、目的语句、一些关于函数在必要时如何实现的文档,这些示例可以被视为另一种文档(在“真实”代码中变成注释代码)(还有其他一些书也采取了类似的立场。)

    • 最后,记录宏与记录任何其他代码没有什么不同。唯一不同的是注释中写了什么:不是描述某个函数在做什么,而是描述它的代码 同样,评论也更多的是元层次的。宏的一种常见方法是尽量减少宏内部的工作——即在该级别所需的工作(例如,将表达式包装在 (lambda () ...)

        3
  •  2
  •   chollida    14 年前

    我遵循一种类似于此处所述的方法:

    http://www.cc.gatech.edu/computing/classes/cs2360/ghall/style/commenting.html

    注意:这是用于公共Lisp的。

    " Four Semicolons(;;;;)
    ...denote a sub heading in the file...
    
    Three Semicolons(;;;)
    ...denote a description of the succeeding function, macro, or
    variable definition...
    [I usually just most of the description into the "docstring"
      of the function or variable.] 
    
    
     Two Semicolons(;;)
     ...denote a description of the succeeding expression...
    
     One Semicolon(;)
     ...denotes an in-line comment that explains a particular element
        of the expression on that line... Brevity is important for
        inline comments"
    
        4
  •  0
  •   David Gelhar    14 年前

    我认为一个很好的开始就是用一句话来描述函数的作用

    它可以用任意数量的参数调用,并按提供的顺序将每个参数输出到屏幕。