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.
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/
"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/