From: Roy Leonard
Subject: Newbie question on passing functions as arguments
Date: 
Message-ID: <918eee97.0408061756.14d20d91@posting.google.com>
I'm fairly new to Lisp, and I've got somewhat of a question.
(FYI, I'm working on Lesson 8 at
http://www.fast-index.com/declarative/lectures/  So it's Common Lisp,
and I'm learning in Lispworks)

I was trying to make a function that I could pass an optional function
argument to, and have a default value for that function.

So, knowing that

(defun foo (&optional (bar 8))
  bar)

would give me:

2> (foo)
8

3> (foo 4)
4

I extended that "knowledge" to:

(defun something-three (bar &optional (baz #'=))
  (if (baz bar 3)
      "You Win!"
    "Sorry, Play Again"))

So, I'm essentially testing for a condition to 3, with a default being
=.

However I keep getting errors like:

10> (something-three 3)
Error: Undefined function BAZ called with arguments (3 3).


I'm obviously doing something horribly wrong... my question is what?

I had thought that in Lisp you could pass functions around as data,
right?

From: Peter Seibel
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <m3hdrf4sfw.fsf@javamonkey.com>
···········@gmail.com (Roy Leonard) writes:

> I'm obviously doing something horribly wrong... my question is what?
>
> I had thought that in Lisp you could pass functions around as data,
> right?

You can. But in Common Lisp there are two namespaces--BAZ in your
function is the name of a variable whose value happens to be a
function not the name of a function. Look up FUNCALL and APPLY in your
favorite Common Lisp reference.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Iain Little
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87657vptr9.fsf@yahoo.com>
···········@gmail.com (Roy Leonard) writes:

> I'm fairly new to Lisp, and I've got somewhat of a question.
> (FYI, I'm working on Lesson 8 at
> http://www.fast-index.com/declarative/lectures/  So it's Common Lisp,
> and I'm learning in Lispworks)
>
> I was trying to make a function that I could pass an optional function
> argument to, and have a default value for that function.
[...]
> (defun something-three (bar &optional (baz #'=))
>   (if (baz bar 3)
>       "You Win!"
>     "Sorry, Play Again"))
>
> So, I'm essentially testing for a condition to 3, with a default being
> =.

Almost right, you just need a small change:

(defun something-three (bar &optional (baz #'=))
  (if (funcall baz bar 3)
      "You Win!"
    "Sorry, Play Again"))

> I had thought that in Lisp you could pass functions around as data,
> right?

That is right.  The problem you have come up against is that functions
and values are in different namespaces.[1] When you write "(baz bar
3)", this means that you want to call the function called BAZ.  When
you write "(funcall baz bar 3)", you are calling the function that is
the value of the variable BAZ.

The following example might help, both to explain why the distinction
is made, and to help understand it:

(let ((list '(1 2 3)))
  (list 'a list 'b))

This will return:

(a (1 2 3) b)

If we didn't have separate namespaces for functions and values, then
we wouldn't be able to call the local variable LIST and still be able
to use the function LIST when the variable is in scope.

Having separate namespaces is also why we have the special syntax (#')
for quoting functions.  That syntax is saying that we want a symbol's
function, rather than its value.

[1] This isn't true in all Lisps.  In Scheme, for instance, the
approach that you originally took would work.  People often refer to a
Lisp as being a Lisp-1 or Lisp-2, depending on which design choice was
made in this regard.

Cheers,


Iain
From: Roy Leonard
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <918eee97.0408071135.3f693141@posting.google.com>
Iain Little <······@yahoo.com> wrote in message 
> Almost right, you just need a small change:

Excellent! It works!
I think I had heard of funcall before, but I had heard that it was
quite inefficent compared to... some other method of doing essentially
the same thing.

Can you confirm this?

> If we didn't have separate namespaces for functions and values, then
> we wouldn't be able to call the local variable LIST and still be able
> to use the function LIST when the variable is in scope.

I see. So we can have George the Function, and George the Local
Varible, and they don't know that each other exists.

Hmm.. are there any global system-defined-varibles? From what I
remember of C-ish languages, there were certain things that you
weren't allowed to touch. Does Lisp have the same?

> People often refer to a Lisp as being a Lisp-1 or Lisp-2,
> depending on which design choice was made in this regard.

Ahh, a 1-namespace, or 2-namespace Lisp, right?
Well, I could ask about what would happen when a defined varible
conflicts with, say, one of the clauses in a LOOP macro, but I think
I'll wait on that until I actually get to learning LOOP.

Peter Seibel <·····@javamonkey.com> wrote in message 
> Look up FUNCALL and APPLY in your favorite Common Lisp reference.

That I did. So would I be right in saying that the only "real"
difference between FUNCALL and APPLY is that APPLY will take extra
arguments and include them in a list in the place of the last
argument?

So if FOO only takes 2 arguments, and I:

> (apply #'foo 'Fred 'Harry 'George)

Then FOO will get 'Fred as normal, and '(Harry George) as the second
argument?

Or would it be more complex than that?

Thanks again.
From: Bruce Stephens
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87ekmioffi.fsf@cenderis.demon.co.uk>
···········@gmail.com (Roy Leonard) writes:

[...]

> Excellent! It works!
> I think I had heard of funcall before, but I had heard that it was
> quite inefficent compared to... some other method of doing essentially
> the same thing.
>
> Can you confirm this?

No.

[...]

> That I did. So would I be right in saying that the only "real"
> difference between FUNCALL and APPLY is that APPLY will take extra
> arguments and include them in a list in the place of the last
> argument?
>
> So if FOO only takes 2 arguments, and I:
>
>> (apply #'foo 'Fred 'Harry 'George)
>
> Then FOO will get 'Fred as normal, and '(Harry George) as the second
> argument?
>
> Or would it be more complex than that?

No more complex, but you've got it the wrong way around.  apply can
take a list and call a function with the elements as separate
arguments.  So if foo takes two arguments, then you could call it like
this:

(apply 'foo '(Fred Harry))
From: Edi Weitz
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87vffu7lpx.fsf@bird.agharta.de>
On 7 Aug 2004 12:35:42 -0700, ···········@gmail.com (Roy Leonard) wrote:

> I think I had heard of funcall before, but I had heard that it was
> quite inefficent compared to... some other method of doing
> essentially the same thing.
>
> Can you confirm this?

No. If you want to call a function that you don't know until runtime
there isn't a more efficient way to do it.[1]

> Hmm.. are there any global system-defined-varibles? From what I
> remember of C-ish languages, there were certain things that you
> weren't allowed to touch. Does Lisp have the same?

In a way. See

  <http://www.lispworks.com/reference/HyperSpec/Body/11_abab.htm>

That does, e.g., mean that you are not allowed to redefine the
function CL:MAX. Note, however, that you can declare your own package
in which you 'shadow' the symbol MAX from the COMMON-LISP package. In
this package you can define your own MAX function.

> Well, I could ask about what would happen when a defined varible
> conflicts with, say, one of the clauses in a LOOP macro

Nothing, in this case. The LOOP 'keywords' (they aren't really
keywords in the technical sense) are recognized by name and there
meaning depends upon their position within the LOOP body.

> That I did. So would I be right in saying that the only "real"
> difference between FUNCALL and APPLY is that APPLY will take extra
> arguments and include them in a list in the place of the last
> argument?

Yes. You can easily define FUNCALL using APPLY but you'll have a hard
time defining APPLY in terms of FUNCALL.

>> (apply #'foo 'Fred 'Harry 'George)
>
> Then FOO will get 'Fred as normal, and '(Harry George) as the second
> argument?

No. The last argument to APPLY must be a list. These are all
equivalent:

  (funcall #'foo 'fred 'harry 'george)
  (apply #'foo '(fred harry george))
  (apply #'foo 'fred '(harry george))
  (apply #'foo 'fred 'harry '(george))
  (apply #'foo 'fred 'harry 'george ())

Cheers,
Edi.


[1] Well, in some implementations with high optimization settings it
    might be a tad more efficient to do

      (declare (function f))
      ...
      (funcall f args)

    instead of just

      (funcall f args)

    because in the second case F might be a symbol as well as a
    function object so if you /know/ it'll always be a function you
    can help the compiler.

-- 

"Lisp doesn't look any deader than usual to me."
(David Thornley, reply to a question older than most languages)

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Roy Leonard
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <918eee97.0408081421.7ff0e9e1@posting.google.com>
Edi Weitz <········@agharta.de> wrote in message news:<··············@bird.agharta.de>...
> No. If you want to call a function that you don't know until runtime
> there isn't a more efficient way to do it.[1]
[...]
> [1] Well, in some implementations with high optimization settings it
>     might be a tad more efficient to do
> 
>       (declare (function f))
>       ...
>       (funcall f args)
> 
>     instead of just
> 
>       (funcall f args)
> 
>     because in the second case F might be a symbol as well as a
>     function object so if you /know/ it'll always be a function you
>     can help the compiler.

Just to try it out, I tried the declare, and I had to play with it a
bit to get it to work... it seems like you have to #' it in the
declare, but then *not* #' it in the funcall... Like:

 (defun foo (thefun)
               (declare (function #'thefun))
               (funcall thefun 1 1))

(I assume) that would be because after you have told it that it's a
function, quoting it causes it to look for the function that thefun is
pointing to instead of the declared function THEFUN itself??

Or am I thinking of it backwards, and (declare (function baz)) simply
makes it always look at baz as a function - so baz can't be used in
the symbol namespace?


[snip]
> Yes. You can easily define FUNCALL using APPLY but you'll have a hard
> time defining APPLY in terms of FUNCALL.

Indeed. Is there any way in Lisp to convert a list into separate
arguments? If I had a list of indeterminate length such as:

(defvar foo '(could-be might possibly likely
your-guess-is-as-good-as-mine ...))

and I wanted to AND it, is there some sort of thing I could do like:

(and (break-out-of-list foo))

Or would I have to:

(defun list-and (args)
  (let ((retval nil))
    (dolist (curval args)
      (if curval
        (setf retval curval)
        (return-from list-and nil)))
    retval))

(pardon my lack of elegance - is tail-recursive better here?)

(defun my-list-and (args)
  (cond ((or (not (first args))
             (<= (length args) 1))
         (first args))
        (T (my-list-and (rest args)))))


> No. The last argument to APPLY must be a list. These are all
> equivalent:
> 
>   (funcall #'foo 'fred 'harry 'george)
>   (apply #'foo '(fred harry george))
>   (apply #'foo 'fred '(harry george))
>   (apply #'foo 'fred 'harry '(george))
>   (apply #'foo 'fred 'harry 'george ())
> 

I see. So FUNCALL calls a function with the given arguments, while
APPLY applies a function to the given list, or calls it with the list
as its arguments.

As an exercise, I put together PRE-APPLY to change all of the above
APPLY calls into the first example. :-) - Hey, I need all the practice
I can get.

(defun pre-apply (func &rest args)
  (let* ((my-args (reverse args))
         (temp-list (pop my-args)))
    (dolist (cur-item temp-list)
      (push cur-item my-args))
    (apply func (reverse my-args))))


Thank-you very much for your help, btw.
From: Zach Beane
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <m3wu099rx8.fsf@unnamed.xach.com>
···········@gmail.com (Roy Leonard) writes:

> Is there any way in Lisp to convert a list into separate
> arguments? If I had a list of indeterminate length such as:
>
> (defvar foo '(could-be might possibly likely
> your-guess-is-as-good-as-mine ...))
>
> and I wanted to AND it, is there some sort of thing I could do like:
[snip]

EVERY and friends are useful for this sort of operation, e.g.

   (every #'identity foo)

http://www.lispworks.com/reference/HyperSpec/Body/f_everyc.htm

> As an exercise, I put together PRE-APPLY to change all of the above
> APPLY calls into the first example. :-) - Hey, I need all the practice
> I can get.
>
> (defun pre-apply (func &rest args)
>   (let* ((my-args (reverse args))
>          (temp-list (pop my-args)))
>     (dolist (cur-item temp-list)
>       (push cur-item my-args))
>     (apply func (reverse my-args))))

LIST* does something like this. CLTL2 specifically mentions it on
pp145-146:

  "The arguments for the /function/ consist of the last argument to
  APPLY appended to the end of a list of all other arguments to APPLY
  but the /function/ itself; it is as if all the arguments to APPLY
  except the /function/ were given to LIST* to create the argument
  list."

Zach
From: Edi Weitz
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87acx4kffs.fsf@bird.agharta.de>
On 8 Aug 2004 15:21:41 -0700, ···········@gmail.com (Roy Leonard) wrote:

> Just to try it out, I tried the declare, and I had to play with it a
> bit to get it to work... it seems like you have to #' it in the
> declare, but then *not* #' it in the funcall... Like:
>
>  (defun foo (thefun)
>                (declare (function #'thefun))
>                (funcall thefun 1 1))

Which Lisp are you using? If I compile this with CMUCL I get an error
message

  Type-error in KERNEL::OBJECT-NOT-SYMBOL-ERROR-HANDLER:
     #'THEFUN is not of type SYMBOL
     [Condition of type TYPE-ERROR]

The correct syntax would be

  (defun foo (thefun)
    (declare (function thefun))
    (funcall thefun 1 1))

> (I assume) that would be because after you have told it that it's a
> function, quoting it causes it to look for the function that thefun
> is pointing to instead of the declared function THEFUN itself??
>
> Or am I thinking of it backwards, and (declare (function baz))
> simply makes it always look at baz as a function - so baz can't be
> used in the symbol namespace?

Nope. Without the declaration THEFUN is an arbitrary local variable of
FOO which can hold anything. So, with

  (defun foo2 (thefun)
    (funcall thefun 1 1))

you can do (FOO2 '+) as well as (FOO2 #'+). In the first case THEFUN
is bound to a symbol, in the second case it's bound to a function. At
runtime FUNCALL will have to check which kind of argument it got and
will have to act accordingly. (Of course, if THEFUN is bound to
anything else like, say, a number you'll get a runtime error.)

With the declaration (see FOO above) you promise to the compiler that
DEFUN will /never/ be anything other than a function, i.e. you'll
never call FOO like (FOO '+), so the call to FUNCALL /might/ be
compiled more efficiently. (And there's the potential for strange
misbehaviour if THEFUN is not a function. So don't do this kind of
micro-optimization until you've identified this part of your app as a
bottleneck.)

> Indeed. Is there any way in Lisp to convert a list into separate
> arguments?

Yes, APPLY... :)

> If I had a list of indeterminate length such as:
>
> (defvar foo '(could-be might possibly likely
> your-guess-is-as-good-as-mine ...))
>
> and I wanted to AND it, is there some sort of thing I could do like:
>
> (and (break-out-of-list foo))

Look up functions like EVERY or SOME in the standard. You might also
want to look at REDUCE (although it won't help in this particular case
because AND is not a function.)

> (pardon my lack of elegance - is tail-recursive better here?)

No. Schemers generally find tail-recursion to be more elegant, Common
Lispers generally don't. Also, the Scheme language standard makes
certain guarantees about tail-recursion which the CL standard doesn't.

Cheers,
Edi.

-- 

"Lisp doesn't look any deader than usual to me."
(David Thornley, reply to a question older than most languages)

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Roy Leonard
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <918eee97.0408091813.eb252f1@posting.google.com>
Edi Weitz <········@agharta.de> wrote in message news:<··············@bird.agharta.de>...
> >  (defun foo (thefun)
> >                (declare (function #'thefun))
> >                (funcall thefun 1 1))
> 
> Which Lisp are you using? If I compile this with CMUCL I get an error
> message
[snip] 
> The correct syntax would be
> 
>   (defun foo (thefun)
>     (declare (function thefun))
>     (funcall thefun 1 1))

Ahh, the famous CMUCL. 
I was using Lispworks Personal, and I just tried the same (incorrect)
defun call with Allegro CL Trial - and it didn't complain either.

Fortunately, the correct defun doesn't cause any errors.

So does anyone have any guesses when CMUCL will be released for
Windows? :-D
I keep trying Linux every year or so, but it never seems to support my
hardware properly - ATI AIW 8500 is not its friend, apparently. :-)

> With the declaration (see FOO above) you promise to the compiler that
> DEFUN will /never/ be anything other than a function, i.e. you'll
> never call FOO like (FOO '+), so the call to FUNCALL /might/ be
> compiled more efficiently. (And there's the potential for strange
> misbehaviour if THEFUN is not a function. So don't do this kind of
> micro-optimization until you've identified this part of your app as a
> bottleneck.)

I see. So the DECLARE's purpose is only really for me to enter into a
blood oath with the compiler. (And have the added bonus of not having
to #' in the FUNCALL)

> > Indeed. Is there any way in Lisp to convert a list into separate
> > arguments?
> 
> Yes, APPLY... :)

*grin* 
So if I'm plugging the values of my list into a macro, special form,
etc. I'm out of luck then?
From: Matthew Danish
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <20040810025107.GJ15746@mapcar.org>
On Mon, Aug 09, 2004 at 07:13:14PM -0700, Roy Leonard wrote:
> So does anyone have any guesses when CMUCL will be released for
> Windows? :-D

Who knows, it may not be too far away, there seems to be progress.

> > With the declaration (see FOO above) you promise to the compiler that
> > THEFUN will /never/ be anything other than a function, i.e. you'll
> > never call FOO like (FOO '+), so the call to FUNCALL /might/ be
> > compiled more efficiently. (And there's the potential for strange
> > misbehaviour if THEFUN is not a function. So don't do this kind of
> > micro-optimization until you've identified this part of your app as a
> > bottleneck.)
> 
> I see. So the DECLARE's purpose is only really for me to enter into a
> blood oath with the compiler. (And have the added bonus of not having
> to #' in the FUNCALL)

No: #' indicates that the name is in the function namespace.  Function
parameters are in the variable namespace, that is why you do not need
the #'.

(defun foo (f)
  ;; says that the VARIABLE named F is bound to a function value
  (declare (type function foo))  
  (funcall f 1 2))

(defun foo (x)
  (flet ((blah (x y)
           (+ x y)))
    ;; says that the FUNCTION named BLAH is bound to a function value (duh)
    ;; FLET puts names into the FUNCTION namespace
    (declare (ftype (function (number number) number) blah))
    (blah x x)))

It has occurred to me that this issue might be much easier to figure out
if it was made explicit on every variable or function reference.

For example, (foo x y) <==> (function.foo variable.x variable.y)
Notice that the FIRST element of a form is looked up in the function
namespace.  It is not even evaluated before the look-up.

(function f) <==> #'f <==> function.f

So, (funcall #'+ 1 2) becomes (function.funcall function.+ 1 2)
and (funcall f 1 2) becomes (function.funcall variable.f 1 2)

So, when working with real Lisp code, you just have to remember that
those namespace prefixes are really there, they're just implied by
context.

(let ((x #'(lambda () 1))) (funcall x))
  <==>
(function.let ((variable.x function.(lambda () 1))) 
  (function.funcall variable.x))

I put a function. prefix in front of the LAMBDA form because that is how
it is treated by CL: a way to designate a function that has no name.
You must realize, however, that even though variable.x is bound to a
function value, it is still in the variable namespace.  LET is not a
function, but it is looked up in the function namespace, hence the
prefix.

Similarly,
(flet ((f () 1)) (funcall #'f))
  <==>
(function.flet ((function.f () 1)) (function.funcall function.f))

Without the #', (funcall f) would become (function.funcall variable.f),
and hopefully it is quite clear that there is no binding for variable.f
here.

It should be trivial to understand the form
(let ((list (list 1 2 3))) (funcall #'list list)) now, for example.


> > > Indeed. Is there any way in Lisp to convert a list into separate
> > > arguments?
> > 
> > Yes, APPLY... :)
> 
> *grin* 
> So if I'm plugging the values of my list into a macro, special form,
> etc. I'm out of luck then?

Macros are expanded at compile-time.  It doesn't make sense to have the
elements of a run-time list value "plugged" into a macro.  Macros
operate on code alone, it just so happens that code is represented as
Lisp data and can be manipulated with the Lisp language.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
From: Kalle Olavi Niemitalo
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87r7qg50bn.fsf@Astalo.kon.iki.fi>
···········@gmail.com (Roy Leonard) writes:

> Just to try it out, I tried the declare, and I had to play with it a
> bit to get it to work... it seems like you have to #' it in the
> declare, but then *not* #' it in the funcall... Like:
>
>  (defun foo (thefun)
>                (declare (function #'thefun))
>                (funcall thefun 1 1))

That's not right.  Because FUNCTION is a type, the declaration
is a shorthand for (declare (type function #'thefun)).  But the
specification of the TYPE declaration says the syntax is (type
typespec var*) where var is a variable name.  #'thefun is not a
variable name, so SBCL 0.8.12.34 complains:

  debugger invoked on a TYPE-ERROR in thread 30647:
    The value #'THEFUN is not of type SYMBOL.

The right way is:

  (defun foo (thefun)
    (declare (function thefun))
    (funcall thefun 1 1))

This declares that the value of the parameter variable THEFUN is
a function.  FOO can now be called like this:

  (foo #'+)             ; => 2

Because the parameter has been declared as a function, a symbol
must not be given:

  (foo '+)              ; "the consequences are undefined"

SBCL 0.8.12.34 detects this error and complains:

  debugger invoked on a TYPE-ERROR in thread 30647:
    The value + is not of type FUNCTION.

CLISP 2.32 just returns 2 as if the declaration had not been
there; CLHS section 3.3.1 explicitly permits this.  Because
"the consequences are undefined" when the TYPE declaration is
violated, other implementations could react in stranger ways.

> (pardon my lack of elegance - is tail-recursive better here?)

Iteration is generally better than tail recursion in Common Lisp.
This particular case could also be solved with the ALWAYS clause
of LOOP.
From: Edi Weitz
Subject: Re: Newbie question on passing functions as arguments
Date: 
Message-ID: <87657skfb5.fsf@bird.agharta.de>
On Mon, 09 Aug 2004 08:48:12 +0300, Kalle Olavi Niemitalo <···@iki.fi> wrote:

> This particular case could also be solved with the ALWAYS clause of
> LOOP.

ALWAYS will always return NIL or T while AND will return its last
argument if all args are true.

Edi.

-- 

"Lisp doesn't look any deader than usual to me."
(David Thornley, reply to a question older than most languages)

Real email: (replace (subseq ·········@agharta.de" 5) "edi")