Функция 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")))) 

Та же функция, что и раньше, но с добавленной печатью. Теперь тоже работает в меню.

Другие вопросы по тегам