Функция Lisp возвращает NIL при использовании в функции меню, но в остальном работает
Я написал функцию для запроса небольшой программы базы данных, которую пишу для школы. Эта функция ищет по имени. Когда я запускаю функцию сама по себе, она работает. Когда я запускаю его в меню, он не работает (возвращает NIL). Вот все актуальное:
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
(defun search-name (name)
(remove-if-not
#'(lambda (cat) (equal (getf cat :name) name)) *db*))
(defun input-name ()
(search-name
(prompt-read "Name")))
(defun search-menu ()
(print "1) Search Name")
(print "2) Search Color")
(print "3) Search Min. Weight")
(print "4) Search Min. Experience")
(print "5) Search Min. Length")
(setf choose (read))
(cond ((= choose 1)(input-name))
((= choose 2)(print "Color"))
((= choose 3)(print "Weight"))
((= choose 4)(print "XP"))
((= choose 5)(print "Color"))
)
NIL
)
Прямо сейчас я работаю только над поиском имени, остальная часть меню - это просто заполнители. Когда я запускаю "input-name" (который использует search-name) сам по себе, он возвращает правильный результат. Когда я пробую первый вариант из меню поиска (который также запускает "input-name"), он возвращает NIL. Мне интересно, почему, когда я запускаю, он работает сам по себе, но не при использовании с этим меню. Если кому-то нужна другая информация, не стесняйтесь спрашивать. Я сделаю все возможное, чтобы это обеспечить. Кроме того, я новичок, так что, пожалуйста, простите меня.
3 ответа
Если вам нужен вывод в программе, вам нужно что-то напечатать.
(defun example ()
1000)
Вышеупомянутая функция ничего не печатает. Он просто возвращает число.
Если мы вызовем его в цикле чтения-оценки-печати:
CL-USER 134 > (defun example ()
1000)
EXAMPLE
CL-USER 135 > (example)
1000
Вы видите, что напечатано 1000. Но почему?
Мы запускаем это в READ-EVAL-PRINT- LOOP. Цикл read, eval, PRINT.
Означает: система Lisp печатает возвращаемое значение оценки, но не ваш код.
Теперь добавляем вызов печати:
CL-USER 136 > (defun example ()
(print 1000))
EXAMPLE
CL-USER 137 > (example)
1000
1000
Напечатано дважды!
CL-USER 137 > (example)
1000 ; <- the function example prints
1000 ; <- the read-eval-print-loop prints the result
Итак, наша функция теперь что-то печатает сама, поскольку она вызывает PRINT
.
Теперь это работает:
CL-USER 138 > (defun call-the-example ()
(example)
(values))
CALL-THE-EXAMPLE
CL-USER 139 > (call-the-example)
1000
Мы можем назвать example
функция, функция что-то печатает, а REPL ничего не печатает.
REPL ничего не печатает, так как call-the-example
ничего не возвращает. Он не возвращает значения.
Таким образом, вам нужно добавить вызов PRINT
Вы правы, добавив вызов печати, но причина проста в том, что раньше вы не печатали и вызов (input-name)
не печатал. Ты звонил(input-name)
в READ-EVAL-PRINT-LOOP, который затем распечатывает результат. Не ваш код, но REPL выводил.
Стиль: неопределенная переменная
(defun foo ()
(setf bar 10) ; <- BAR is undefined
(print bar) ; <- BAR is undefined
(setf bar 20) ; <- BAR is undefined
(print bar)) ; <- BAR is undefined
Напишите это вместо этого - используя LET
для определения локальной переменной:
(defun foo ()
(let ((bar 10)) ; define BAR
(print bar) ; BAR is defined
(setf bar 20) ; BAR is defined
(print bar))) ; BAR is defined
search-menu
ничего не делает с возвращаемым значением из input-name
. Функция возвращает значение последнего выражения, которое она выполняет, и последнего выражения вsearch-menu
является NIL
, так вот что он возвращает.
Если вы хотите, чтобы он возвращал значение cond
выражение, удалить NIL
с конца.
Вы также должны использовать let
объявить локальную переменную, а не назначать неопределенную переменную choose
.
(defun search-menu ()
(print "1) Search Name")
(print "2) Search Color")
(print "3) Search Min. Weight")
(print "4) Search Min. Experience")
(print "5) Search Min. Length")
(let ((choose (read)))
(cond ((= choose 1) (input-name))
((= choose 2) (print "Color"))
((= choose 3) (print "Weight"))
((= choose 4) (print "XP"))
((= choose 5) (print "Color")))))
В итоге я нашел решение, которое работает, просто используя print в функции input-name. Эта функция должна только показывать результаты, поэтому она работает нормально.
(defun input-name ()
(print
(search-name
(prompt-read "Name"))))
Та же функция, что и раньше, но с добавленной печатью. Теперь тоже работает в меню.