0

fedora-13 マシンに clisp をインストールしました。clisp インタープリターで、次のように入力しました。

(defun ask-num ()
    (format t "Please enter a number.")
    (let ((val (read)))
        (if (numberp val)
            val
            (ask-num))))

以下は、Paul Graham の本の元のコードです。

(defun ask-number ()
  (format t "Please enter a number. ")
  (let ((val (read)))
    (if (numberp val)
        val
        (ask-number))))

私が見逃したものはありますか?これは、コードのエラーというよりも、インタープリターの特異性のように思えます。ここにリンクがあります。問題のコードに対して ctrl-F が必要になる場合があります。

更新: ハハ、そうですね...問題です!

[9]> (defun ask-num ()
    (format t "Please enter a number.")
    (let ((val (read)))
        (if (numberp val)
            val
            (ask-num))))
ASK-NUM
[10]> ask-num

*** - SYSTEM::READ-EVAL-PRINT: variable ASK-NUM has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of ASK-NUM.
STORE-VALUE    :R2      Input a new value for ASK-NUM.
ABORT          :R3      Abort main loop
4

3 に答える 3

2

CLISP に関数を実行させるには、(ask-num)ではなくと入力する必要があります。ask-num

[1]> (defun ask-num ()
    (format t "Please enter a number.")
    (let ((val (read)))
        (if (numberp val)
            val
            (ask-num))))
ASK-NUM
[2]> (ask-num)
Please enter a number.1
1
[3]> ask-num

*** - SYSTEM::READ-EVAL-PRINT: variable ASK-NUM has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of ASK-NUM.
STORE-VALUE    :R2      Input a new value for ASK-NUM.
ABORT          :R3      Abort main loop
Break 1 [4]> 
于 2011-05-31T03:14:01.767 に答える
0

paxdiablo が言ったように、clisp は ask-num を変数として評価しようとしていました。Common Lisp には、関数とその他の種類の値に対して別個の名前空間があります。関数はたまたまクロージャーである値として扱われるだけだと思う​​かもしれませんが、代わりにそれらは別々に格納され、検索されます。

閉鎖が必要な場合は、入力できます

[1]> #'ASK-NUM

返す

#<FUNCTION ASK-NUM NIL (DECLARE (SYSTEM::IN-DEFUN ASK-NUM))
  (BLOCK ASK-NUM (FORMAT T "Please enter a number.")
   (LET ((VAL (READ))) (IF (NUMBERP VAL) VAL (ASK-NUM))))>

ここで詳細を読むことができます: http://en.wikipedia.org/wiki/Common_Lisp#The_function_namespace

于 2011-07-03T20:46:43.177 に答える
0

あなたが抱えている問題を指摘していないので、私にできる最善のことは、それを再現することです.

ただし、そのコードは CLISP 2.44.1 を使用する Ubuntu 10 で問題なく動作します。

pax@pax-desktop:~$ clisp

  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.44.1 (2008-02-23) <http://clisp.cons.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2008

Type :h and hit Enter for context help.

[1]> (defun ask-num ()
    (format t "Please enter a number.")
    (let ((val (read)))
        (if (numberp val)
            val
            (ask-num))))
ASK-NUM
[2]> (ask-num)
Please enter a number.hello
Please enter a number.goodbye
Please enter a number.3141592653589
3141592653589
[3]> 

したがって、私が本当に提案できるのは、上記のトランスクリプトが示していることを正確に実行しようとすることだけです. それでも問題が解決しない場合は、最新バージョンの CLISP を使用していることを確認し、発生している実際の問題で質問を更新してください (すべての適切な質問には、問題に至る状況と共に、予想される実際の動作が含まれている必要があります)


実際のエラーを投稿したので、そもそも関数をどのように呼び出したかという単純な問題であることがわかります。(ask-num)指定したリンクで指定されているように、で呼び出す必要があります。

(ask-number)
Please enter a number. a
Please enter a number. (ho hum)
Please enter a number. 52
52

そのエラーが発生する理由は、 unadornedask-numが変数として評価されているためです (実際には関数である場合)。ここで実際にこれを見ることができます:

pax@pax-desktop:~$ clisp
: : : : :
Type :h and hit Enter for context help.

[1]> 42
42
[2]> myvar

*** - EVAL: variable MYVAR has no value
The following restarts are available:
USE-VALUE      :R1      You may input a value to be used instead of MYVAR.
STORE-VALUE    :R2      You may input a new value for MYVAR.
ABORT          :R3      Abort main loop
Break 1 [3]> (set 'myvar 42)
42
Break 1 [3]> myvar
42
Break 1 [3]>
于 2011-05-31T03:03:33.293 に答える