Common Lisp let функция

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

(defun input-1 ()
       (defvar *message* (read-line))
       (defvar *a-value* (parse-integer(read-line)))
       (defvar *b-value* (parse-integer(read-line))))

(defun alphabet (list " " "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
         "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))

(defun alphabet-num (list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
             20 21 22 23 24 25 26 27 28 29))
;(defun inverse (value)
;  (let ((x 0))
;    (loop while (< x 29)
;    (print x))))

(defun inverse (value)
       (dotimes (x 28)
           (when (equal (mod (* x value) 29) 1)
             (return-from inverse x))))

(defun get-int (string)
  (getf (position string alphabet) alphabet-num))

(defun get-string (int)
  (getf (position int alphabet) alphabet))

(defun cipher-calc (character)
  (let ((c-int (get-int character))
    (f-char ""))
    (setf c-int (* *a-value* (- c-int *b-value*)))
    (setf f-char (get-string (mod (abs c-int) 29)))))

Однако я получаю эту ошибку

; in: DEFUN CIPHER-CALC
;     (* *A-VALUE* (- C-INT *B-VALUE*))
; 
; caught WARNING:
;   undefined variable: *A-VALUE*

;     (- C-INT *B-VALUE*)
; 
; caught WARNING:
;   undefined variable: *B-VALUE*

;     (GET-INT CHARACTER)
; 
; caught STYLE-WARNING:
;   undefined function: GET-INT

;     (GET-STRING (MOD (ABS C-INT) 29))
; 
; caught STYLE-WARNING:
;   undefined function: GET-STRING
; 
; compilation unit finished
;   Undefined functions:
;     GET-INT GET-STRING
;   Undefined variables:
;     *A-VALUE* *B-VALUE*
;   caught 2 WARNING conditions
;   caught 2 STYLE-WARNING conditions

Мне трудно поверить, что вы не можете вызвать функцию внутри блока let, поэтому я предполагаю, что совершаю ошибку. Буду рад любым другим советам по моему коду.


person Mitchell    schedule 19.05.2017    source источник
comment
Возможный дубликат В чем разница между использованием let и var объявить переменную?   -  person Renzo    schedule 19.05.2017


Ответы (2)


Ваш код:

(defun input-1 ()
  (defvar *message* (read-line))
  (defvar *a-value* (parse-integer(read-line)))
  (defvar *b-value* (parse-integer(read-line))))

DEFVAR предполагается использовать на верхнем уровне, а не внутри функции. В этом случае переменные будут определены при запуске функции. Но когда вы просто компилируете, оцениваете или загружаете такую ​​функцию, переменная не определяется. Таким образом, компилятор позже предупредит, что в вашем коде эти переменные не определены.

Когда DEFVAR используется на верхнем уровне, Lisp распознает наличие определений переменных.

(defvar *message*)
(defvar *a-value*)
(defvar *b-value*))

(defun input-1 ()
  (setf *message* (read-line))
  (setf *a-value* (parse-integer (read-line)))
  (setf *b-value* (parse-integer (read-line))))
person Rainer Joswig    schedule 19.05.2017
comment
Хорошо, спасибо. Почему такие функции, как get-int и get-string, не распознаются? - person Mitchell; 19.05.2017
comment
@Mitchell: неясно, что вы пытались скомпилировать и как. Я вижу только предупреждения для функции CIPHER-CALC... - person Rainer Joswig; 19.05.2017
comment
Да, как только я решил проблему с переменными, она разрешилась сама собой. Спасибо еще раз. - person Mitchell; 19.05.2017

defvar делает не то, что вы думаете. Это гарантирует, что переменная существует, и если она не существует, она привязывает ее ко второму аргументу. Таким образом:

(defvar *test* 5)
(defvar *test* 10) ; already exist, has no effect
*test* ; ==> 5

Что вы можете сделать, так это определить их так в верхней части вашего файла и использовать setf в своей функции:

(defvar *message*)

(defun input-1 ()
       (setf *message* (read-line))
       ...)

Ведь настройка — это то, что вы делаете. Вы смешиваете функции и переменные с alphabet. Здесь вы можете использовать defparameter. Это похоже на defvar, но всегда перезаписывается при загрузке файла:

(defparameter *alphabet* (list " " "a" "b" ...))
person Sylwester    schedule 19.05.2017
comment
Спасибо, я не знал, что определяю эти списки как функции. - person Mitchell; 19.05.2017