knowledge-database (beta)

Current group: comp.lang.lisp

Newbie question

Newbie question  
Ulf Wikstr?m
 Re: Newbie question  
David Sletten
 Re: Newbie question  
Frode Vatvedt Fjeld
From:Ulf Wikstr?m
Subject:Newbie question
Date:17 Jan 2005 01:53:29 -0800
Hello!
Is (cons a b) and '(a . b) not the same thing?

I want to define a function bind1 like this:

(defun bind1 (fun arg1)
#'(lambda (&rest rest)
(apply fun '(arg1 . rest))))

When i try to do:

(funcall (bind1 #'+ 2) 3)

i get the following error message:

*** - APPLY: argument list given to + is dotted (terminated by REST)

This code works, however:

(defun bind1 (fun arg1)
#'(lambda (&rest rest)
(apply fun (cons arg1 rest))))

I really can't see the difference.. Am I missing something obvious?

Thanks!
From:David Sletten
Subject:Re: Newbie question
Date:Mon, 17 Jan 2005 10:17:56 GMT
Ulf Wikstr?m wrote:

> Hello!
> Is (cons a b) and '(a . b) not the same thing?
>
> I want to define a function bind1 like this:
>
> (defun bind1 (fun arg1)
> #'(lambda (&rest rest)
> (apply fun '(arg1 . rest))))
>
> When i try to do:
>
> (funcall (bind1 #'+ 2) 3)
>
> i get the following error message:
>
> *** - APPLY: argument list given to + is dotted (terminated by REST)
>
> This code works, however:
>
> (defun bind1 (fun arg1)
> #'(lambda (&rest rest)
> (apply fun (cons arg1 rest))))
>
> I really can't see the difference.. Am I missing something obvious?
>
> Thanks!
Yes, you are missing something obvious. Here's what it is...

In Lisp a single-quote is a syntactic shortcut for the QUOTE special
operator:
http://www.lispworks.com/documentation/HyperSpec/Body/s_quote.htm

'(a b c) becomes (quote (a b c)). The QUOTE operator simply returns its
argument without evaluation:
'(a b c) => (A B C)
(quote (a b c)) => (A B C)

Your example '(a . b) evaluates neither A nor B:
'(a . b) => (A . B)

However, CONS is a function, so its arguments are evaluated before it
gets called:
(let ((a 1)
(b 2))
(cons a b))
=> (1 . 2)

Here, the _value_ of the variable A and the _value_ of the variable B
are sent to CONS, so your analogy is not quite correct. Instead, '(a .
b) is equivalent to (cons 'a 'b). Here the _symbol_ A and the _symbol_ B
are CONSed.

In your first function definition, you are trying to APPLY #'+ to the
CONS (ARG1 . REST) consisting of the _symbols_ ARG1 and REST, not the
_values_ of the parameters named ARG1 and REST. In your second
definition, you correctly evaluate these parameters, and your code works.

David Sletten
From:Frode Vatvedt Fjeld
Subject:Re: Newbie question
Date:Mon, 17 Jan 2005 11:06:51 +0100
ulfwikstrom@netscape.net (Ulf Wikstr?m) writes:

> Is (cons a b) and '(a . b) not the same thing?

No, the former creates a new cons-cell whose car and cdr are the
values of the variables a and b, while the second form returns the
same (constant) object which is a cons-cell whose car and cdr are the
symbols a and b. Just try to evaluate the forms to see the difference.

> I want to define a function bind1 like this:
>
> (defun bind1 (fun arg1)
> #'(lambda (&rest rest)
> (apply fun '(arg1 . rest))))

Try this:

(defun bind1 (fun arg1)
(lambda (&rest rest)
(apply fun arg1 rest)))

--
Frode Vatvedt Fjeld
   

Copyright © 2006 knowledge-database   -   All rights reserved