Hi. I'm new to serious lisp programming (I've fiddled with emacs lisp for a while, though), and I'm trying to create an automatically defined function. I've generated an appropriate function body, but I can't get the incantation right to turn it into a function.
Now, I want to make a function symbol, auto-func, that takes two arguments and returns the result of binding them into arg1 and arg2, and executing func-body on them. That is:
Can anybody hit me with a clue stick about this? (I'm using CMUCL.)
Thanks! -- header address is anti-spamified. use caution when replying by email to <d...@loopback.mersenne.com> because my real address omits the hostname.
<postmas...@loopback.mersenne.com> wrote: > Hi. I'm new to serious lisp programming (I've fiddled with emacs lisp > for a while, though), and I'm trying to create an automatically defined > function. I've generated an appropriate function body, but I can't get > the incantation right to turn it into a function.
> Now, I want to make a function symbol, auto-func, that takes two > arguments and returns the result of binding them into arg1 and arg2, and > executing func-body on them. That is:
dave madden <postmas...@loopback.mersenne.com> writes: > Hi. I'm new to serious lisp programming (I've fiddled with emacs lisp > for a while, though), and I'm trying to create an automatically defined > function. I've generated an appropriate function body, but I can't get > the incantation right to turn it into a function.
> Now, I want to make a function symbol, auto-func, that takes two > arguments and returns the result of binding them into arg1 and arg2, and > executing func-body on them. That is:
> Can anybody hit me with a clue stick about this? (I'm using CMUCL.)
The normal thing to do, of course, would be
(defun auto-func (x y) (+ x y))
but I assume you're saying you want func-body to be a variable that auto-func uses.
First know that it is bad style to use dynamic variables without *'s on each end of the name unless you have some very important reason to the contrary. And variables are lexical by default, so let's assume you've arranged to declare the specialness (i.e., dynamic nature) of the variable using defvar or defparameter or something like that, as in:
(defvar *func-body* (generate-2-arg-func))
and let's further assume that this yielded (+ *arg1* *arg2*) just for clarity of anyone later trying to debug the system. (Better yet, you might want it to yield:
if you want generate-2-arg-func to be side-effect free and not polluting your special variable environment as a side-effect of calling it with debugging args. Anyway, all that given, you probably already defined generate-2-arg-func by doing something vaguely like:
(defun generate-args (n-args) (loop for i below n-args collect (intern (format nil "*ARG~D*" i))))
So using the same generate-args function that you surely made as a subroutine because you knew it would be so useful (wink), you would now write:
(defun auto-func (&rest args) (let ((n-args (length args))) (progv (generate-args n-args) args ;bind n ars to n args (eval *func-body*)))) ; done in the environment of the special bindings
-- -- --
The other way to write this is not to use specials at all and to compose it only with lexicals, but that involves promoting some function from text to a real function using EVAL of a LAMBDA expression, or using COMPILE.
But all this really begs the question of why on earth you're trying to do this in this detached way. Can you back up from your problem and explain why you would ever have a situation in which you knew the function body and the args in so detached a way? It's possible to handle, as you've seen here, but it doesn't sound very much like any likely real-world scenario.
(It doesn't sound like homework either, so hopefully my doing a fully elaborated answer isn't spoiling anything.)
-- -- ---
Notes:
* It doesn't matter that you're using CMUCL. This kind of stuff is identical in all implementations of CL.
* I didn't test any of the above code, so there might be bugs. I was on my way out the door and only had 5 minutes to write this. Hope I didn't screw up anything major. I think the overall structure should be right. But, as they say, caveat emptor...
<postmas...@loopback.mersenne.com> wrote: >Hi. I'm new to serious lisp programming (I've fiddled with emacs lisp >for a while, though), and I'm trying to create an automatically defined >function. I've generated an appropriate function body, but I can't get >the incantation right to turn it into a function.
>Now, I want to make a function symbol, auto-func, that takes two >arguments and returns the result of binding them into arg1 and arg2, and >executing func-body on them. That is:
> > Now, I want to make a function symbol, auto-func, that takes two > > arguments and returns the result of binding them into arg1 and arg2, and > > executing func-body on them. That is:
(Plus a couple of other people sent useful information.)
Thanks very much! The "compile" version worked great, and is simple enough that I can (almost :-) understand what's going on. It looks like I'll have to go over the quoting and unquoting mechanisms more carefully...I'm aware of the "," operator to unquote in macros, but I never needed it before and don't really understand how it works yet.
To respond to the questions about what I'm doing, I'm *trying* to work through the even-parity-3 example in Koza's _Genetic_Programming_III_ book. Abstractly, it makes plenty of sense, but I'm trying to code it up and reproduce the runs.
So, I've started by making a random code generator, which produces a parameterized executable form based on a list of initial terminals and functions. And, now that I can turn these forms into real functions, I'm going to make a bunch of them and call them with various arguments to see which ones come closest to producing the results I want. Then, I'll work out the combination and mutation code, mate the best members of the initial population, and check out their offspring. And so on.
Thanks again, d. -- header address is anti-spamified. use caution when replying by email to <d...@loopback.mersenne.com> because my real address omits the hostname.
In article <39FC7F11.48BC4...@loopback.mersenne.com>, dave madden
<postmas...@loopback.mersenne.com> wrote: > Thanks very much! The "compile" version worked great, and is simple > enough that I can (almost :-) understand what's going on. It looks like > I'll have to go over the quoting and unquoting mechanisms more > carefully...I'm aware of the "," operator to unquote in macros, but I > never needed it before and don't really understand how it works yet.
It has nothing to with Macros - other than that it is being used in macros a lot. It is simply a notation for lists:
(list '+ pi pi)
is the same as:
`(+ ,pi ,pi)
You can think of it as follows:
In (list '+ pi pi) you have write the list constructing function (here LIST) and you have to quote the constants (here the symbol +).
In `(+ ,pi ,pi) you write a list template and everything is constant - except in the places after the minus characters - so you are unquoting (-> forcing the evaluation at these places). So it is kind of opposite from the above.
* Rainer Joswig <jos...@corporate-world.lisp.de> | It is simply a notation for lists: | | (list '+ pi pi) | | is the same as: | | `(+ ,pi ,pi) | | You can think of it as follows: | | In (list '+ pi pi) you have write the list constructing function | (here LIST) and you have to quote the constants (here the symbol +). | | In `(+ ,pi ,pi) you write a list template and everything is constant | - except in the places after the minus characters - so you are | unquoting (-> forcing the evaluation at these places). So it is kind | of opposite from the above.
Except that the result of the backquote form is to be treated as a constant. The list structure may not be modified as it might be shared with other list structures.
(list ...) constructs a list at run-time. `(...) constructs at least parts of the list at read-time.
#:Erik -- Does anyone remember where I parked Air Force One? -- George W. Bush