Re: Rebuilding functions at run-time



On Wed, 15 Apr 2009 22:44:27 +0200, Francisco Vides Fernández wrote:

Tamas K Papp wrote:

On Wed, 15 Apr 2009 21:34:36 +0200, Francisco Vides Fernández wrote:

Hello

Let's suppose that I have a file named "foo" with just one word "bar".
I've written a macro, deftemplate, that expands to something like:

(deftemplate foo () #p"foo")
=>
(defun foo ()
(write-string "bar"))

So far, so good. Now I'd like to add some code that, when the contents
of "foo" changes to "baz", should rebind #'foo to

(lambda ()
(write-string "baz"))

But, AFAIK, this can't be a macro, since it will be expanded at macro-
expansion time, so the function it compiles will depend on the
contents of the file at expansion time.

I guess I could use eval, but everybody says is evil (honestly, I
still can't see why).

Another option could be compile, I suppose.

What is the Lisp Way to do this? (if there is such)

It is not entirely clear what you are trying to achieve, but you could
use closures.

(defun make-function (initial-string)
(let ((string initial-string))
(list (lambda () ; writes string
(write-string string))
(lambda (new-string) ; sets string
(setf string new-string)))))

(defparameter *foo* (make-function "foo")) (funcall (first *foo*)) ;
"foo"
(funcall (second *foo*) "bar") ; which you can read from a file, etc
(funcall (first *foo*)) ; "bar"

I'm afraid that I oversimplified the problem. Let's try again (please be
patient :)) If file 'foo' contained one string in one line then I want
to generate the function

(lambda ()
(write-string "bar"))

But if contains two strings in two separated lines then I'd like to
generate

(lambda ()
(write-string "bar")
(write-string "baz"))

So, I think that the closures solution wouldn't work for me, as I can
generate the lambda function body only by using a macro, or evaling or
compiling. Am I right?

You can always construct such forms and then compile them (see compile
and eval). But that is the most un-Lispy way of doing things you can
imagine.

You are telling us _how_ you want to do something, but that is clearly
wrong. Tell us _what_ you want to do. Closures provide the
functionality you need, and are idiomatic in Lisp.

Tamas
.



Relevant Pages

  • Re: Compile time string literal substitution to external data file
    ... and these string literals may expose sensitive information ... > I want to use the compile time macros for file name, line number, and ... I'd put a macro and a function like: ...
    (microsoft.public.vc.language)
  • Re: Rebuilding functions at run-time
    ... (deftemplate foo () ... (defun foo () ... But, AFAIK, this can't be a macro, since it will be expanded at macro- ... (let ((string initial-string)) ...
    (comp.lang.lisp)
  • Re: Whats up with Scheme macros?
    ... "Defines name as a macro by associating a macro function with that name ... (defmacro foo () ... But the value of x is needed at compile time, ... they happen for a reason. ...
    (comp.lang.lisp)
  • Re: silly: "spel" instead of "macro"
    ... but the macro form could not have. ... > Couldn't another implementation decide to compile before executing ... an instance of fooclass does not have a readable print ... 0-> The symbol FOO ...
    (comp.lang.lisp)
  • Re: Lisp2Perl - Lisp to perl compiler
    ... > because the foo macro doesn't see the a reference. ... Now at compile time, if you encounter a DEFDYNFUN form, ... At some point, you decide to recompile from scratch, ...
    (comp.lang.lisp)