Надлежащий комментарий для функционального программирования

Я изучал схему, и я просто понял, что действительно не знаю, как правильно прокомментировать мой функциональный код схемы. Я знаю, как добавить комментарий, конечно - Вы добавляете a ; и помещенный Ваш комментарий после него. Мой вопрос - то, что я должен вставить свои комментарии, и где я должен прокомментировать для максимальной удобочитаемости и понятности для других программистов, читающих мой код?

Вот фрагмент кода, который я записал. Это - вызванная функция 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 ()) избегать НАСТОЛЬКО портящий форматирование.

Я просто не уверен, как/где добавить комментарии для создания этого более понятным. Некоторая схема кодирует, я видел, просто имеет комментарии наверху, который является большим, если Вы хотите использовать код, но не полезные, если Вы хотите понять/изменить это.

Также - как я должен прокомментировать макросы?

12
задан Cam 12 July 2010 в 19:03
поделиться

4 ответа

Обычный стиль комментариев в Lisp следующий

  • Четыре точки с запятой для комментария к целому подразделу файла.
  • Три точки с запятой для введения одной процедуры.
  • Две точки с запятой для описания определения выражения/процедуры на следующей строке.
  • Одна точка с запятой для комментария в конце строки.

Комментарии к обзору процедуры, вероятно, должны соответствовать стилю документов 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))))

N.B. Я не использую три точки с запятой для всего описания процедуры, поскольку это портит fill-paragraph в Emacs.


Теперь о коде, я бы отказался от всего этого define-variable-as-a-lambda. Да, я понимаю, что это самый "чистый" способ определить функцию, и это обеспечивает хорошую последовательность в определении процедур как результатов LET и других процедур, но есть причина для синтаксического сахара, и она заключается в том, чтобы сделать вещи более читаемыми. То же самое для LETREC - просто используйте внутренний DEFINE, что то же самое, но более читабельно.

Нет ничего страшного в том, что параметр 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))

Таким образом, вместо того, чтобы читатель процедуры погряз в деталях CAR и CDR, он может просто понять, что FOR-EACH выведет каждый элемент NUMS.

6
ответ дан 2 December 2019 в 21:42
поделиться

Некоторые случайные примечания:

  • Традиционно в коде Scheme и Lisp использовались ;;; для комментариев верхнего уровня, ;; для комментариев в коде и ; для комментариев к той же строке, что и код, который они комментируют. Emacs поддерживает это, рассматривая каждый из них немного по-своему. Но особенно на стороне схемы это уже не так популярно, как было, но разница между ;; и ; по-прежнему распространена.

  • В большинстве современных схем используются новые виды комментариев: theres:

    • # | ... | # для блочного комментария - полезно для длинных фрагментов текста, которые комментируют весь файл.
    • #; - это комментарий, который заставляет реализацию игнорировать выражение, что полезно для отладки.
  • Что касается фактического содержания того, что писать, оно не отличается от любого другого языка, за исключением того, что при более функциональном подходе у вас обычно есть больше вариантов того, как разложить свой код. Это также делает более удобным написание более мелких функций, которые объединяются в более крупные функциональные возможности - и это также меняет стиль документации, поскольку многие такие небольшие функции будут «самодокументироваться» (в том смысле, что они легко читаются и очень очевидно, как они работают).

  • Мне неприятно звучать как зажившая пластинка, но я все же считаю, что вам стоит потратить некоторое время на HtDP. Одна вещь, которую он поощряет в своем рецепте дизайна, - это сначала писать примеры, затем документацию, а затем расширять ее до реального кода.Кроме того, этот рецепт оставляет вам код с очень стандартным набором комментариев: типы ввода / вывода, формулировку цели, некоторую документацию о том, как реализована функция, когда это необходимо, и примеры можно рассматривать как другой вид документации ( который превратился бы в закомментированный код в «реальном» коде). (Есть и другие книги, которые занимают аналогичную позицию по отношению к документации.)

  • Наконец, документирование макросов ничем не отличается от документирования любого другого кода. Единственное, что может сильно отличаться от того, что написано в комментариях: вместо описания того, что делает какая-то функция, вы склонны описывать, какой код она также расширяет , поэтому комментарии также больше относятся к мета-уровню . Общий подход к макросам заключается в минимальной работе внутри макроса - именно то, что необходимо на этом уровне (например, обернуть выражения в (lambda () ...) ), а фактическую реализацию оставить на функция. Это также помогает в документировании, поскольку в двух связанных частях будут комментарии о том, как макрос расширяется и как он выполняется независимо.

4
ответ дан 2 December 2019 в 21:42
поделиться

Я использую подход, похожий на тот, что выложен здесь:

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

Примечание: это для Common 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"
2
ответ дан 2 December 2019 в 21:42
поделиться

Я думаю, отличным местом для начала было бы поместить ваше односложное описание того, что делает функция

Она может быть вызвана с любым количеством аргументов и выводит каждый аргумент на экран в том порядке, в котором они предоставлены.

в качестве комментария в начале.

Я не особенно разбираюсь в схеме, поэтому не могу прокомментировать (:-)), ожидаются ли дополнительные построчные комментарии, объясняющие механику того, как функция достигает этого результата, в соответствии с обычным стилем схемы (но я подозреваю, что нет).

0
ответ дан 2 December 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: