Функция Lisp возвращает NIL при использовании в функции меню, но в остальном работает - PullRequest
1 голос
/ 05 февраля 2020

Я написал функцию для запроса программы для небольшой базы данных, которую я пишу для школы. Эта функция ищет по имени. Когда я запускаю функцию, она работает. Когда я запускаю его в меню, оно не работает (возвращает 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 ]

2 голосов
/ 05 февраля 2020

Если вы хотите выводить данные в программе, вам нужно что-то напечатать.

(defun example ()
  1000)

Приведенная выше функция ничего не печатает. Он просто возвращает число.

Если мы назовем его в read-eval-print-l oop:

CL-USER 134 > (defun example ()
                1000)
EXAMPLE

CL-USER 135 > (example)
1000

Вы видите, что напечатано 1000. Но почему?

Мы запускаем его в READ-EVAL- PRINT -L OOP. Read, eval, PRINT , l oop.

Означает: система Lisp печатает возвращенное значение оценки, но не ваш код.

Сейчас мы добавляем print call:

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-L OOP, которая затем печатает результат. Не ваш код, но 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
0 голосов
/ 12 февраля 2020

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")))))
0 голосов
/ 05 февраля 2020

Я закончил тем, что нашел решение, которое работает, просто используя print в функции input-name. Эта функция должна показывать только результаты, поэтому она прекрасно работает.

(defun input-name ()                                                           
  (print                                                                       
  (search-name                                                                 
   (prompt-read "Name")))) 

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

...