From: Dawgmatix
Subject: Help with this code?
Date: 
Message-ID: <1106438802.196430.259580@c13g2000cwb.googlegroups.com>
Am working through PAIP by Senor Norvig.


1) Could anyone explain this code please

(defun generate-all (phrase)
"Generate a list of all possible expansions of this phrase."
(cond ((null phrase) (list nil))
((listp phrase)
(combine-all (generate-all (first phrase))
(generate-all (rest phrase))))
((rewrites phrase)
(mappend #'generate-all (rewrites phrase)))
(t (list (list phrase)))))

(defun combine-all (xlist ylist)
"Return a list of lists formed by appending a y to an x.
E.g., (combine-all '((a) (b)) '((1) (2)))
-> ((A 1) (B 1) (A 2) (B 2))."
(mappend #'(lambda (y)
(mapcar #'(lambda (x) (append x y)) xlist))
ylist))

2) Second , could someone tell me in general what happens
in tha case of a form
(lambda1 (......( lambda2.........)))
Ie a lambda placed within a lambda

Thanks.

From: John Thingstad
Subject: Re: Help with this code?
Date: 
Message-ID: <opsk067blvpqzri1@mjolner.upc.no>
On 22 Jan 2005 16:06:42 -0800, Dawgmatix <·········@gmail.com> wrote:

> Am working through PAIP by Senor Norvig.
>
>
> 1) Could anyone explain this code please
>

I'll give it a shot. First we indent the code correctly.

(defun generate-all (phrase)
  "Generate a list of all possible expansions of this phrase."
  (cond ((null phrase) (list nil))
        ((listp phrase)
         (combine-all (generate-all (first phrase))
                      (generate-all (rest phrase))))
        ((rewrites phrase)
         (mappend #'generate-all (rewrites phrase)))
        (t (list (list phrase)))))
This is a conditional.
In the first case phrase is null and we return a empty lisp '()

In the second case we are traversing the list depth first.
Say we has (This (is (just)) a silly (sentence))

In a tree form this would look as:

    [This [->]       a silly   [->]
	     [is [->]            [sentence]
	          [just]
It starts by traversing the first element and continues to go further down
in the first recusitivly until it encounters something that is not a list.
Then it moves on to the next element (the (generate-all (rest phrase))
So we get "This is just a silly list" as the traversal iorder.

Nor sure exactly what rewites does but it's a fair bet it rewrites the  
sentence.
The last option (t) is chosen is the element is a atom in which case
it returns ((atom))

(defun combine-all (xlist ylist)
  "Return a list of lists formed by appending a y to an x.
E.g., (combine-all '((a) (b)) '((1) (2)))
-> ((A 1) (B 1) (A 2) (B 2))."
  (mappend #'(lambda (y)
               (mapcar #'(lambda (x) (append x y)) xlist))
           ylist))

Not entirely sure what mappens does as it is not included.
mapcar applies the given lambda function to all the elements in the list.
in this case it takes the y from the outer list and combines it the  
elements
xlist in turn.

>
> 2) Second , could someone tell me in general what happens
> in tha case of a form
> (lambda1 (......( lambda2.........)))
> Ie a lambda placed within a lambda
>
> Thanks.
>

Not sure what you mean.
lambda is just a anonymous function.
Nothing spetacular happens.
It totally depends on what's in the ...

It's like asking what happens when you call a function within a function.


-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Pascal Bourguignon
Subject: Re: Help with this code?
Date: 
Message-ID: <87pszwodj8.fsf@thalassa.informatimago.com>
"Dawgmatix" <·········@gmail.com> writes:
> 2) Second , could someone tell me in general what happens
> in tha case of a form
> (lambda1 (......( lambda2.........)))
> Ie a lambda placed within a lambda

It depends on how the second lambda is used.

    (lambda (...) ...)

returns an anonymous function.

eg.
    (lambda (x) (+ (sin x) (cos x)))

    (lambda (x) (* x x))

    (lambda (f) (funcall f (/ pi 4)))

What you can do with function _values_, is to _call_ them:

    (defparameter f1 (lambda (x) (* x x)))
    (let ((f2 (lambda (x) (+ (sin x) (cos x)))))
        (funcall f1 (funcall f2 (/ pi 3))))

        --> 1.8660254037844386466L0 
            about: (sin(pi/3)+cos(pi/3))^2


This one is a function that takes a function as argument:

    (lambda (f) (funcall f (/ pi 4)))

You could use it like this:

    (defparameter g (lambda (f) (funcall f (/ pi 4))))

    (funcall g (function sin)) --> 0.70710678118654752444L0
                                   about: sin(pi/4)
    (funcall g (function cos)) --> 0.70710678118654752444L0
                                   about: cos(pi/4)

Of course instead of an existing named function you could pass it an
anonymous function:

    (funcall g (lambda (x) (* x x))) --> 0.6168502750680849137L0
                                         about: (pi/4)^2

Also, an anonymous function can return a function:
    
    (lambda (x) (lambda (y) (+ x y)))

is an anonymous function that returns a function that increment its
argument by the value of the argument to the first function.

    (defparameter h (lambda (x) (lambda (y) (+ x y))))
     
    (funcall h 1)             --> #<CLOSURE :LAMBDA (Y) (+ X Y)>
    (function-lambda-expression (funcall h 1)))
                              --> (LAMBDA (Y) (+ X Y)) 
    (funcall (funcall h 1) 3) --> 4
    (funcall g h)             --> #<CLOSURE :LAMBDA (Y) (+ X Y)>
    (function-lambda-expression (funcall g h))
                              --> (LAMBDA (Y) (+ X Y))
    (funcall (funcall g h) 1) --> 1.7853981633974483096L0
                                  (about 1+pi/4)


Note that sometimes, lambda is only lambda:

    (funcall (lambda (x) `(lambda (y) (* y ,x))) 3) --> (LAMBDA (Y) (* Y 3))

which is not a function, but a mere list whose first symbol is LAMBDA.
Such a list whose first symbol is LAMBDA, can be used as a function
literal, a function designator in the first place of a sexp:

    ((lambda (x) `(lambda (y) (* y ,x))) 3) --> (LAMBDA (Y) (* Y 3))

    ((lambda (x) (* x (1+ x)))  2) --> 6

An anonymous function can call an anonymous function:

    (lambda (x) ((lambda (y) (* y y)) (1+ (/ x 2))))

is the function x |--> (1+x/2)^2 :

    (funcall (lambda (x) ((lambda (y) (* y y)) (1+ (/ x 2)))) 2) --> 4
    ((lambda (x) ((lambda (y) (* y y)) (1+ (/ x 2)))) 2)         --> 4
    ((lambda (x) ((lambda (y) (* y y)) (1+ (/ x 2)))) 3)         --> 25/4


In conclusion, anything can happen when several imbricated s-exp
contains the symbol lambda, you have to analyse the meaning of the
s-exps.

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