Page 1 of 2

REPL problems in Lisp

Posted: Tue Dec 30, 2008 7:01 pm
by aloyslisp
Hello folks,

As I just begin a nTh CL version in Java, I just crash on some problems.
It's not in the language implementation itself (witch is mainly easy), but in some details that you can grab in current implementations. X3J13 doesn't give advice about. Examples are tested on CLisp.

Though... REPL in lisp can be made in a simple and classical way as :

Code: Select all

(loop(write(eval(read))))
Trying '(a b) as input it works -> (a b).

Why ? as :

Code: Select all

(read) -> '(a b) -> (quote (a b))
(eval (quote(a b))) -> (a b)
(write (a b)) -> a is not a function
If I try a close equivalent (?)

Code: Select all

(write(eval '(a b)))
the result is an error.

A hint is perhaps :

"20.1. Run-Time Evaluation of Forms"
If the predicate constantp is true of an object, then that object, when considered as a form to be evaluated, always evaluates to the same thing; it is a constant. This includes self-evaluating objects such as numbers, characters, strings, bit-vectors, and keywords, as well as all constant symbols declared by defconstant, such as nil, t, and pi. In addition, a list whose car is quote, such as (quote foo), is considered to be a constant.

I probably loose something somewhere.

Best regards

Ivan

Re: REPL problems in Lisp

Posted: Tue Dec 30, 2008 9:00 pm
by Paul Donnelly
The paragraph you quote is about mutability of data when read. The problem is exactly what it says. A is not a function. Anything you plan to EVAL needs to be valid Lisp code. When you READ (A B), (A B) is the return value. You can't evaluate this code unless A is a defined function and B is a defined variable. When you READ '(A B), (QUOTE (A B)) is the return value. Since QUOTE is defined, you can run this code.

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 2:54 am
by aloyslisp
Paul Donnelly wrote:The paragraph you quote is about mutability of data when read. The problem is exactly what it says. A is not a function. Anything you plan to EVAL needs to be valid Lisp code. When you READ (A B), (A B) is the return value. You can't evaluate this code unless A is a defined function and B is a defined variable. When you READ '(A B), (QUOTE (A B)) is the return value. Since QUOTE is defined, you can run this code.
You're completely right in your response, but...

In my (read) answer I send '(a b). So it's like putting '(a b) instead of (read). That's not the error answer that astonished me but the (write(eval(read))) answer with '(a b) giving (a b), witch is for REPL correct, but... seems incorrect doing it by hand. :? ,

That's not a BIG problem, just an implementation feature, that I try to figure out.

For example If implementation was made of intermediate storage :

Code: Select all

(setq r (read)) -> '(a b)
(setq e (eval '(a b))) -> (a b)
(write e) -> (a b)
and that's normal, as last write evaluation is on the symbol e, though it's value. But direct call, doesn't use intermediate symbolic uninterned values.

I'm quite confused.

Thanks a lot

Ivan

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 3:44 am
by aloyslisp
Ok, I looked about :oops:

(eval (read)) evaluates (read) and not '(a b)

though (eval '(a b)) -> a not a function.

But in the same way....

(read) -> '(a b)
(eval (read)) ->
[*]args evaluation : (eval '(a b))
[*]eval exec : (a b)

When we apply write
(write (a b))
args evaluation : a not a function -> stop

except if '(a b) is somewhere in the evaluation process considered as a constant... I'll try with a functional modif. It could explains it. But it'd meens that eval of CONSes and of arguments would be different. I just figure out and make some back-engeenering.

Thanks

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 4:45 am
by ramarren
aloyslisp wrote: (eval (read)) evaluates (read) and not '(a b)
Unless you are using some eval I am not familiar with, then this is wrong. EVAL is a function, so first its argument is evaluated (if this is circular evaluator, then it might be by the same EVAL function), resulting in '(a b), which is the shorthand for (QUOTE (a b)), which when evaluted gives a constant list containing two symbols, (a b). But this was explained by Paul.

I think your problem is because you attempt to perform textual substitution disregarding literal syntax. There might be little syntax in Common Lisp, but there is some, and you can't just plug printed representation back in the source and expect it to work. You can't just give WRITE "(a b)", because this is not how the literal list object is represented in the source, just like you can't give "#<SOME-CLASS #x20442DDE>" to a function expecting object of class SOME-CLASS.

Some objects, like keywords, numbers, and arrays, are self-evaluating, so their printed representation can be used directly in evaluated position in the source, but lists can't, because they are the most basic block of Lisp program, and so it was decided that special syntax, (QUOTE ...), and its shortened form '... was for literal lists, rather than program parts.

So when you want to simulate REPL by substituting expressions by hand you must use literal syntax to represent real objects. In your case:

Code: Select all

(read) -> '(a b) == (quote (a b)) must be represented in the source as: (quote (quote (a b)) == ''(a b)
(eval ''(a b)) -> (a b) must be represented in the source as: (quote (a b)) == '(a b)
(write '(a b)) -> (a b), which is printed
Hope this helps and I am not horribly wrong.

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 12:14 pm
by aloyslisp
Thanks a lot,

I completely agree with your view. But it was not clear in the standards, as implementation is not (as is it's normal) not defined.

And exactly as you wrote the '' (quote(quote...)) syntax works without problem (just a macro-function).

My problem is :
[*](read) with an input of '(a b ) gives '(a b).
[*]In (eval) result is (a b). That's OK.
[*]Write as function evalute arguments (in this case object) so error. Normal. but why in Clisp (write(eval(read))) works ? :shock: Read is not a special form.

Notthing about in the standard, my hairs will be shortly cut... ;)

All good four you

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 12:51 pm
by ramarren
I say again: by separating the (write (eval (read))) expression by hand you are injecting additional evaluation. (read-from-string "'(a b)") will result in an object whose printable/readable syntax is '(A B), but you cannot just write (eval '(a b)) and expect it to work, because it will be evaluated twice, first by normal evaluator, since EVAL is a function, and then by (eval).

By doing (eval (read)) the first evaluation is that of (read) by system evaluator, and the second of (eval). To get the same result you have to stop the first evaluation with additional quote if you perform it by hand, by substituting "'(a b)" in place of (read). Remember, you are typing all your code into a preexisting REPL, so everything you type is inside another layer of (write (eval (read))). Well, not exactly, but close enough.

So when you type (eval '(a b)) what actually happens is (eval (read "(eval '(a b)))). And if you pass this to (write ...) then there will be one eval too many, dropping reads for clarity, : (write (eval (eval '(a b)))), where it should be (write (eval '(a b))). You have to counteract this with additional quotes to balance: (write (eval (eval ''(a b)))).

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 3:39 pm
by aloyslisp
Yea !

That was exactly what I thought about. But I wonder if I was mistaking the process.

I just explain.

First attempt was the REPL standard.

Afterwared was suppressing the eval as object is evaluated by the (write), as you say overquoting the read.

As you say it's right that the (read) is evaluated by eval. I think I've some to process about. Have you got some links over this particular problem ?

A good happy new year for all of you.

Ivan

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 4:05 pm
by ramarren
I think SICP (http://mitpress.mit.edu/sicp/full-text/book/book.html) goes a bit into evaluation and quoting... see for example chapter 4.1 The Metacircular Evaluator. Note that SICP uses a variant of Scheme, but concepts are similar.

Happy new year.

Re: REPL problems in Lisp

Posted: Wed Dec 31, 2008 7:54 pm
by aloyslisp
Thanks a lot,

Not exactly a response, but good flow of ideas to snuff around... A lot of reading and thinking.

I'll give here some news when concepts will be clearer for me. Details puzzle me. :D. But I'll catch it... ;-)

Happy new year, and good programming for all of yours.

Ivan