From: Captain Obvious on 3 Nov 2009 04:25 ??>> You can use macro to generate a code which generates lambda, ??>> for example. NE> Ok, so I use macro to generate code and then invoke the compiler at NE> runtime. No! You use macro to transform your code at compile time. Then code you've generated does anything it wants in runtime. NE> What is best practice for this: eval or compile ? In case you _really_ need it, best practice is compile. But you do not need it in this case. A rule of thumb: if you think you need eval or compile, it is higly lickely you're doing it wrong. Basically, the only case when you need eval is when code is not known at compile-time. That is, user enters it from keyboard, or you recieve it from network, or generate through GA or something. In other cases, when you just need to fill in some parameters, you can do that other way. NE> Do they have similar meaning in this context ? Yep they do, almost. The only difference is that eval might or might not compile functions, while compile almost certainly does. compile is a bit tidier IMHO because it accepts only lambda rather than arbitrary piece of code. There is also a third way to do it -- (coerce ... 'function), it is pretty good too, if you just need a function, not necessarily compiled. That's how you can generate lambdas at runtime, but there is no reason to do this in this case. Xach have shown how you can do this with lambda and without any code duplication. That was really the best way. It is actually a good practice to avoid using macros when you can just use higher-order functions. If you absolutely want to use macros, you can do this like this (using IF at runtime): (defmacro maybe-lambda (predicate paramlist statement) `(if ,predicate (lambda ,paramlist ,statement) (lambda ,paramlist (not ,statement)))) (defun foo (value predicate) (maybe-lambda predicate (x) (eql x value))) No runtime code generation, but maybe have lost its generality. Or you can write a more complex macro which is more general. Your `maybe` macro just maybe inserts NOT in the beginning of the statement. My with-maybe macro can insert NOT into any place within statement user wants it to. (defmacro with-maybe (predicate statement) `(if ,predicate (macrolet ((maybe (statement) statement)) ,statement) (macrolet ((maybe (statement) `(not ,statement))) ,statement))) You use it like this: (defun foo (value predicate) (with-maybe predicate (lambda (x) (maybe (eql x value))))) Macro generates a code which has IF switching between two branches. Branches are made different by different MAYBE local macros defined via MACROLET -- in first branch MAYBE is no-op, so it is vanilla statement. In second branch MAYBE adds NOT to the statement. Unfortunately there is no tool one can use to get fully macroexpanded code (at least I don't know any), but once you'll replace macrolet:ed maybe:s, you'll get exactly function you had wrote yourself: (defun foo (value predicate) (if predicate (lambda (x) (eq x value)) (lambda (x) (not (eq x value))))) NE> (defun foo (predicate value) NE> (eval `(function (lambda (x) NE> (maybe ,predicate (eql x ,value)))))) By the way, if you're generating code anyway, you do not really need macro, you can do this with ordinary function or just construct in-place: (defun foo (predicate value) (eval `(function (lambda (x) ,(let ((code `(eql x, value)) (if predicate code `(not ,code)))))
From: Pascal Costanza on 3 Nov 2009 05:47 Tobias C. Rittweiler wrote: > Barry Margolin <barmar(a)alum.mit.edu> writes: > >> Nicolas Edel <nicolas.edel(a)gmail.com> wrote: >> >>> Nice, indeed. But before I let the implementation decide by itself, I >>> would like to know if there are fundamental differences when calling >>> eval and compile in this context. >> No semantic differences, just performance differences. Compile will >> create a compiled function, eval will create an interpreted function in >> some implementations. > > COMPILED-FUNCTION-P will return T on the first kind, but NIL on the > other kind! Not quite: It may actually return T in some implementations for the second kind. A CL implementation is required to support at least minimal compilation (as per 3.2.2.2 in the HyperSpec), but is not required to support a 'pure' interpreter (as per 3.1 in the HyperSpec) and can actually always perform (at least minimal) compilation. > That's as big semantical change as you can get. ;-) Still not that big. ;) Pascal -- 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: Pascal Costanza on 3 Nov 2009 06:02 Nicolas Edel wrote: > On Nov 3, 9:31 am, Pascal Costanza <p...(a)p-cos.net> wrote: >>> Ok, so I use macro to generate code and then invoke the compiler at >>> runtime. >>> What is best practice for this: eval or compile ? Do they have similar >>> meaning in this context ? >>> (defun foo (predicate value) >>> (eval `(function (lambda (x) >>> (maybe ,predicate (eql x ,value)))))) >>> or >>> (defun foo (predicate value) >>> (compile nil `(lambda (x) >>> (maybe ,predicate (eql x ,value))))) >> The semantics are the same. Which one is better depends on context. If >> you use these functions only one or two times, or so, it's not >> worthwhile to compile them, because compilation creates a considerable >> overhead by itself. If you use them more often, then compilation is >> worthwhile (although I recently heard that in, say, ECL or GCL, >> compilation is almost always prohibitive). >> > > At that time, I don't know if they will be used often. But if they are > to be used in a context such as packet filtering, there will be a slow > startup time but this will be runtime efficient. I wanted to learn how > to make this now to avoid problems at experimentation time. If you want your code to be very sophisticated, you can actually also implement your own version that uses interpreted code by default, counts how often a particular runtime-generated function is called, and after a certain threshold, compiles into a more efficient version (under the assumption that it will continue to be called even more often). Here is a sketch [untested]: (defclass smart-function (funcallable-standard-object) () (:metaclass funcallable-standard-class)) (defparameter *threshold* 10) (defun make-smart-function (body) (let ((fun (make-instance 'smart-function))) (set-funcallable-instance-function fun (let ((counter 0) (funfun (eval body))) (lambda (&rest args) (declare (dynamic-extent args) (when (> (incf counter) *threshold*) (unless (compiled-function-p funfun) (setq funfun (compile nil body))) (set-funcallable-instance-function fun funfun)) (apply funfun args)))) fun)) (defmacro smart-lambda ((&rest args) &body body) `(make-smart-function `(lambda ,args ,@body))) Yes, this requires the CLOS MOP. ;) Pascal -- 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: Nicolas Edel on 3 Nov 2009 07:37 On Nov 3, 6:02 am, Pascal Costanza <p...(a)p-cos.net> wrote: > Nicolas Edel wrote: > > On Nov 3, 9:31 am, Pascal Costanza <p...(a)p-cos.net> wrote: > >>> Ok, so I use macro to generate code and then invoke the compiler at > >>> runtime. > >>> What is best practice for this: eval or compile ? Do they have similar > >>> meaning in this context ? > >>> (defun foo (predicate value) > >>> (eval `(function (lambda (x) > >>> (maybe ,predicate (eql x ,value)))))) > >>> or > >>> (defun foo (predicate value) > >>> (compile nil `(lambda (x) > >>> (maybe ,predicate (eql x ,value))))) > >> The semantics are the same. Which one is better depends on context. If > >> you use these functions only one or two times, or so, it's not > >> worthwhile to compile them, because compilation creates a considerable > >> overhead by itself. If you use them more often, then compilation is > >> worthwhile (although I recently heard that in, say, ECL or GCL, > >> compilation is almost always prohibitive). > > > At that time, I don't know if they will be used often. But if they are > > to be used in a context such as packet filtering, there will be a slow > > startup time but this will be runtime efficient. I wanted to learn how > > to make this now to avoid problems at experimentation time. > > If you want your code to be very sophisticated, you can actually also > implement your own version that uses interpreted code by default, counts > how often a particular runtime-generated function is called, and after a > certain threshold, compiles into a more efficient version (under the > assumption that it will continue to be called even more often). > > Here is a sketch [untested]: > > (defclass smart-function (funcallable-standard-object) () > (:metaclass funcallable-standard-class)) > > (defparameter *threshold* 10) > > (defun make-smart-function (body) > (let ((fun (make-instance 'smart-function))) > (set-funcallable-instance-function > fun > (let ((counter 0) (funfun (eval body))) > (lambda (&rest args) > (declare (dynamic-extent args) > (when (> (incf counter) *threshold*) > (unless (compiled-function-p funfun) > (setq funfun (compile nil body))) > (set-funcallable-instance-function fun funfun)) > (apply funfun args)))) > fun)) > > (defmacro smart-lambda ((&rest args) &body body) > `(make-smart-function `(lambda ,args ,@body))) > > Yes, this requires the CLOS MOP. ;) > Looks nice, but I am not shure I am already comfortable enough at Lisp programing to use such tricks. Thanks anyway ;) :Nicolas
From: Juanjo on 3 Nov 2009 08:07 On Nov 3, 9:31 am, Pascal Costanza <p...(a)p-cos.net> wrote: > Nicolas Edel wrote: > > On Nov 2, 7:24 pm, "Captain Obvious" <udode...(a)users.sourceforge.net> > > wrote: > >> NE> 1. Why ? > > >> Because macros work at macroexpansion time, NOT > >> runtime. > > >> NE> 2. How to use macros for generating the lambdas ? > > >> You can use macro to generate a code which generates lambda, > >> for example. > > > Ok, so I use macro to generate code and then invoke the compiler at > > runtime. > > What is best practice for this: eval or compile ? Do they have similar > > meaning in this context ? > > > (defun foo (predicate value) > > (eval `(function (lambda (x) > > (maybe ,predicate (eql x ,value)))))) > > > or > > > (defun foo (predicate value) > > (compile nil `(lambda (x) > > (maybe ,predicate (eql x ,value))))) > > The semantics are the same. Which one is better depends on context. If > you use these functions only one or two times, or so, it's not > worthwhile to compile them, because compilation creates a considerable > overhead by itself. If you use them more often, then compilation is > worthwhile (although I recently heard that in, say,ECLor GCL, > compilation is almost always prohibitive). It is not "almost always prohibitive". The cost is basically executing a C compiler. And that is worthwhile if you need the function often and if the function it is low level enough that it profits from compilation. What is prohibitive is to compile using C a function that you are going to use only once, and do it for every use. The alternative then is to use bytcompiled functions, which do save some time, but are not as efficient as natively compiled ones. You can always do this, without much hassle. One cheap way is to coerce a lambda form to a function type. > (coerce '(lambda (x) (1+ x)) 'function) #<bytecompiled-function 0000000102a301e0> > (funcall * 2) 3 Juanjo
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Article about lisp and array languages Next: lisp, java and evolution of types |