From: ChilliHead
Subject: Returning functions
Date: 
Message-ID: <1013079424.574860@ernani.logica.co.uk>
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?

From: Steve Long
Subject: Re: Returning functions
Date: 
Message-ID: <3C62B165.780B4E47@hotmail.com>
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?
From: Kent M Pitman
Subject: Re: Returning functions
Date: 
Message-ID: <sfwit99wltr.fsf@shell01.TheWorld.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?

(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.
From: Raymond Wiker
Subject: Re: Returning functions
Date: 
Message-ID: <868za5tt85.fsf@raw.grenland.fast.no>
"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/
From: Dr. Edmund Weitz
Subject: Re: Returning functions
Date: 
Message-ID: <m33d0d4chh.fsf@bird.agharta.de>
"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
From: Matthew X. Economou
Subject: Re: Returning functions
Date: 
Message-ID: <w4on0yeec1h.fsf@eco-fs1.irtnog.org>
>>>>> "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
From: Kent M Pitman
Subject: Re: Returning functions
Date: 
Message-ID: <sfwlmdyh3d8.fsf@shell01.TheWorld.com>
"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.