Another newbie question

Started by frontera000, October 10, 2006, 09:27:02 AM

Previous topic - Next topic

frontera000

> (setq x '(1 '(2 3 4)))

(1 '(2 3 4))

> x

(1 '(2 3 4))

> (x 0)

1

> (x 1)

'(2 3 4)

> (first (x 1))



array, list or string expected in function first : (x 1)

> (first '(2 3 4))

2

>



Somehow quoted list works differently.

cormullion

#1
A bit confusing this one, and I don't claim to understand it. I _think_ that newLISP is trying to evaluate (2 3 4) as a function call before it can pass the value to first. So finding that 2 is not a function, it complains. When you pass '(2 3 4) directly to first, though, it doesn't try to evaluate the list, because it's quoted...



Perhaps. But what do i know ‽ * ... :-)









* I've joined m i c h a e l 's campaign to reintroduce the interrobang.

Fanda

#2
This goes into internal behaviour of newLISP. I tried to write the expression different way:


> (setq x '(1 '(2 3 4)))
(1 '(2 3 4))
> (x 1)
'(2 3 4)
> (first (x 1))
array, list or string expected in function first : (x 1)

> (setq z (quote (1 (quote (2 3 4)))))
(1 (quote (2 3 4)))
> (z 1)
(quote (2 3 4))
> (first (z 1))
quote

> (quote? (x 1))
true
> (quote? (z 1))
nil

> (first ''(2 3 4))
array, list or string expected in function first : ''(2 3 4)


It looks that quoted list '(1 2 3):

> ''(1 2 3)

'(1 2 3)

is a special kind of data type - not array, list, or string. To me it's like a lambda-list, but it's a quoted-list.



That's my theory :-)



Fanda

frontera000

#3
I kind of understand (and *prefer* ) the way newLISP does this.



But I guess I am thinking of other LISPs (oh no!!)



Scheme:



#;3> (define i '(1 '(2 3 4)))
#;4> i
(1 (quote (2 3 4)))

#;5> (car i)
1
#;6> (cdr i)
((quote (2 3 4)))
#;7> (cadr i)
(quote (2 3 4))
#;8> (caadr i)
quote
#;9> (car '(2 3 4))
2





Common LISP :



[2]> (setq x '(1 '(2 3 4)))
(1 '(2 3 4))
[3]> x
(1 '(2 3 4))
[4]> (second x)
'(2 3 4)
[5]> (car (second x))
QUOTE
[6]> (car '(2 3 4))
2


Lutz

#4
Except when trying to evaluate:


(1 '(a b c)) => (b c)
; or
('(a b c) 1) => b


which is implicit indexing, newLISP list quoting, evaluation and first, last etc. work exactly like in other LISPs and Schemes.



For example in R5RS Scheme:
> (define x '(a b '(c d)))
> (cdr x)
(b '(c d))
> (cdr (cdr x))
('(c d))
> (car (cdr (cdr x)))
'(c d)
>


if you replace car with first and cdr with rest, you will get exactly the same in newLISP or an interactive Common LISP. In all 3 forms of LISPs the quote protects from evaluation.



Lutz

frontera000

#5
In newLISP:



> (setq x '(1 '(2 3 4)))
(1 '(2 3 4))
> (first (first (rest x)))

array, list or string expected : (first (rest x))


In scheme:



#;1> (define x '(1 '(2 3 4)))
#;2> (car (car (cdr x)))
quote




In Common LISP:

[1]> (setq x '(1 '(2 3 4)))
(1 '(2 3 4))
[2]> (car (car (cdr x)))
QUOTE

Lutz

#6
Ok, thanks, now I understand Fanda's post. Yes, the quote ' is its own data type quote-type (sub-type of list) in newLISP similar to lambda-type sub-type of list. The ' and (quote x) are equivalent when evaluated:


(= 'x (quote x)) => true

; and

(quote? (quote 'x)) => true

; but here the expresssion (quote x) is unevaluated

(quote? '(quote x)) => nil

; and

(list? '(quote x)) => true


Just like lambda the ' is resolved during code translation/source parsing. This is why we have the quote? and lambda? type predicates.



Most of the time the difference is not recognizable (as in my example) but in Frontera's and Fanda's example this difference shows. Both the ' and the function quote server the same purpose of protecting an expession from evaluation, but the ' is much faster processed becuase it is translated during source load time. You still need the quote function to quote duwing runtime.



For that reason when you want to rewrite McCarthy's original definition of LISP in newLISP you would have to use the function (quote ...) instead of ' and:


(first (first (rest (quote (1 (quote 2 3 4)))))) => quote

you get the same result in Scheme as in Common LISP.



Lutz