From: LuB
Subject: the little schemer
Date: 
Message-ID: <1149940935.308784.193870@h76g2000cwa.googlegroups.com>
I am working through The Little Schemer - translating their examples
from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
module).

I am stuck on the following function called 'firsts'. It takes a
non-null list as an argument and returns the first argument of each top
level internal list.

firsts applied to the list ((a b) (c d) (e f)) should return (a c e)

I have compiled the following in Lisp-in-a-Box

CL-USER> (defun firsts (l)
           (cond
             ((null l) '())
             (t (cons (car (car l))(firsts (cdr l))))))

The Little Schemer has the following syntax

(define firsts
   (lambda (l)
      (cond
         ((null? l) quote())
         (else (cons (car (car l))(firsts (cdr l))))))))

Please excuse any mis-spellings or parens.

Now, I'd like to test my implementation. The following all break out to
the debugger in Lisp-in-a-Box implying my syntax is incorrect:

CL-USER> (let ((s '(one two three)) (t '(four five six)))
           (firsts (s t)))
; Evaluation aborted

CL-USER> (let ((s '(one two three)) (x '(four five six)))
           (firsts (s x)))
; Evaluation aborted

CL-USER> (let ((s '(one two three)) (x '(four five six)))
           (firsts (s x)))
; Evaluation aborted

The debugger always complains UNDEFINED S.


So then I tried to be more literal:

CL-USER> (firsts ('(one two three) '(four five six)))

and I get EVAL: '(one two three) is not a function name.

so then I decide to try building from the ground up:

CL-USER> (firsts '(one two))

which EXPECTEDLY complains that '(one two) is not a list. That much I
understand.

so then I try:

(firsts '('(one two)))

which returns (QUOTE). Now, this is a problem .... I want it to return
(one) since I have an outerlist with one internal list. so finally I
try:

(firsts '('(one two) '(three four)))

which returns 'QUOTE. Slightly different response. It doesn't seem to
be encapsulated in a list.

Ok - so at any rate - I'm not sure how to CREATE AN EXAMPLE to test my
function.For many other examples - I was using (let to create variables
and then using them in the function within the (let scope ... but I
seem to be breaking something here. I tried then to supply literal
arguments and I'm not sure if I need to quote the outer list and the
inner lists ... or just the inner lists. It seems that the compiler
finished and executes the code if I quote both. Otherwise, it keeps
looking for a FUNCTION NAME.

Finally, I tried this:

CL-USER> (let ( (a '(one two three)) (b '(four five six)) )
           (firsts '(a b)))

to see if I was using incorrect syntax (quoted the args when passed to
firsts) but it breaks saying A IS NOT A LIST.

I am using Peter Seibels "Practial Common Lisp" as a reference - and
oddly, he doesn't have an example in the (let introduction that assigns
a list to a variable. Could that be part of my problem?

I will try a global variable and setf to see if I can get this example
to work. I can't test my silly (firsts implementation - since I can't
seem to pass in two lists ...

And if (let is having a problem identifying lists wasn't enough, I
really don't understand why my literal lists don't work as args to
(firsts.

Thanks for any input in advance. I tried to be as precise as possible.

-Luther

From: LuB
Subject: Re: the little schemer
Date: 
Message-ID: <1149943088.917773.203500@i40g2000cwc.googlegroups.com>
LuB wrote:
> I am working through The Little Schemer - translating their examples
> from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
> module).
>
> I am stuck on the following function called 'firsts'. It takes a
> non-null list as an argument and returns the first argument of each top
> level internal list.
>
> firsts applied to the list ((a b) (c d) (e f)) should return (a c e)
>
> I have compiled the following in Lisp-in-a-Box
>
> CL-USER> (defun firsts (l)
>            (cond
>              ((null l) '())
>              (t (cons (car (car l))(firsts (cdr l))))))
>
> The Little Schemer has the following syntax
>
> (define firsts
>    (lambda (l)
>       (cond
>          ((null? l) quote())
>          (else (cons (car (car l))(firsts (cdr l))))))))
>
> Please excuse any mis-spellings or parens.
>
> Now, I'd like to test my implementation. The following all break out to
> the debugger in Lisp-in-a-Box implying my syntax is incorrect:
>
> CL-USER> (let ((s '(one two three)) (t '(four five six)))
>            (firsts (s t)))
> ; Evaluation aborted
>
> CL-USER> (let ((s '(one two three)) (x '(four five six)))
>            (firsts (s x)))
> ; Evaluation aborted
>
> CL-USER> (let ((s '(one two three)) (x '(four five six)))
>            (firsts (s x)))
> ; Evaluation aborted
>
> The debugger always complains UNDEFINED S.
>
>
> So then I tried to be more literal:
>
> CL-USER> (firsts ('(one two three) '(four five six)))
>
> and I get EVAL: '(one two three) is not a function name.
>
> so then I decide to try building from the ground up:
>
> CL-USER> (firsts '(one two))
>
> which EXPECTEDLY complains that '(one two) is not a list. That much I
> understand.
>
> so then I try:
>
> (firsts '('(one two)))
>
> which returns (QUOTE). Now, this is a problem .... I want it to return
> (one) since I have an outerlist with one internal list. so finally I
> try:
>
> (firsts '('(one two) '(three four)))
>
> which returns 'QUOTE. Slightly different response. It doesn't seem to
> be encapsulated in a list.
>
> Ok - so at any rate - I'm not sure how to CREATE AN EXAMPLE to test my
> function.For many other examples - I was using (let to create variables
> and then using them in the function within the (let scope ... but I
> seem to be breaking something here. I tried then to supply literal
> arguments and I'm not sure if I need to quote the outer list and the
> inner lists ... or just the inner lists. It seems that the compiler
> finished and executes the code if I quote both. Otherwise, it keeps
> looking for a FUNCTION NAME.
>
> Finally, I tried this:
>
> CL-USER> (let ( (a '(one two three)) (b '(four five six)) )
>            (firsts '(a b)))
>
> to see if I was using incorrect syntax (quoted the args when passed to
> firsts) but it breaks saying A IS NOT A LIST.
>
> I am using Peter Seibels "Practial Common Lisp" as a reference - and
> oddly, he doesn't have an example in the (let introduction that assigns
> a list to a variable. Could that be part of my problem?
>
> I will try a global variable and setf to see if I can get this example
> to work. I can't test my silly (firsts implementation - since I can't
> seem to pass in two lists ...
>
> And if (let is having a problem identifying lists wasn't enough, I
> really don't understand why my literal lists don't work as args to
> (firsts.
>
> Thanks for any input in advance. I tried to be as precise as possible.
>
> -Luther

Ah ... I thought about other languages for a second and realized that
you generally don't assign lists ... often you build them. Some
scripting languages have a neat syntax to do so in one step ... but I
wondered if my problem was in the way I was building the lists to use
as args to firsts.

So I remembered the (list 1 2 3) function (introduced in ch 3 of
Peter's book) and whalah ... the following works as expected.

CL-USER> (firsts (list (list 1 2 3)(list 4 5 6)))
(1 4)

CL-USER> (let ((a (list "a" "b" "c")) (b (list "d" "e" "f")))
           (firsts (list a b)))
("a" "d")


I guess I don't really understand the different between quote(...) and
(list ...) yet.

Why doesn't this approach work the same way as the above?


CL-USER>(quote (a b))
(A B)
CL-USER> (let ((a '(a b)) (b '(c d)))
           (firsts '(a b)))
; Evaluation aborted

A IS NOT A LIST



I see what is happening. What is the rule that reflects the behavior:



CL-USER> (setf a '(a b) b '(c d) c '(e f))
(E F)
CL-USER> (print a)

(A B)
(A B)
CL-USER> (print b)

(C D)
(C D)
CL-USER> (print c)

(E F)
(E F)
CL-USER> (firsts (a b c))
; Evaluation aborted
CL-USER> (firsts '(a b c))
; Evaluation aborted
CL-USER> (let ((a '(a b)) (b '(c d)))
           (firsts '(a b)))
; Evaluation aborted

but

CL-USER> (firsts (list a b c))
(A C E)


It seems to me that I can create lists with the tick character (QUOTE).


CL-USER> (setf a '(a b) b '(c d) c '(e f))


But I CANNOT use the tick character when passing a list to firsts. I
must use the (list function. So --- whats the difference between

creating a list     (a b c) ;; where a b and c are previously defined
S-expressions

the list function (list "a" "b" "c")

and the quote function (quote a b c)


firsts doesn't like quoting ...


Ok - thanks again for any input.


Really enjoying Lisp!
From: Richard M Kreuter
Subject: Re: the little schemer
Date: 
Message-ID: <87odx1aqj0.fsf@progn.net>
"LuB" <···········@yahoo.com> writes:
>
> It seems to me that I can create lists with the tick character (QUOTE).
>
> CL-USER> (setf a '(a b) b '(c d) c '(e f))
>
> But I CANNOT use the tick character when passing a list to firsts. I
> must use the (list function). So --- whats the difference between
>
> creating a list     (a b c) ;; where a b and c are previously defined
> S-expressions
>
> the list function (list "a" "b" "c")
>
> and the quote function (quote a b c)

LIST is a function that accumulates its arguments into a list.

> (list 1 2 3)
(1 2 3)

Evaluation of a function involves evaluation of the function's
arguments.

> (let ((a 1)
        (b 2)
        (c 3))
    (+ a b c))
6
> (let ((a 1)
        (b 2)
        (c 3))
    (list a b c)
(1 2 3)

The quote character in Lisp syntax is a shorthand for the QUOTE
special operator.  Special operators, unlike functions, do not
necessarily evaluate their arguments.  QUOTE does not evaluate its
argument.  

> (quote (a))
(A)
> (quote (a b c))
(A B C)

Therefore,

> '(a)
(A)
> '(a b c)
(A B C)

QUOTE doesn't have anything specifically to do with lists; it can be
used to prevent evaluation of any Lisp object.  

> (quote a)
A
> 'a
A

However, most Lisp objects are self-evaluating, so the following uses
of quote, though valid, are fairly silly:

> (quote 1)
1
> (quote "xyz")
"xyz"
> (quote #(7 8 9))
#(7 8 9)

As the exercise you're trying requires constructing a list of lists,
you'll probably want to do something like this to test your function:

(let ((a (list 'one 'two 'three))
      (b (list 'four 'five 'six)))
  (firsts (list a b)))

In general, I'd suggest avoiding quoted lists entirely until you're
familiar with Lisp.  It may also be counterproductive to try to learn
CL from a book on Scheme, if you don't already know Scheme.

--
RmK
From: Pascal Bourguignon
Subject: Re: the little schemer
Date: 
Message-ID: <87mzcl2k0e.fsf@thalassa.informatimago.com>
"LuB" <···········@yahoo.com> writes:

> Ah ... I thought about other languages for a second and realized that
> you generally don't assign lists ... often you build them. Some
> scripting languages have a neat syntax to do so in one step ... but I
> wondered if my problem was in the way I was building the lists to use
> as args to firsts.
>
> So I remembered the (list 1 2 3) function (introduced in ch 3 of
> Peter's book) and whalah ... the following works as expected.
>
> CL-USER> (firsts (list (list 1 2 3)(list 4 5 6)))
> (1 4)
>
> CL-USER> (let ((a (list "a" "b" "c")) (b (list "d" "e" "f")))
>            (firsts (list a b)))
> ("a" "d")
>
>
> I guess I don't really understand the different between quote(...) and
> (list ...) yet.
>
> Why doesn't this approach work the same way as the above?




> CL-USER>(quote (a b))
> (A B)
> CL-USER> (let ((a '(a b)) (b '(c d)))
>            (firsts '(a b)))
> ; Evaluation aborted
>
> A IS NOT A LIST
>
> I see what is happening. What is the rule that reflects the behavior:

The rule to evaluate a form in Common Lisp is the following:

  (defun %eval (form environment)
    (cond
       ((symbolp form)
         (if (symbol-macro-bound-to-symbol-in-env form environment)
            (%eval (symbol-macro-expansion form environment))
            (value-bound-to-symbol form environment)))
       ((atom    form)  form)
       ;; otherwise form is a cons:
       ((symbolp (first form))
          (cond
             ((special-operator-p (first form))
                (cond ((eq (quote quote) (first form))
                         (second form))
                      ((eq (quote if) (first form))
                         (if (%eval (second form) environment)
                             (%eval (third  form) environment)
                             (%eval (fourth form) environment)))
                       ...))
             ((macro-bound-to-symbol-in-env-p (first form) environment)
                  ...)
             (t
                (apply (function-bound-to-symbol (car form) environment)
                       (mapcar (lambda (arg) (%eval arg environment))
                               (rest form))))))
       ((and (consp (first form))
             (eq (quote lambda) (first (first form))))
          ;; ((lambda ...) ...)
          (apply (%eval (first form) environment)
                 (mapcar (lambda (arg) (%eval arg environment))
                         (rest form))))
       (t (error "Not a function ~A" (first form)))))


There's a significant difference between Scheme and Common Lisp you
should be aware of to translate the examples:

Scheme is a lisp-1, meaning that a symbol can only be bound to a
function or a value at the same time.

Common Lisp is a lisp-2, meaning that a symbol can be bound both to a
function and to a value at the same time.

In Scheme, the evaluation rule is different from the above:
FUNCTION-BOUND-TO-SYMBOL calls are replaced by VALUE-BOUND-TO-SYMBOL calls.


So, in scheme, an expression as: (f x) 
can be interpreted as a function call as soon as f is bound to a function.

In Common Lisp, f must have a function in its function slot for this
to work.  If the value slot of f is bound to a function, you cannot
call this function with (f x), you must write (funcall f x)


When you write (let ((s ...) (t ...))  (firsts (s t)))
there are two errors.

First, you cannot bind T, that is, if T is the symbol T from the
COMMON-LISP package, ie. if your haven't shadowed CL:T, because CL:T
is a constant symbol.

The second error, is that LET binds only value slots of the
variables. S gets a value, but not a function.  So (S T), which is
interpreted as a function call, doesn't find a function bound to S
(function-bound-to-symbol (car form) environment) raises an error.

So, you won't have a _variable_ in the first position of a form in
Common Lisp.  In Scheme, you may have a variable in the first position
of a form, when this variable is bound to a function.




Now, as you may have noticed, as soon as you have a symbol in a
function argument position,  it gets evaluated by the form:
(mapcar (lambda (arg) (%eval arg environment)) (rest form))
and the value of the symbol is returned by:
(value-bound-to-symbol form environment)

So the question is how can you produce a list containing symbols?
If you write: (list a b c)
you'll get a list containing the value of a, the value of b, and the
value of c, or an error, if you haven't bound any value to these
symbols...

To get a symbol, (you could intern a symbols from their names:  
(list (intern "A")  (intern "B")  (intern "C")) but this is 
longuish to write and to read), so what we want is to prevent %eval to
evaluate the symbol, to call value-bound-to-symbol.  This is done
with the QUOTE special operator.  As you can see above, it merely
returns the second form without any evaluation.

(quote a)                            --> a
(quote (a b c))                      --> (a b c)
(list (quote a) (quote b) (quote c)) --> (a b c)

The difference between the last two forms, is that (quote (a b c))
returns the very same cons cell that is in the source of that (quote
(a b c)) form, while LIST, as a function, gets three arguments the A,
B and C symbols that are present inside the (list (quote a) (quote b)
(quote c)) source form, and builds a new list, calling CONS thrice and
return the first of these new CONS cells.


This is handy since the programs are s-exprs, this allows us to have
literal s-exprs that we can easily manipulate



Of course, if what you want is not a list of symbols, but a list of
the values of these symbols, you let the evaluator fetch you these
values, so you just write:  (list a b c), or:

(let ((a '(a b c)) (b '(d e f)))
    (firsts (list a b)))

(firsts '((a b c) (d e f))) ; would do too...




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
From: LuB
Subject: Re: the little schemer
Date: 
Message-ID: <1149949228.527221.243810@m38g2000cwc.googlegroups.com>
Pascal Bourguignon wrote:
> "LuB" <···········@yahoo.com> writes:
>
> > Ah ... I thought about other languages for a second and realized that
> > you generally don't assign lists ... often you build them. Some
> > scripting languages have a neat syntax to do so in one step ... but I
> > wondered if my problem was in the way I was building the lists to use
> > as args to firsts.
> >
> > So I remembered the (list 1 2 3) function (introduced in ch 3 of
> > Peter's book) and whalah ... the following works as expected.
> >
> > CL-USER> (firsts (list (list 1 2 3)(list 4 5 6)))
> > (1 4)
> >
> > CL-USER> (let ((a (list "a" "b" "c")) (b (list "d" "e" "f")))
> >            (firsts (list a b)))
> > ("a" "d")
> >
> >
> > I guess I don't really understand the different between quote(...) and
> > (list ...) yet.
> >
> > Why doesn't this approach work the same way as the above?
>
>
>
>
> > CL-USER>(quote (a b))
> > (A B)
> > CL-USER> (let ((a '(a b)) (b '(c d)))
> >            (firsts '(a b)))
> > ; Evaluation aborted
> >
> > A IS NOT A LIST
> >
> > I see what is happening. What is the rule that reflects the behavior:
>
> The rule to evaluate a form in Common Lisp is the following:
>
>   (defun %eval (form environment)
>     (cond
>        ((symbolp form)
>          (if (symbol-macro-bound-to-symbol-in-env form environment)
>             (%eval (symbol-macro-expansion form environment))
>             (value-bound-to-symbol form environment)))
>        ((atom    form)  form)
>        ;; otherwise form is a cons:
>        ((symbolp (first form))
>           (cond
>              ((special-operator-p (first form))
>                 (cond ((eq (quote quote) (first form))
>                          (second form))
>                       ((eq (quote if) (first form))
>                          (if (%eval (second form) environment)
>                              (%eval (third  form) environment)
>                              (%eval (fourth form) environment)))
>                        ...))
>              ((macro-bound-to-symbol-in-env-p (first form) environment)
>                   ...)
>              (t
>                 (apply (function-bound-to-symbol (car form) environment)
>                        (mapcar (lambda (arg) (%eval arg environment))
>                                (rest form))))))
>        ((and (consp (first form))
>              (eq (quote lambda) (first (first form))))
>           ;; ((lambda ...) ...)
>           (apply (%eval (first form) environment)
>                  (mapcar (lambda (arg) (%eval arg environment))
>                          (rest form))))
>        (t (error "Not a function ~A" (first form)))))
>
>
> There's a significant difference between Scheme and Common Lisp you
> should be aware of to translate the examples:
>
> Scheme is a lisp-1, meaning that a symbol can only be bound to a
> function or a value at the same time.
>
> Common Lisp is a lisp-2, meaning that a symbol can be bound both to a
> function and to a value at the same time.

Ah --- very nice. Thank you.

>
> In Scheme, the evaluation rule is different from the above:
> FUNCTION-BOUND-TO-SYMBOL calls are replaced by VALUE-BOUND-TO-SYMBOL calls.
>
>
> So, in scheme, an expression as: (f x)
> can be interpreted as a function call as soon as f is bound to a function.
>
> In Common Lisp, f must have a function in its function slot for this
> to work.  If the value slot of f is bound to a function, you cannot
> call this function with (f x), you must write (funcall f x)
>
>
> When you write (let ((s ...) (t ...))  (firsts (s t)))
> there are two errors.
>
> First, you cannot bind T, that is, if T is the symbol T from the
> COMMON-LISP package, ie. if your haven't shadowed CL:T, because CL:T
> is a constant symbol.


Ah yes ... stupid error. I saw that after the post. Thanks for pointing
it out. I do indeed understand the name clash there.


> The second error, is that LET binds only value slots of the
> variables. S gets a value, but not a function.  So (S T), which is
> interpreted as a function call, doesn't find a function bound to S
> (function-bound-to-symbol (car form) environment) raises an error.
>
> So, you won't have a _variable_ in the first position of a form in
> Common Lisp.  In Scheme, you may have a variable in the first position
> of a form, when this variable is bound to a function.

Ah ... I'd not yet drawn that conclusion. That makes very good sense -
and will be helpful as I work through the "scheme" book with my Lisp in
a box implementation.

>
> Now, as you may have noticed, as soon as you have a symbol in a
> function argument position,  it gets evaluated by the form:
> (mapcar (lambda (arg) (%eval arg environment)) (rest form))
> and the value of the symbol is returned by:
> (value-bound-to-symbol form environment)
>
> So the question is how can you produce a list containing symbols?
> If you write: (list a b c)
> you'll get a list containing the value of a, the value of b, and the
> value of c, or an error, if you haven't bound any value to these
> symbols...
>
> To get a symbol, (you could intern a symbols from their names:
> (list (intern "A")  (intern "B")  (intern "C")) but this is
> longuish to write and to read), so what we want is to prevent %eval to
> evaluate the symbol, to call value-bound-to-symbol.  This is done
> with the QUOTE special operator.  As you can see above, it merely
> returns the second form without any evaluation.
>
> (quote a)                            --> a
> (quote (a b c))                      --> (a b c)
> (list (quote a) (quote b) (quote c)) --> (a b c)
>
> The difference between the last two forms, is that (quote (a b c))
> returns the very same cons cell that is in the source of that (quote
> (a b c)) form, while LIST, as a function, gets three arguments the A,
> B and C symbols that are present inside the (list (quote a) (quote b)
> (quote c)) source form, and builds a new list, calling CONS thrice and
> return the first of these new CONS cells.
>
>
> This is handy since the programs are s-exprs, this allows us to have
> literal s-exprs that we can easily manipulate
>
>
>
> Of course, if what you want is not a list of symbols, but a list of
> the values of these symbols, you let the evaluator fetch you these
> values, so you just write:  (list a b c), or:
>
> (let ((a '(a b c)) (b '(d e f)))
>     (firsts (list a b)))
>
> (firsts '((a b c) (d e f))) ; would do too...
>

Thank you very much Pascal!

All very well put. Thanks for the clarity.

-Luther
From: Ben
Subject: Re: the little schemer
Date: 
Message-ID: <1149957893.870592.146800@i40g2000cwc.googlegroups.com>
try:

(let ((a '(one two three))
      (b '(four five six)))
      (firsts (list a b)))

or

(firsts '((one two three) (four five six)))

I think when you use:

(firsts (a b))

the evaluator thinks a is a function, there are other ways to fix this,
but this should get you going.
From: Ben
Subject: Re: the little schemer
Date: 
Message-ID: <1149959263.393717.52320@g10g2000cwb.googlegroups.com>
I was looking at your firsts function and worked out a different
approach:

(defun firsts (l)
  (if (null l)
      nil
      (if (consp l)
	  (if (consp (car l))
	      (cons (car (car l)) (firsts (cdr l)))
	      nil)
	  nil)))

this is a little longer but:

CL-USER> (firsts '(one two three))
NIL

CL-USER> (firsts '((one two) three))
(ONE)

which is a little clearer result than throwing you out to the debugger.
From: Paolo Amoroso
Subject: Re: the little schemer
Date: 
Message-ID: <8764j92omb.fsf@plato.moon.paoloamoroso.it>
"LuB" <···········@yahoo.com> writes:

> I am working through The Little Schemer - translating their examples
> from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
> module).
>
> I am stuck on the following function called 'firsts'. It takes a
> non-null list as an argument and returns the first argument of each top
> level internal list.
>
> firsts applied to the list ((a b) (c d) (e f)) should return (a c e)

(defun firsts (list)
  (mapcar #'first list))


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net
From: R. Mattes
Subject: Re: the little schemer
Date: 
Message-ID: <pan.2006.06.11.13.58.33.666020@mh-freiburg.de>
On Sat, 10 Jun 2006 14:15:24 +0200, Paolo Amoroso wrote:

> "LuB" <···········@yahoo.com> writes:
> 
>> I am working through The Little Schemer - translating their examples
>> from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
>> module).
>>
>> I am stuck on the following function called 'firsts'. It takes a
>> non-null list as an argument and returns the first argument of each top
>> level internal list.
>>
>> firsts applied to the list ((a b) (c d) (e f)) should return (a c e)
> 
> (defun firsts (list)
>   (mapcar #'first list))
> 

 This of course only works if _all_ elements of list are cons which
is not guaranteed by the original request.

 Cheers RalfD

> Paolo
From: Pascal Costanza
Subject: Re: the little schemer
Date: 
Message-ID: <4evve8F1fc1sgU1@individual.net>
LuB wrote:
> I am working through The Little Schemer - translating their examples
> from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
> module).
> 
> I am stuck on the following function called 'firsts'. It takes a
> non-null list as an argument and returns the first argument of each top
> level internal list.
> 
> firsts applied to the list ((a b) (c d) (e f)) should return (a c e)
> 
> I have compiled the following in Lisp-in-a-Box
> 
> CL-USER> (defun firsts (l)
>            (cond
>              ((null l) '())
>              (t (cons (car (car l))(firsts (cdr l))))))
> 
> The Little Schemer has the following syntax
> 
> (define firsts
>    (lambda (l)
>       (cond
>          ((null? l) quote())
>          (else (cons (car (car l))(firsts (cdr l))))))))
> 
> Please excuse any mis-spellings or parens.
> 
> Now, I'd like to test my implementation. The following all break out to
> the debugger in Lisp-in-a-Box implying my syntax is incorrect:
> 
> CL-USER> (let ((s '(one two three)) (t '(four five six)))
>            (firsts (s t)))
> ; Evaluation aborted

This cannot possibly work, but before explaining this, it's better to 
know what your current mental model is: What do you think (s t) is 
supposed to give you? What result do you expect from the call to (firsts 
(s t))?


Pascal

-- 
3rd European Lisp Workshop
July 3 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
From: LuB
Subject: Re: the little schemer
Date: 
Message-ID: <1149950181.172379.322560@m38g2000cwc.googlegroups.com>
Pascal Costanza wrote:
> LuB wrote:
> > I am working through The Little Schemer - translating their examples
> > from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
> > module).
> >
> > I am stuck on the following function called 'firsts'. It takes a
> > non-null list as an argument and returns the first argument of each top
> > level internal list.
> >
> > firsts applied to the list ((a b) (c d) (e f)) should return (a c e)
> >
> > I have compiled the following in Lisp-in-a-Box
> >
> > CL-USER> (defun firsts (l)
> >            (cond
> >              ((null l) '())
> >              (t (cons (car (car l))(firsts (cdr l))))))
> >
> > The Little Schemer has the following syntax
> >
> > (define firsts
> >    (lambda (l)
> >       (cond
> >          ((null? l) quote())
> >          (else (cons (car (car l))(firsts (cdr l))))))))
> >
> > Please excuse any mis-spellings or parens.
> >
> > Now, I'd like to test my implementation. The following all break out to
> > the debugger in Lisp-in-a-Box implying my syntax is incorrect:
> >
> > CL-USER> (let ((s '(one two three)) (t '(four five six)))
> >            (firsts (s t)))
> > ; Evaluation aborted
>
> This cannot possibly work, but before explaining this, it's better to
> know what your current mental model is: What do you think (s t) is
> supposed to give you? What result do you expect from the call to (firsts
> (s t))?

Hi Pascal,

My goal was to create a list of lists

(("one" "two" "three")("four" "five" "six"))

I wanted to pass this list of lists to my function firsts.

The result would be ("one" "four").

So - I know I made a few mistakes. (s t) uses a reserved word ... so
the t is never going to work. Another point that Pascal pointed out in
a different post is that in Common Lisp, the first expression is
assumed to be a function -- and that is not the case here. I knew that
implicitly - since I'm writing functions ... but I didn't explicitly
make a note ... so completely disregarded the principle when creating a
list. That is why it is complaining that S is not a function. Common
Lisp is looking for a function ... but I was thinking ... "oh, I need
to pass a list in here ... that means I just need to put parens around
two existing arguments" so I confused the compiler.

Obviously I am just beginning with Lisp .... and its a bit odd since
I'm walking through "The Little Schemer" which is based on the Scheme
dialect ... so still getting a grasp on the formatting and syntax. I
appreciate the approach the book takes so I'd like to push through it
... and learn about the subtle distinctions between Common Lisp and
Scheme along the way. I don't think the book will push the language to
its extreme - its mostly about style, problem solving and recursive
programming.

So conceptually - I wanted to pass a list of lists to a function ...
and return a list of the first elements of each of the nested lists.

Thanks for the input,

-Luther
From: Pascal Costanza
Subject: Re: the little schemer
Date: 
Message-ID: <4f2e09F1h36uoU1@individual.net>
LuB wrote:
> Pascal Costanza wrote:
>> LuB wrote:
>>> I am working through The Little Schemer - translating their examples
>>> from the scheme dialect to Common Lisp (Lisp In A Box with the CLisp
>>> module).
>>>
>>> I am stuck on the following function called 'firsts'. It takes a
>>> non-null list as an argument and returns the first argument of each top
>>> level internal list.
>>>
>>> firsts applied to the list ((a b) (c d) (e f)) should return (a c e)
>>>
>>> I have compiled the following in Lisp-in-a-Box
>>>
>>> CL-USER> (defun firsts (l)
>>>            (cond
>>>              ((null l) '())
>>>              (t (cons (car (car l))(firsts (cdr l))))))
>>>
>>> The Little Schemer has the following syntax
>>>
>>> (define firsts
>>>    (lambda (l)
>>>       (cond
>>>          ((null? l) quote())
>>>          (else (cons (car (car l))(firsts (cdr l))))))))
>>>
>>> Please excuse any mis-spellings or parens.
>>>
>>> Now, I'd like to test my implementation. The following all break out to
>>> the debugger in Lisp-in-a-Box implying my syntax is incorrect:
>>>
>>> CL-USER> (let ((s '(one two three)) (t '(four five six)))
>>>            (firsts (s t)))
>>> ; Evaluation aborted
>> This cannot possibly work, but before explaining this, it's better to
>> know what your current mental model is: What do you think (s t) is
>> supposed to give you? What result do you expect from the call to (firsts
>> (s t))?
> 
> Hi Pascal,
> 
> My goal was to create a list of lists
> 
> (("one" "two" "three")("four" "five" "six"))
> 
> I wanted to pass this list of lists to my function firsts.
> 
> The result would be ("one" "four").
> 
[...]

> So conceptually - I wanted to pass a list of lists to a function ...
> and return a list of the first elements of each of the nested lists.

You've already learned a lot.

If you want to create a list programmatically, use LIST:

(let ((x '(one two three)) (y '(four five six)))
   (firsts (list x y)))

...or in this case also:

(firsts '((one two three) (four five six)))


It's important to note that the following two expressions have a 
different meaning:

(list 'x 'y 'z)
'(x y z)

The ' is an abbreviation for QUOTE. So the expressions are actually:

(list (quote x) (quote y) (quote z))
(quote (x y z))

Although both expressions give you the same (or better: similar) 
results, the important difference is that with LIST, the list is 
guaranteed to be created at runtime, while with QUOTE, the list is 
created at compile time. In (quote (x y z)), the list consisting of (x y 
z) is a value at compile time, and QUOTE makes sure that it is not 
evaluated at runtime.

This difference, even if you don't understand it completely right now, 
will become important sooner or later. Especially, it's not a good idea 
to perform side effects on lists built via QUOTE. Your function doesn't 
perform side effects, so it's fine to pass it lists built via QUOTE. 
When in doubt, use LIST.


Pascal

-- 
3rd European Lisp Workshop
July 3 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
From: Pascal Bourguignon
Subject: Re: the little schemer
Date: 
Message-ID: <877j3n3ci2.fsf@thalassa.informatimago.com>
Pascal Costanza <··@p-cos.net> writes:
> It's important to note that the following two expressions have a
> different meaning:
>
> (list 'x 'y 'z)
> '(x y z)
>
> The ' is an abbreviation for QUOTE. So the expressions are actually:
>
> (list (quote x) (quote y) (quote z))
> (quote (x y z))
>
> Although both expressions give you the same (or better: similar)
> results, the important difference is that with LIST, the list is
> guaranteed to be created at runtime, while with QUOTE, the list is
> created at compile time. In (quote (x y z)), the list consisting of (x
> y z) is a value at compile time, and QUOTE makes sure that it is not
> evaluated at runtime.

Perhaps some language lawyer could bring in some references, but I
think that the list obtained by evaluating (quote (x y z)) would be
created either at read-time or at load-time.  I doubt the compilers
would take the pain to _copy_ it.

For example, at the REPL (both clisp and sbcl):

[20]> (progn (defparameter *l* #1=(quote (a b c))) (defun f () #1#))
F
[21]> (eq (f) *l*)
T
[22]> (compile 'f)
F ;
NIL ;
NIL
[23]> (eq (f) *l*)
T
[24]> 


(With compile-file/load, the situation is murkier, but at least with
clisp, it's still the lisp reader which creates the quoted literals
read from the .fas files).


> This difference, even if you don't understand it completely right now,
> will become important sooner or later. Especially, it's not a good
> idea to perform side effects on lists built via QUOTE. Your function
> doesn't perform side effects, so it's fine to pass it lists built via
> QUOTE. When in doubt, use LIST.
>
>
> Pascal
>
> -- 
> 3rd European Lisp Workshop
> July 3 - Nantes, France - co-located with ECOOP 2006
> http://lisp-ecoop06.bknr.net/

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.