2017-02-16 16 views
3

The Common Lisp Hyperspec page for print упоминает об этом:Зачем печатать выходные данные Common Lisp перед новой строкой, а затем пробел?

печать так же, как prin1 за исключением того, что выводимое представление объекта предшествует символ новой строки и последующим пробелом.

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

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

Я предполагаю, что это может быть связано с обеспечением того, чтобы выход всегда читался с read прямо из print. Хотя я бы предпочел новую строку для этого, я могу догадаться, что конечное пространство может быть таким, что в потоке read может знать, что это конец объекта и немедленно вернуть его, не дожидаясь остальной части потока (следующие print с). Тем не менее, я до сих пор не могу понять цель, лежащую в основе предшествующей новой строки.

Я просматривал HyperSpec, но я не могу найти причину упоминания.

EDIT:

Я посмотрел в предшественник Common-Lisp в частности, INTERLISP, Maclisp и предшественник Maclisp в Лиспе 1.5.

Interlisp (страница 145 в this pdf) и функция Lisp 1.5 (страница 140 в this pdf) print функция распечатывает объект, за которым следует новая строка.

Кажется, что MacLisp представил эту разницу. Я не нашел причину в первоначальном справочном руководстве, и я только нашел следующие on this revised reference manual:

Как PRIN1, PRINT выводит объект в файл в форме, которая может быть понята READ. Тем не менее, объект выводится с символом новой строки, за которым следует пробел, так что повторные вызовы PRINT могут быть выполнены без завершения одного объекта в начале следующего.

Конечно, для этой цели хватило бы новой строки в исходном определении, поэтому эта причина кажется нецелесообразной.

EDIT 2:

Как показывает ответ Райнера Joswig, это кажется, что это изменение появилось в Лисп 1.6 перед тем Maclisp.

+2

Я просто догадываюсь, но я бы сказал, что ведущая новая строка - это просто вариант на задней новой строке (один стандарт, возможно, так же хорош, как и другой); и что конечное пространство связано с тем, что, когда «print» был сначала написан, вам нужно переместить печатающую головку механического TTY в сторону, чтобы вы могли видеть, что было написано. – Dolda2000

+0

@ Dolda2000 Изучив предшественники CL и обнаружив, что изначально 'print' _did_ просто выводит конечную новую строку в Lisp 1.5, это кажется маловероятным. – JoL

ответ

5

Смотрите, например: PDP-6 LISP (LISP 1.6) Revised. (January 1967)

Мое предположение было бы, что этот вариант PRINT (который записывает символ новой строки, то S-выражение в читаемом формате, а затем пробел) поступил в отделение MIT Лиспа из-за его используйте в Read Read Eval Print Loop. См. Стр. 1 и 17 выше. Из PDP-6 Lisp 1.6 он перешел в то, что тогда называлось Maclisp и дальше.

Jon L White знал бы это.

Посмотрите на пример для РЕПЛ, то чтения Eval цикл PRINT, на странице 1. Здесь я использую слушателя LispWorks Лисп, где последняя закрывающая скобка уже делает READпринять S-выражение и нет далее введите необходимо:

CL-USER 25 > (PROG NIL 
       A 
       (TERPRI) 
       (PRINT (EVAL (READ))) 
       (GO A)) 

(+ 12 12) 
24 
(+ 45 (* 
     34 
     12 
     12)) 
4941 

Каждый результат на своей собственной линии. Это кстати. также как взаимодействие на MIT Lisp Machine - последняя закрывающая скобка входит в s-выражение, выражение оценивается и выводится значение.

Теперь представьте себе, что она определяется не напечатать строку первой:

CL-USER 27 > (PROG NIL 
       A 
       (TERPRI) 
       (PRIN1 (EVAL (READ))) 
       (terpri) 
       (GO A)) 

(+ 1 2)3 

(* 23 (+ 1 
     1 
     3))115 

Результат будет напечатан непосредственно после последней закрывающей скобкой.

Питер Норвиг дает то же рассуждение в своей книге Парадигмы искусственного интеллекта Программирование, стр 231/232 (как отмечено пользователем DKIM):

В Лиспе, однако, функция печать ставит в newline перед объектом, который будет напечатан, и пробелом после. ... В UNIX существует только одна разумная политика, потому что все входные данные для интерпретатора UNIX (оболочки) заканчиваются символами новой строки, поэтому нет необходимости в новой строке. Однако в некоторых интерпретаторах Lisp ввод может быть завершен с помощью подходящей круглой скобки. В этом случае необходима новая строка-before, чтобы выход не отображался в той же строке, что и вход.

+0

Это показывает, что действительно это изменение было в Lisp 1.6 до MacLisp, но ни этот ответ, ни страницы, на которые вы ссылаетесь, не упоминают о причине дизайна, и это то, что я искал. – JoL

+0

@jimg: см. Пример ответа со страницы 1, расширенный в моем ответе. –

+0

"результат будет напечатан сразу после последней закрывающей круглой скобки" Это не происходит со мной, потому что вход терминала по умолчанию буферизирован. Я должен нажать '^ D' после закрытия круглой скобки, чтобы получить результат, который вы видите, но естественным является нажатие Enter, и поэтому результат будет напечатан в следующей строке. – JoL

2

В основном это функция REPL-only, что-то вроде линий «trace» или debug ».

Прецедент Это что-то вроде

(map nil #'print list) 

или, в более общем плане,

(complex-traversal-map #'print weird-structure) 

Он вставляет пробелы вокруг печатного объекта, чтобы избежать помех с выходом других print вызовов. Из-за каких-то пробелов эволюционировали на протяжении десятилетий. Его следовало называть print-on-a-separate-line, но он должен был быть коротким и легко догадаться.

Это по существу «устаревшая» функциональность, например rplaca and rplacd.

+0

Звучит разумно, и это, вероятно, то, для чего он наиболее полезен. Если у вас есть источник на руку, это было бы здорово упомянуть, но я понимаю, что официальную причину можно нигде не упоминать. Во всяком случае, я буду принимать этот ответ завтра, если к тому времени не появится лучший ответ. – JoL