English 中文(简体)
returning a lambda function in clisp, then evaluating it
原标题:

Suppose I have this wonderful function foo

[92]> (defun foo () (lambda() 42))
FOO
[93]> (foo)
#<FUNCTION :LAMBDA NIL 42>
[94]> 

Now, suppose I want to actually use foo and return 42.

How do I do that? I ve been scrounging around google and I can t seem to come up with the correct syntax.

最佳回答

You want the FUNCALL function:

* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42
问题回答

The relevant terms here are "Lisp-1" and "Lisp-2".

Your attempt at calling would work in a Lisp-1 like e.g. Scheme or Clojure. Common Lisp is a Lisp-2 however which roughly means that variable names and function names are separate.

So, in order to call the function bound to a variable you either need to use the special forms funcall or apply as others have pointed out or set the function value of the symbol foo rather than the variable value.

The former basically takes the variable value of the symbol, assumes/checks that value is a function and then calls the function (with whatever arguments you passed to funcall/apply.

You don t really want to do the latter as that is quite silly in all but very specialised cases, but for completness sake this is roughly how you d do it:

CL-USER> (setf (symbol-function  foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {C43DCFD}>
CL-USER> (foo)
42

You should also want to look into the labels and flet special forms (which are commonly used) - there you actually do use the latter methods (these forms create a temporary function binding for symbols).

So your problem would there look like this:

(flet ((foo () 
         42))
  (foo))

i.e. here you temporarily bind the function value of the symbol foo to the function returning 42. Within that temporary context you can then call (foo) like regular global functions.

Your function foo returns a function. Use the funcall function to apply a function to arguments, even if the argument set is empty.

Here you can see that foo returns a value of type function:

CL-USER> (let ((f (foo)))
           (type-of f))
FUNCTION
CL-USER> (let ((f (foo)))
           (funcall f))
42
CL-USER> (type-of (foo))
FUNCTION
CL-USER> (funcall (foo))
42

Another option besides FUNCALL is APPLY:

(apply (foo) nil)

FUNCALL is the idiomatic way here, but you ll need APPLY when you have a list of parameters.





相关问题
Lisp code called from Java

Long story: I am doing a project for my functional programing class, and I thought of writing an AI controller in Lisp, for the Mario AI competition. I was looking over frameworks/libraries/ways of ...

Emacs, Zen-Coding mode, and Putty

I use emacs via Putty and since Putty doesn t send certain key combinations to the remote console I generally need to re-bind them to other key combinations. After installing the amazing Zen-Coding ...

In Which Cases Is Better To Use Clojure? [closed]

I develop in Lisp and in Scheme, but I was reading about Clojure and then I want to know, in which cases is better to use it than using Lisp or Scheme? Thanks

lambda-gtk negative pointer

I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative ...

Is there a common lisp package naming convention?

I have created some of my own user packages and have run into a name clash. In Java, the naming convention is to use your domain name in the package name: e.g. import com.example.somepackage;. Are ...

SOAP request from within an AutoLISP/AutoCAD macro

We have built a webservice for a client that uses AutoCAD. They have a macro that runs in AutoCAD that builds a SOAP request. But they have not figured out how to actually send() the soap request to ...

热门标签