From: Mirko on
On Apr 5, 12:49 pm, "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de>
wrote:
> On 5 Apr., 18:24, Tamas K Papp <tkp...(a)gmail.com> wrote:
>
>
>
> > On Mon, 05 Apr 2010 08:27:52 -0700, Mirko wrote:
> > > I have a utility that may need to do some unit conversions.  I would
> > > like to specify the conversion rules as an association list:
>
> > > ((a do-something) (b do-something-else) ... etc)
>
> > > Now, I could specify `do-something' as #'(lambda (arg)
> > >       (* arg 5))
>
> > > and so on.  All the lambda's have the same format #'(lambda (arg)
> > > (...)), only the ellipsis changing from item to item
>
> > > Specifying the lambdas works, but makes the a-list hard to read. Instead
> > > I would like it to contain the bodies of the lambda's.
>
> > > ((a (* arg 5)) (b (/ arg 12)) ... etc)
>
> > > So, the question is how to compile those bodies (I am not sure `compile'
> > > is the right term - I just want to get an `executable' lambda out of
> > > these).
>
> > > Right now, I am compiling via macros:
>
> > > (defmacro build (sym)
> > >   `(lambda (arg)
> > >      ,(second (assoc sym +table+)))
>
> > > and then
>
> > > (funcall (build a) arg)
>
> > > will execute my function.
>
> > > But I am wondering if I am misusing the macros here, and if there is
> > > something more direct
>
> > I think that this is OK, but I would do it in a slightly different
> > way.  You want convenient syntax for two things: defining new
> > conversions, and performing them by name.  I would just use a macro
> > for the first and a generic function for the second, eg:
>
> > (defgeneric do-conversion (name arg)
> >   (:documentation "Perform the named conversion on ARG."))
>
> > (defmacro define-conversion (name &body body)
> >   `(defmethod do-conversion ((name (eql ',name)) arg)
> >      ,@body))
>
> > (define-conversion m->km (/ arg 1000))
> > (define-conversion km->m (* arg 1000))
>
> > ;; example:
> > (do-conversion 'm->km 1000)
>
> > Best,
>
> > Tamas
>
> How about this one without generic functions.
> Dispatch is done by symbol lookup if necessary.
>
> (defparameter *table*
>   '((m->km (/ arg 1000))
>     (km->m (* arg 1000))))
>
> (defmacro defconv (var conversions)
>   (when (symbolp conversions)
>     (setf conversions (symbol-value conversions)))
>   `(progn ,@(loop for (name calculation) in conversions
>                   collect `(defun ,name (,var)
>                              ,calculation))))
>
> (defconv arg *table*)
>
> (m->km 4)
>
> (funcall 'm->km 4)
>
> (defun convert (how what)
>   (funcall how what))
>
> (convert 'm->km 4)

Well, thank you both, but that is not what I am looking for.

(and my previous example breaks down now).

Suppose I have this list: (* arg 4).

how can I convert it into something that I can call with (mapcar #'foo
some-list) on the fly?

So, I do not want to define this function using defun. I want a
lambda.

Thanks,

Mirko
From: Tamas K Papp on
On Mon, 05 Apr 2010 11:03:45 -0700, Mirko wrote:

> On Apr 5, 12:49 pm, "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de>
> wrote:
>> On 5 Apr., 18:24, Tamas K Papp <tkp...(a)gmail.com> wrote:
>>
>>
>>
>> > On Mon, 05 Apr 2010 08:27:52 -0700, Mirko wrote:
>> > > I have a utility that may need to do some unit conversions.  I
>> > > would like to specify the conversion rules as an association list:
>>
>> > > ((a do-something) (b do-something-else) ... etc)
>>
>> > > Now, I could specify `do-something' as #'(lambda (arg)
>> > >       (* arg 5))
>>
>> > > and so on.  All the lambda's have the same format #'(lambda (arg)
>> > > (...)), only the ellipsis changing from item to item
>>
>> > > Specifying the lambdas works, but makes the a-list hard to read.
>> > > Instead I would like it to contain the bodies of the lambda's.
>>
>> > > ((a (* arg 5)) (b (/ arg 12)) ... etc)
>>
>> > > So, the question is how to compile those bodies (I am not sure
>> > > `compile' is the right term - I just want to get an `executable'
>> > > lambda out of these).
>>
>> > > Right now, I am compiling via macros:
>>
>> > > (defmacro build (sym)
>> > >   `(lambda (arg)
>> > >      ,(second (assoc sym +table+)))
>>
>> > > and then
>>
>> > > (funcall (build a) arg)
>>
>> > > will execute my function.
>>
>> > > But I am wondering if I am misusing the macros here, and if there
>> > > is something more direct
>>
>> > I think that this is OK, but I would do it in a slightly different
>> > way.  You want convenient syntax for two things: defining new
>> > conversions, and performing them by name.  I would just use a macro
>> > for the first and a generic function for the second, eg:
>>
>> > (defgeneric do-conversion (name arg)
>> >   (:documentation "Perform the named conversion on ARG."))
>>
>> > (defmacro define-conversion (name &body body)
>> >   `(defmethod do-conversion ((name (eql ',name)) arg)
>> >      ,@body))
>>
>> > (define-conversion m->km (/ arg 1000)) (define-conversion km->m (*
>> > arg 1000))
>>
>> > ;; example:
>> > (do-conversion 'm->km 1000)
>>
>> > Best,
>>
>> > Tamas
>>
>> How about this one without generic functions. Dispatch is done by
>> symbol lookup if necessary.
>>
>> (defparameter *table*
>>   '((m->km (/ arg 1000))
>>     (km->m (* arg 1000))))
>>
>> (defmacro defconv (var conversions)
>>   (when (symbolp conversions)
>>     (setf conversions (symbol-value conversions)))
>>   `(progn ,@(loop for (name calculation) in conversions
>>                   collect `(defun ,name (,var)
>>                              ,calculation))))
>>
>> (defconv arg *table*)
>>
>> (m->km 4)
>>
>> (funcall 'm->km 4)
>>
>> (defun convert (how what)
>>   (funcall how what))
>>
>> (convert 'm->km 4)
>
> Well, thank you both, but that is not what I am looking for.
>
> (and my previous example breaks down now).
>
> Suppose I have this list: (* arg 4).
>
> how can I convert it into something that I can call with (mapcar #'foo
> some-list) on the fly?
>
> So, I do not want to define this function using defun. I want a
> lambda.

Maybe I am not getting the question, but if you just want a lambda,
you could use a lambda. If you want to drop the arg to make it more
compact, you could do something like

(defmacro conv (&body body) `(lambda (arg) ,@body))

(funcall (conv (* arg 4)) 3)

Tamas
From: Thomas A. Russ on
Mirko <mirko.vukovic(a)gmail.com> writes:

> On Apr 5, 12:49�pm, "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de>
> > How about this one without generic functions.
> > Dispatch is done by symbol lookup if necessary.
> >
> > (defparameter *table*
> > � '((m->km (/ arg 1000))
> > � � (km->m (* arg 1000))))
> >
> > (defmacro defconv (var conversions)
> > � (when (symbolp conversions)
> > � � (setf conversions (symbol-value conversions)))
> > � `(progn ,@(loop for (name calculation) in conversions
> > � � � � � � � � � collect `(defun ,name (,var)
> > � � � � � � � � � � � � � � �,calculation))))
> >
> > (defconv arg *table*)
> >
> > (m->km 4)
> >
> > (funcall 'm->km 4)
> >
> > (defun convert (how what)
> > � (funcall how what))
> >
> > (convert 'm->km 4)
>
> Well, thank you both, but that is not what I am looking for.
>
> (and my previous example breaks down now).
>
> Suppose I have this list: (* arg 4).
>
> how can I convert it into something that I can call with (mapcar #'foo
> some-list) on the fly?

Any of the solutions that produce the lambda function will work for
this. So, as long as you had a way of looking up the function, it
should work.

Suppose you had a table of (key . function) forms, and this funciton:

(defun get-conversion-function (key)
(cdr (assoc key *table)))

you could then simply call

(mapcar (get-conversion-function 'foo) some-list)

MAPCAR evaluates its arguments (like all functions), so you can compute
the function to return. It will just work like you want it to.






--
Thomas A. Russ, USC/Information Sciences Institute











From: Rainer Joswig on
In article
<f853a030-f395-481c-85a0-e3d7d2bd312d(a)y17g2000yqd.googlegroups.com>,
Mirko <mirko.vukovic(a)gmail.com> wrote:


> Well, thank you both, but that is not what I am looking for.
>
> (and my previous example breaks down now).
>
> Suppose I have this list: (* arg 4).
>
> how can I convert it into something that I can call with (mapcar #'foo
> some-list) on the fly?
>
> So, I do not want to define this function using defun. I want a
> lambda.
>
> Thanks,
>
> Mirko

The typical question is: do you really want to do that and not have pre-compiled functions?


If yes:

CL-USER 49 > '(* arg 4)
(* ARG 4)

CL-USER 50 > (append '(lambda (arg)) (list '(* arg 4)))
(LAMBDA (ARG) (* ARG 4))

CL-USER 51 > (eval (append '(lambda (arg)) (list '(* arg 4))))
#<anonymous interpreted function 4060000BB4>

CL-USER 52 > (compile nil (append '(lambda (arg)) (list '(* arg 4))))
#<Function 11 4060000DFC>
NIL
NIL

CL-USER 53 > (mapcar (compile nil (append '(lambda (arg)) (list '(* arg 4)))) '(1 2 3 4))
(4 8 12 16)

--
http://lispm.dyndns.org/
From: Mirko on
On Apr 5, 3:23 pm, Rainer Joswig <jos...(a)lisp.de> wrote:
> In article
> <f853a030-f395-481c-85a0-e3d7d2bd3...(a)y17g2000yqd.googlegroups.com>,
>
>
>
>  Mirko <mirko.vuko...(a)gmail.com> wrote:
> > Well, thank you both, but that is not what I am looking for.
>
> > (and my previous example breaks down now).
>
> > Suppose I have this list: (* arg 4).
>
> > how can I convert it into something that I can call with (mapcar #'foo
> > some-list) on the fly?
>
> > So,  I do not want to define this function using defun.  I want a
> > lambda.
>
> > Thanks,
>
> > Mirko
>
> The typical question is: do you really want to do that and not have pre-compiled functions?
>
> If yes:
>
> CL-USER 49 > '(* arg 4)
> (* ARG 4)
>
> CL-USER 50 > (append '(lambda (arg)) (list '(* arg 4)))
> (LAMBDA (ARG) (* ARG 4))
>
> CL-USER 51 > (eval (append '(lambda (arg)) (list '(* arg 4))))
> #<anonymous interpreted function 4060000BB4>
>
> CL-USER 52 > (compile nil (append '(lambda (arg)) (list '(* arg 4))))
> #<Function 11 4060000DFC>
> NIL
> NIL
>
> CL-USER 53 > (mapcar (compile nil (append '(lambda (arg)) (list '(* arg 4)))) '(1 2 3 4))
> (4 8 12 16)
>
> --http://lispm.dyndns.org/

I evidently missed stating the crucial part. I wanted run-time
compilation - the lambda will exist only briefly.

This is really a matter of preference. I could have defined all the
conversion functions a-priori form the stored conversion definitions,
but I felt that would be an overkill. I have multiple variable types,
and multiple possible units

Pascal's post pointed me to `compile', and that has done the trick.
Now I am off to carefully read the hyperspec section.


Thanks.