【问题标题】:Common Lisp let functionCommon Lisp 让函数
【发布时间】:2017-10-19 03:02:59
【问题描述】:

我刚刚开始使用 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 块内调用函数,所以我假设我犯了一个错误。欢迎对我的代码提供任何其他提示。

【问题讨论】:

标签: common-lisp let


【解决方案1】:

您的代码:

(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))))

【讨论】:

  • 好的,谢谢。为什么 get-int 和 get-string 等函数不被识别?
  • @Mitchell:目前还不清楚你试图编译什么以及如何编译。我只看到函数 CIPHER-CALC... 的警告
  • 是的,一旦我解决了它自己解决的变量问题。再次感谢。
【解决方案2】:

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" ...))

【讨论】:

  • 谢谢,我没有意识到我将这些列表定义为函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
相关资源
最近更新 更多