I've been playing around with Scheme and Common Lisp
In Scheme I'm able to write a function like this to return a function:
(define (testfunc f)
(lambda (x) (f x x)))
then call it like this
((testfunc +) 4)
=> 8
but how can I do this in Common Lisp?
Well, my cheapware Lisp flakes out when I do this, but this might work in
ACL...
(defmacro make-my-function (name)
`(progn (defun ,name (a b) (format nil "~a ~b" a b)) #',name))
and use it thus...
(funcall (make-my-function fred) 1 2)
or
(funcall #'fred 1 2)
This is a degenerate example, but it's what Lisp is really great for:
code that writes code.
...sl...
ChilliHead wrote:
> I've been playing around with Scheme and Common Lisp
>
> In Scheme I'm able to write a function like this to return a function:
>
> (define (testfunc f)
> (lambda (x) (f x x)))
>
> then call it like this
>
> ((testfunc +) 4)
>
> => 8
>
> but how can I do this in Common Lisp?
"ChilliHead" <···········@hotmail.com> writes:
> I've been playing around with Scheme and Common Lisp
>
> In Scheme I'm able to write a function like this to return a function:
>
> (define (testfunc f)
> (lambda (x) (f x x)))
>
> then call it like this
>
> ((testfunc +) 4)
>
> => 8
>
> but how can I do this in Common Lisp?
(defun testfunc (f)
(lambda (x) (funcall f x x)))
Note that (FUNCALL fn . args) is used to cause the contents of a
variable name or expression computed in the normal variable namespace
and causing it to be called as a function would be.
(funcall (testfunc #'+) 4)
Note that (FUNCTION f), or the equivalent shorthand notation: #'f
is a kind of inverse transformation, taking a name in the function
namespace and make it available for use as a value in the ordinary
namespace of variables and expressions.
"ChilliHead" <···········@hotmail.com> writes:
> I've been playing around with Scheme and Common Lisp
>
> In Scheme I'm able to write a function like this to return a function:
>
> (define (testfunc f)
> (lambda (x) (f x x)))
>
> then call it like this
>
> ((testfunc +) 4)
>
> => 8
>
> but how can I do this in Common Lisp?
(defun testfunc (f)
(lambda (x) (funcall f x x)))
(funcall (testfun #'+) 4)
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
"ChilliHead" <···········@hotmail.com> writes:
> I've been playing around with Scheme and Common Lisp
>
> In Scheme I'm able to write a function like this to return a
> function:
>
> (define (testfunc f)
> (lambda (x) (f x x)))
>
> then call it like this
>
> ((testfunc +) 4)
>
> => 8
>
> but how can I do this in Common Lisp?
As this kind of question comes up here rather often, I've added it to
the Cookbook:
<http://agharta.de/cookbook/functions.html>
I hope the experts will take a quick look at it and correct my
mistakes.
Thanks in advance,
Edi.
From: David Sletten
Subject: Re: Returning functions
Date:
Message-ID: <3C634978.406@home.com>
ChilliHead wrote:
> I've been playing around with Scheme and Common Lisp
>
> In Scheme I'm able to write a function like this to return a function:
>
> (define (testfunc f)
> (lambda (x) (f x x)))
>
> then call it like this
>
> ((testfunc +) 4)
>
> => 8
>
> but how can I do this in Common Lisp?
>
I'm not as experienced as the others who've responded, but here's my two
cents...
In Scheme, a symbol can only be associated with a single value, so the
following expressions conflict:
(define f
(lambda (x)
(+ x 2)) )
(define f 'foo)
However, in Common Lisp a symbol has both a value cell and a function
cell (as well as 3 others). These cells are entirely independent of each
other. Thus, these expressions have no impact upon one another:
(defun g (x)
(+ x 3) )
(setf g 'bar)
The defun above is another way of doing this:
(setf (symbol-function 'g) #'(lambda (x) (+ x 3)))
So now (g 7) => 10
If you wanted to, you could assign a function as the value of g too:
(setf g #'(lambda (y) (* y 4)))
However, when eval looks at a list whose car is a symbol, its function
cell is used. In this case, (g 7) is still 10. But (funcall g 7) is 28.
funcall applies the value of its first argument as a function. Note that
the value cell of g is used here. Contrast that with (funcall #'g 7) or
(funcall 'g 7), where again the function cell is used.
I think that in your Scheme example, since the symbol testfunc only
contains a function value that there is no confusion when it is eval'd.
I believe that your function definition is equivalent to this in Common
Lisp:
(setf testfunc
#'(lambda (f)
#'(lambda (x)
(funcall f x x))))
which is different than this:
(defun testfunc (f)
#'(lambda (x)
(funcall f x x)) )
The first example assigns a function as the value of testfunc. It
doesn't do anything to the function cell. Then (testfunc #'+) is
meaningless to eval since the function cell is undefined. You must use
funcall to apply the function stored in testfunc. The value of (funcall
testfunc #'+) is itself a function, and this must be passed to funcall too:
(funcall (funcall testfunc #'+) 4)
The second example defines a function which returns a function, so now
(testfunc #'+) is meaningful. The returned value is used with funcall:
(funcall (testfunc #'+) 4)
David Sletten
>>>>> "David" == David Sletten <·········@home.com> writes:
David> The defun above is another way of doing this: (setf
David> (symbol-function 'g) #'(lambda (x) (+ x 3)))
Isn't that technically incorrect? DEFUN wraps the body with a BLOCK
of the same name as the function, so a possibly less incorrect macro
expansion would be:
(setf (symbol-function 'g) #'(lambda (x) (block g (+ x 3))))
But this is probably missing some implementation-specific magic.
--
Matthew X. Economou <········@irtnog.org> - Unsafe at any clock speed!
"We're born with a number of powerful instincts, which are found across all
cultures. Chief amongst these are a dislike of snakes, a fear of falling,
and a hatred of popup windows" --Vlatko Juric-Kokic
"Matthew X. Economou" <···············@irtnog.org> writes:
> >>>>> "David" == David Sletten <·········@home.com> writes:
>
> David> The defun above is another way of doing this: (setf
> David> (symbol-function 'g) #'(lambda (x) (+ x 3)))
>
> Isn't that technically incorrect? DEFUN wraps the body with a BLOCK
> of the same name as the function, so a possibly less incorrect macro
> expansion would be:
>
> (setf (symbol-function 'g) #'(lambda (x) (block g (+ x 3))))
Well, we can assume that David's using an implementation that treewalks
the code, sees that the block is unused, and elides it. ;) But yes,
you're right, there is an implicit block there.
> But this is probably missing some implementation-specific magic.
The correct function of DEFUN does not rely on such implementation-specific
magic. The magic is allowed as additional bookkeeping to aid the programming
environment. e.g., you might see:
(system::record-source-file 'g *load-truename*)
(setf (documentation 'g 'function) nil) ;could have been something more
... etc.