Say I want to pass functions + or - (or similar) to another function
and there apply them to some set:
; -- ideal (not working) code: --
(defun general-function (fun a b)
(fun a b))
...and then call it like
(general-function '+ 5 7) or
(general-function '* 3 4) etc
Is this possible and trivial?
·······@ec.auckland.ac.nz (Peder Y) wrote in message news:<····························@posting.google.com>...
> Say I want to pass functions + or - (or similar) to another function
> and there apply them to some set:
>
> ; -- ideal (not working) code: --
>
> (defun general-function (fun a b)
> (fun a b))
>
> ...and then call it like
>
> (general-function '+ 5 7) or
> (general-function '* 3 4) etc
>
> Is this possible and trivial?
Not the way you have it. You need (funcall fun a b). In Lisp, symbols
have separate value and function bindings. The expression (fun a b)
looks for a function named fun, ignoring the lexical variable named
fun.
Usually you want to quote a function using #' rather than ' . The
expresson '+, equivalent to (quote +) gives you the symbol +, whereas
#'+ which is equivalent to (function +) retrieves the symbol's
function binding.
For functions that can be dynamically replaced (i.e. the ones you
write yourself, not standard CL functions like +), it makes a
difference which method you use to retain a reference to the function.
The object obtained by (function <sym>) does not change after a new
version of the function is installed under the given symbol;
funcall-ing the originally retrieved value uses the original function.
(defun foo () 'foo)
(defvar *func-foo* #'foo)
(defvar *sym-foo* 'foo)
(defun foo () 'redefined)
(funcall *func-foo*) ==> FOO
(funcall *sym-foo*) ==> REDEFINED
Funcalling through a symbol always goes to whatever function is
currently bound to that symbol. Another situation in which this can
matter is when you have local functions.
(defun fun ()
(format t "top level function called~%"))
(defun call-function ()
(flet ((fun () (format t "local function called~%")))
(funcall 'fun) ;; calls top level one
(funcall #'fun))) ;; calls local one
(call-function)
output ==>
top level function called
local function called
The funcall function has no access to your lexical scope, so it cannot
resolve the symbol fun to the local function. The #' operator does
have access to the scoped binding, and uses it to retrieve the right
function object.
From: Hannah Schroeter
Subject: Re: How to pass a function as a parameter
Date:
Message-ID: <aqqs7c$lfm$1@c3po.schlund.de>
Hello!
Peder Y <·······@ec.auckland.ac.nz> wrote:
>Say I want to pass functions + or - (or similar) to another function
>and there apply them to some set:
>; -- ideal (not working) code: --
>(defun general-function (fun a b)
> (fun a b))
>...and then call it like
>(general-function '+ 5 7) or
>(general-function '* 3 4) etc
(defun general-function (fun a b)
(funcall fun a b))
(general-function #'+ 5 7) => 12
(general-function #'* 3 4) => 12
Kind regards,
Hannah.
·······@ec.auckland.ac.nz (Peder Y) writes:
> (general-function '+ 5 7) or
> (general-function '* 3 4) etc
>
> Is this possible and trivial?
yes. "general-function" is, if I understood you right, similar
to FUNCALL. There's also APPLY at your disposal
(see http://www.lispworks.com/reference/HyperSpec/Body/f_apply.htm).
(I think you'd benifit from a lisp text book!)
--
(espen)