开发者

common lisp - ch 02, code error?

I've installed clisp on my fedora-13 machine. In the clisp interpreter, i've en开发者_运维知识库tered the following:

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

Here is the original code from Paul Graham's book:

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

is there something I've missed? this seems more like an idiosyncracy with the interpreter rather than an error in the code. Here is the link. You may have to ctrl-F for the code in question.

UPDATE: haha, right...the problem!

[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


You should be typing (ask-num), not ask-num, in order to have CLISP execute your function.

[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]> 


Since you don't indicate the problem you're having, the best I can do is to try and replicate it.

However, that code works just fine under Ubuntu 10 with CLISP 2.44.1:

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]> 

So, all I can really suggest is that you try to do exactly what the above transcript shows. If that still has a problem, make sure you have a recent version of CLISP and update the question with the actual problem you're having (all good questions should have expected and actual behaviour along with the circumstances leading up to the problem).


Now that you've posted your actual error, we can see it's a simple matter of how you called the function in the first place. You have to call it with (ask-num), as specified in the link you gave:

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

The reason why you're getting that error is because an unadorned ask-num is being evaluated as a variable (when, in reality, it's a function). You can see this in action here:

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]>


As paxdiablo said, clisp was trying to evaluate ask-num as a variable. Common Lisp has separate namespaces for functions and other kinds of values. You might expect a function to just be treated as a a value which happens to be a closure, but instead they're stored and looked up separately.

If you did want the closure, you could enter

[1]> #'ASK-NUM

which returns

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

You can read more about it here: http://en.wikipedia.org/wiki/Common_Lisp#The_function_namespace

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜