knowledge-database (beta)

Current group: comp.lang.lisp

Help with this code?

Help with this code?  
Dawgmatix
 Re: Help with this code?  
John Thingstad
 Re: Help with this code?  
Pascal Bourguignon
From:Dawgmatix
Subject:Help with this code?
Date:22 Jan 2005 16:06:42 -0800
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:Sun, 23 Jan 2005 02:17:25 +0100
On 22 Jan 2005 16:06:42 -0800, Dawgmatix 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:23 Jan 2005 07:38:51 +0100
"Dawgmatix" 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) --> #
(function-lambda-expression (funcall h 1)))
--> (LAMBDA (Y) (+ X Y))
(funcall (funcall h 1) 3) --> 4
(funcall g h) --> #
(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 p:

((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/
   

Copyright © 2006 knowledge-database   -   All rights reserved