Prev: Why warnings about unused keyword although (call-next-method) is used?
Next: [ANN] REVISED DEADLINE for Scheme and Functional Programming Workshop
From: Mirko on 14 Jun 2010 09:25 Hello, Can someone please give me a simple example of the usefulness of (coerce ... 'function). I am confused because (funcall (lambda ...) ...) seems to work as well as (funcall (coerce (lambda ... ) 'function) ...) Thank you, Mirko
From: Rainer Joswig on 14 Jun 2010 09:47 In article <39c97637-9ea4-4d2a-b1d2-6c8a4cdef48d(a)f6g2000vbl.googlegroups.com>, Mirko <mirko.vukovic(a)gmail.com> wrote: > Hello, > > Can someone please give me a simple example of the usefulness of > (coerce ... 'function). > > I am confused because (funcall (lambda ...) ...) seems to work as well > as (funcall (coerce (lambda ... ) 'function) ...) > > Thank you, > > Mirko (funcall '(lambda (x) (+ x (sin x))) 3.0) CL-USER 5 > (funcall '(lambda (x) (+ x (sin x))) 3.0) Error: Argument to apply/funcall is not a function: (LAMBDA (X) (+ X (SIN X))). But: CL-USER 7 > (funcall (coerce '(lambda (x) (+ x (sin x))) 'function) 3.0) 3.14112 -- http://lispm.dyndns.org/
From: Pascal Costanza on 14 Jun 2010 10:28 On 14/06/2010 15:25, Mirko wrote: > Hello, > > Can someone please give me a simple example of the usefulness of > (coerce ... 'function). > > I am confused because (funcall (lambda ...) ...) seems to work as well > as (funcall (coerce (lambda ... ) 'function) ...) (coerce ... 'function) converts a quoted lambda expression to an actual function. There are actually three ways in Common Lisp to do this: (eval '(lambda (x) (+ x x)) (coerce '(lambda (x) (+ x x) 'function) (compile nil '(lambda (x) (+ x x)) All of those produce functions, but depending on CL implementation, with slightly different results: eval usually produces an interpreted version (unless the CL implementation at hand doesn't provide an interpreter), compile produces a compiled version (unless the CL implementation at hand doesn't provide a compiler, but it nevertheless has to do at least minimal compilation in this case [1]), and coerce usually picks one of the two. There is at least one implementation, though, where coerce provides yet a third alternative: In ECL, coerce compiles to bytecode, which can then be executed faster than 'pure' interpreted code, but is less heavy on resource requirements than the rather expensive compile variant, which in the ECL case compiles to C and then uses an external C compiler to produce the resulting machine code. It depends a lot on circumstances which of the two or three alternatives is better. Compiled code is not always the best option. Especially for one-off code that you want to run just once, but then not reuse anymore, interpretation can be considerably more efficient, because the overhead of running a compilation phase first is avoided. Compilation typically only pays off when you want to reuse the function in question quite often. In cases where efficiency concerns are not the topmost priority, coerce is probably the best choice, because you can trust the vendor of the CL implementation somewhat to use a reasonable variant for coerce. Pascal [1] See Section 3.2.2.2 in the HyperSpec. -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Captain Obvious on 14 Jun 2010 13:14 M> Can someone please give me a simple example of the usefulness of M> (coerce ... 'function). M> I am confused because (funcall (lambda ...) ...) seems to work as well M> as (funcall (coerce (lambda ... ) 'function) ...) You might be confused because (funcall (lambda (x) x) 1) is actually (funcall (function (lambda (x) x)) 1) after macroexpansion. It is because LAMBDA is defined as macro in Common Lisp and it adds that FUNCTION thing. Then FUNCTION is a special operator which can recognize lambda expression and will create a function from it. But FUNCTION does not evaluate its argument, so you cannot construct new functions in runtime this way. So this: (let ((lambda-expression (read s))) (funcall (function lambda-expression) 1) won't work. That's where you need (coerce ... 'function): (let ((lambda-expression (read s))) (funcall (coerce lambda-expression 'function) 1) Other ways to do this is EVAL and COMPILE.
From: fortunatus on 16 Jun 2010 15:23
On Jun 14, 10:28 am, Pascal Costanza <p...(a)p-cos.net> wrote: > (coerce ... 'function) converts a quoted lambda expression to an actual > function. It seems to me that one main use of that would be "auto-programming" kind of code: some program that writes a function as a list structure, then wants to load it into the system. |