Функции типа princ
, print
, ecc.выполнить две разные задачи:
- Они выводят свои аргументы на стандартный вывод, который обычно является терминалом, но может быть другим, если специальная переменная
*standard-output*
является отскоком; - Они возвращают аргумент, напечатанный как значение языка.
Например:
CL-USER> (+ (print 1) (print 2))
1 ; <- printed by (print 1), which returns also 1
2 ; <- printed by (print 2), which returns also 2
3 ; <- the sum of 1+2, printed by the REPL, not by the program!
Итак, если вы попытаетесь, например, (writepoly -1 10 t)
, вы получите:
CL-USER> (writepoly -1 10 t)
-x^10 ; <- printed by writepoly
10 ; <- returned by writepoly
Другими словами, ваша программа печатает что-то и возвращает что-то еще, например последнюю функцию, в которой вы печатаете полином, но возвращаете NIL (как ясно, читая две строки после вызова print-pexpr
), и этопричина ошибки.
Как можно изменить программу, чтобы она возвращала напечатанную строку?В основном есть две возможности.Первое - это то, что было предложено в ответе Райнера Джосвинга с использованием двух вещей: функции with-output-to-string
, которая создает новый выходной поток, в котором все, что «напечатано», возвращается в конце какодна строка, вторая с указанием в качестве имени этого потока *standard-output*
, который на практике «инструктирует» все команды печати (без явного параметра потока) печатать на этой строке (в противном случае вы должны изменить все вызовы печати, добавив явнопоток для печати).
Таким образом, вы можете изменить свою последнюю функцию с помощью:
(defun print-pexpr (P)
(with-output-to-string (*standard-output*)
(loop for (a . b) in P
for start = t then nil
do (writepoly a b start))))
Альтернативный способ состоит в том, чтобы вместо вывода результата в какой-либо поток преобразовать егов строке, используя format
с первым параметром NIL
вместо print (как, например, (format () "~a" expression)
), а затем concatenate
все эти строки водин при объединении различных частей (используя снова format
или concatenate
).Это требует больше изменений в вашей программе.