common lisp - ch 02, code error? - clisp

I've installed clisp on my fedora-13 machine. In the clisp interpreter, i've entered 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

Related

How to do looping in lisp?

Just started learning and coding lisp,
I'm trying to create a program that will continuously accept a number and stops only if and only if the last input number is twice the previous number.
Here's my code
----------
(let((a 0)
(b 0)
(count 0))
(loop
(= a b))
(princ"Enter Number: ")
(defvar a(read))
(format t "~% a = ~d" a)
(setq count (1+ count))
(while
(!= b(* a 2) || <= count 1)
(princ "Program Terminated Normally")
)
Thank you
a bit feedback
(let ((a 0)
(b 0)
(count 0))
(loop
(= a b)) ; here the LOOP is already over.
; You have a closing parenthesis
; -> you need better formatting
(princ"Enter Number: ")
(defvar a(read))
(format t "~% a = ~d" a)
(setq count (1+ count))
(while
(!= b(* a 2) || <= count 1)
(princ "Program Terminated Normally")
)
some improved formatting:
(let ((a 0)
(b 0)
(count 0))
(loop
(= a b)) ; LOOP ends here, that's not a good idea
(princ "Enter Number: ")
(defvar a(read)) ; DEFVAR is the wrong construct,
; you want to SETQ an already defined variable
(format t "~% a = ~d" a)
(setq count (1+ count))
(while ; WHILE does not exist as an operator
(!= b(* a 2) || <= count 1) ; This expression is not valid Lisp
(princ "Program Terminated Normally")
)
You may need to learn a bit more Lisp operators, before you really can write such loops. You also may want to use Lisp interactively and try out things, instead of trying to write code into an editor and never get feedback from a Lisp...
Here's an answer which definitely is not how you would do this in real life, but if you understand what it does you will understand one of the two big important things about Lisps.
(If you understand why the equivalent program would not work reliably in Scheme you'll also understand one of the important things about writing safe programs! Fortunately this is Common Lisp, not Scheme, so it's OK here.)
First of all let's write a little helper function to read integers. This is just fiddly detail: it's not important.
(defun read-integer (&key (prompt "Integer: ")
(stream *query-io*))
;; Read an integer. This is just fiddly details
(format stream "~&~A" prompt)
(values (parse-integer (read-line stream))))
OK, now here's a slightly odd function called mu (which stands for 'mutant U'):
(defun mu (f &rest args)
(apply f f args))
And now here is our program:
(defun read-integers-until-double-last ()
(mu (lambda (c getter current next factor)
(if (= next (* current factor))
(values current next)
(mu c getter next (funcall getter) factor)))
#'read-integer
(read-integer)
(read-integer)
2))
And here it is working:
> (read-integers-until-double-last)
Integer: 0
Integer: 4
Integer: 3
Integer: -2
Integer: -4
-2
-4
For extra mysteriosity you can essentially expand out the calls to mu here, which makes it either more clear or less clear: I'm not quite sure which:
(defun read-integers-until-double-last ()
((lambda (c)
(funcall c c
#'read-integer
(read-integer)
(read-integer)
2))
(lambda (c getter current next factor)
(if (= next (* current factor))
(values current next)
(funcall c c getter next (funcall getter) factor)))))
Again, this is not how you do it in real life, but if you understand what this does and how it does it you will understand quite an important thing about Lisps and their theoretical underpinnings. This is not all (not even most) of the interesting things about them, but it is a thing worth understanding, I think.

Attributes and Instances - Scheme, Racket: unbound identifier in module

I am trying to define a kind of dataset for an exercise I was asked to do. This is the code:
#lang racket
(
(
(pers(sol nub lluv))
(tmp numeric)
(hum numeric)
(vin (yes no))
(class (+ -))
)
;Instances
(sol 30 40 no +)
(lluv 24 70 yes -)
(sol 20 80 no +)
)
The problem is when I run this code I get the following message:
pers: unbound identifier in module in: pers
Do I have to define the identifiers in a different way?
Thanks for your answers!
Well, actually it is a file so there's no need to write "#lang racket". The thing is that I thought I had to run it but it was ok like that according to the exercise.
The next exercise was to read it and the code was the following:
#lang racket
(define (read-file filename)
(define datafile (with-input-from-file filename read))
datafile
)
;Store file info in a variable
(define fileinfo (read-file "filewithinfo.scm"))
So after running that, on console I could write "fileinfo" to display the file information, which was:
>fileinfo
'(((pers (sol nub lluv)) (tmp numeric) (hum numeric) (vin (yes no)) (class (+ -))) (sol 30 40 no +) (lluv 24 70 yes -) (sol 20 80 no +))
More info: https://en.wikibooks.org/wiki/Scheme_Programming/Input_and_Output

Define global from within a function

I need some function which among other stuff would define a new global symbol. So that I could use it like this:
(define (func-prototype symbol value comment)
(define symbol value) ; this should somehow be reformulated
(format "~a=~a !~a\n" symbol value comment))
(define string-list (map func-prototype
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value))))
and be able to get the following results:
> string-list
'("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
> s1
1
> s2
20
> s3
300
Can this be implemented as a function or it is possible to do that only with the help of macros? Could you please suggest any possible implementations or at least give some hints/references that might be helpful?
I'd rethink the general approach, making it simpler. My suggestion: define a global hash table and inside the function add bindings to it, for example:
(define value-map (make-hash))
(define (func-prototype symbol value comment)
(hash-set! value-map symbol value)
(format "~a=~a !~a\n" symbol value comment))
Use it like this:
(define string-list
(map (lambda (lst)
(apply func-prototype lst))
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value"))))
string-list
=> '("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
And wherever you need to refer to one of the symbols in the hash table, do this:
(define (get key)
(hash-ref value-map key))
(get 's1)
=> 1
(get 's2)
=> 20
(get 's3)
=> 300
In general it is not possible to accomplish what you are trying to accomplish in the way you described. Your only hope would be to write stuff out to a file and then load that file into an interactive session. But even then.
In scheme you can't introduce top-level names, such as your desired s1, s2, and s3, except at the top-level. To do so, you could define a macro as:
>(define-syntax define-foo
(syntax-rules ()
((_ name value)
(define name value))))
>(define-foo s1 1)
<undefined>
> s1
1
If you try to use that macro in a function, it is no dice because the body of a function must end with an expression and any definition forms, like what the above macro would expand into, become local variables. That is:
(define (func-prototype name value comment)
(define-foo name value)
name)
>(func-prototype 's1 1 "com")
1
> s1
<error>
One approach that you could take that would work if your string-list is a constant would be as such:
> (define-syntax declare-variables
(syntax-rules ()
((_ (name value comment) ...)
(begin
(define name value)
...))))
> (declare-variables (s1 1 "com") (s2 20 "com") (s3 300 "com"))
> s1
1
This gets it done (I've ignored using 'comment') but, as I said, requires a compile time string-list.
One possibility you might think would work, but wouldn't, would be to use eval as:
(eval '(define s1 1) (environment ...))
but 'eval' only works for expressions, not declarations. Which gets me back to 'load' as a possibility.
First, consider whether you really want to do this, or whether a different solution (like a hash table) would work as well.
You can do this with reflection and dynamic evaluation using the eval procedure.
;; define-variable-with-value! : symbol any -> void
(define (define-variable-with-value! name value)
(eval `(define ,name (quote ,value))))
The quote is important; otherwise you risk reinterpreting a value as an expression to evaluate. To see the difference, consider the example
(define-variable-with-value! 'x (list 'error "kaboom"))

getting standard input and storing it as a string in lisp

I realize this is probably a really stupid question but i have no idea why this isnt working and i pretty much gave up. basically i tried:
(setq answer (string (read)))
and
(setq answer 0)
(format answer "~s" (read))
and
(setq answer (read))
when i try to evaluate
(if (stringp answer)
(princ "works")
(princ "failed"))
on any of the above tries it always comes out failed.
what am i doing wrong?
Or you could just do:
(setq answer (read-line))
That gives you a string right there.
[1]> (setq answer (read))
3
3
[2]> (type-of answer)
(INTEGER 0 16777215)
[3]> (setq answer (read-line))
3
"3"
[4]> (type-of answer)
(SIMPLE-BASE-STRING 1)
[5]>
Start a fresh REPL, then try checking the return value of each of your steps:
T1> (read)
foo
FOO
T1> (read)
1
1
T1> (type-of (read))
foo
SYMBOL
T1> (type-of (read))
1
BIT
Now note, that STRING won't work on all input types:
T1> (string 'foo)
"FOO"
T1> (string 1)
Also note that, unlike setq, (format foo ...) won't set foo, but write to it, if it's a stream or a string with a fill-pointer. Take a look at its Documentation, and you'll see:
format destination control-string
&rest args => result
[...]
destination---nil, t, a stream, or a
string with a fill pointer.
[...]
format is useful for producing nicely
formatted text, producing good-looking
messages, and so on. format can
generate and return a string or output
to destination.
If destination is a string, a stream,
or t, then the result is nil.
Otherwise, the result is a string
containing the `output.'
Try it like this:
T1> (setq *answer*
(with-output-to-string (s)
(format s "~s" (read))))
1
"1"
T1> *answer*
"1"
Or like this:
T1> (setq *answer* (make-array 20 :element-type 'character :fill-pointer 0))
""
T1> (format *answer* "~s" (read))
1
NIL
T1> *answer*
"1"
Those are the only relevant errors I could find in your code. This definitely returns "works" in every conforming CL (you could also use prin1-to-string):
T1> (defvar *answer*)
*ANSWER*
T1> (setq *answer* (format nil "~s" (read)))
1
"1"
T1> (if (stringp *answer*)
(princ "works")
(princ "failed"))
works
"works"
Unless you are in a messed-up package (try (in-package cl-user) before evaluating your code), or redefined basic functionality, this will work. Give some more exact error descriptions, if it still won't.
ED:
Having read Bill's answer, who correctly pointed at read-line as a shorter solution, I should maybe mention that I didn't try to show the best, most succinct, or most idiomatic approaches in my answer, and that those will vary depending on what you are really trying to do. (The shortest possible solution would have been "works" :) They are just examples that should help explaining why your code failed.
Another thing I forgot to say is that you should keep in mind, that toplevel setqs on variables not defined with defvar or defparameter are generally to be avoided in anything but dabbling at the REPL, since the consequences are undefined. Also, those variables are, by convention, wrapped in asterisks (also called earmuffs) in order to prevent bugs caused by confusing specials with lexically scoped variables.

Language history: origin of variable 'it' in read-eval-print loop?

Some interactive systems, including Standard ML of New Jersey and GHC, offer an interactive toplevel loop where you can type expressions and see results. A nice little convenience is that the result of the most recent expression is bound to the variable it. Here's an example from GHCi:
Prelude> 3 + 5
8
Prelude> it
8
Prelude> 2 * it
16
Prelude> it + 1
17
I'm trying to trace the origin of this convention. Can anyone provide examples of other interactive systems that have used similar conventions? And date them if possible?
Ruby provides the same convenience variable as _:
>> 3 + 5
=> 8
>> _
=> 8
>> 2 * _
=> 16
>> _ + 1
=> 17
Interestingly, the global variable $_ is also available: it's the last input read from gets or readline.
Many common lisps use '*' to denote previous results. EG '*' is the last result, '**' is the result before last, etc:
* 5
5
* 6
6
* 7
7
* (+ * ** ***)
18
Python has '_' which is last result:
>>> 5
5
>>> _
5
Erlang has a function 'v()':
1> 5.
5
2> 6.
6
3> 7.
7
4> v(1) + v(2) + v(3).
18
Not a REPL, but hypertalk (the language of hypercard) allowed "it" in some contexts. I'm not sure of the exact usage case, as I never used hypercard, but it appears to be a similar idea. This dates it to 1986 or so.
It seems that the first instance of a REPL with history list functionality was BBN LISP, ca. 1972.
"In BBN-LISP, each input typed by the user, and the value of the corresponding operation, are automatically stored by the p.a. on a global data structure called the history list." I could not find any documentation on how to actually access those values, only on how to repeat previous events using REDO. (See http://www.softwarepreservation.org/projects/LISP/interlisp/Teitelman-FCJJ1972.pdf)
Nor could I find any single keyword for accessing the last history value in its successor Interlisp, possibly due to lack of Google-Fu.

Resources