From: Francisco Vides =??B?RmVybsOhbmRleg==?=
Subject: Rebuilding functions at run-time
Date: 
Message-ID: <xuOdncGSprBSq3vU4p2dnAA@giganews.com>
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)

Thanks in advance

-- 
+-----------------
| Francisco Vides Fernández <······@dedaloingenieros.com>
| Director técnico.
| Dédalo Ingenieros http://www.dedaloingenieros.com/
| PGP: http://pgp.rediris.es:11371/pks/lookup?op=index&search=0xB1299C15
+------

From: namekuseijin
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <gs5gqv$25cr$1@adenine.netfront.net>
Francisco Vides Fernández escreveu:
> 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"))

sounds like a C++ template metaprogrammer. :)

-- 
a game sig: http://tinyurl.com/d3rxz9
From: Tamas K Papp
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <74mui6F14eg9rU1@mid.individual.net>
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"

Or if you just need one of these, you can store the string in special
variable.

HTH,

Tamas
From: Francisco Vides =??B?RmVybsOhbmRleg==?=
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <VvedncYRD5Sz2nvU4p2dnAA@giganews.com>
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?

-- 
+-----------------
| Francisco Vides Fernández <······@dedaloingenieros.com>
| Director técnico.
| Dédalo Ingenieros http://www.dedaloingenieros.com/
| PGP: http://pgp.rediris.es:11371/pks/lookup?op=index&search=0xB1299C15
+------
From: ·····@sherbrookeconsulting.com
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <30258d5e-e225-4b9b-b754-0da62f3fbce3@q16g2000yqg.googlegroups.com>
On Apr 15, 4:44 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
<······@dedaloingenieros.com> wrote:
[...]

> 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?

I don't see why. Do something like (untested)

(defun make-closures-from-file (name)
  (with-open-file (s name)
    (let ((strings
            (loop
               :for string := (read-line s nil s)
               :until (eq string s)
               :collect strings)))
      (lambda ()
         (mapc #'write-string strings)))

You don't need to use any sort of macro to iterate over that list;
just use a higher-order function.

Cheers,
Pillsy
From: gugamilare
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <bef93844-6c45-4122-8bd4-4ca9042aa1cf@37g2000yqp.googlegroups.com>
On 15 abr, 17:44, Francisco Vides =??B?RmVybsOhbmRleg==?=
<······@dedaloingenieros.com> 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?

Why not?

(defun make-function (string-list)
  (list (lambda ()                    ; writes string list
          (mapcar #'write-string string-list))
        (lambda (new-string-list)          ; sets string list
          (setf string-list new-string-list))))

cl-user> (defvar funcs (make-function '("foo" "boo")))
funcs
cl-user> (funcall (first funcs))
fooboo
("foo" "boo")
cl-user> (funcall (second funcs) (list "bar" "baz" "quux"))
("bar" "baz" "quux")
cl-user> (funcall (first funcs))
barbazquux
("bar" "baz" "quux")

You can read the list from the file.
From: Tamas K Papp
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <74n21eF13mcagU1@mid.individual.net>
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
From: Pascal J. Bourguignon
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <87tz4pfvnt.fsf@galatea.local>
Francisco Vides =??B?RmVybsOhbmRleg==?= <······@dedaloingenieros.com> writes:

> 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"))

Are you sure that's what you want? 
This function will write: barbaz and return "baz".
Is this what you want?


In the meantime I'll bet that what you want is to have a function that writes:
bar
baz
and returns nothing, instead.

(defun make-copy-file-content-to-standard-output-function (file)
   (lambda ()
     (with-open-file (input file)
        (loop for line = (read-line input nil nil)
              while line
              do (write-line line)))
     (values)))

(defparameter *fun* (make-copy-file-content-to-standard-output-function "/tmp/test"))
(progn
  (with-open-file (out "/tmp/test" :direction :output
                       :if-exists :supersede
                       :if-does-not-exist :create)
    (write-line "foo" out))
  (format t "~2%=== First: ~%")
  (funcall *fun*)

  (with-open-file (out "/tmp/test" :direction :output
                       :if-exists :append)
    (write-line "bar" out))
  (format t "~2%=== Second: ~%")
  (funcall *fun*)

  (with-open-file (out "/tmp/test" :direction :output
                       :if-exists :append)
    (write-line "baz" out))
  (format t "~2%=== Third: ~%")
  (funcall *fun*))

prints:

=== First: 
foo


=== Second: 
foo
bar


=== Third: 
foo
bar
baz


-- 
__Pascal Bourguignon__
From: Alessio Stalla
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <3f4c7af5-2a4c-471e-b1f4-9e0b4f146594@r8g2000yql.googlegroups.com>
On Apr 15, 10:44 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
<······@dedaloingenieros.com> 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?

If I have understood it correctly, you are effectively designing a
"language" whose source is a list of lines of text, and whose
semantics are simply to print those lines (probably there's more, but
it's not important right now); and you want to "compile" it to Lisp,
that is, given a source file in your "language" you want to translate
it to Lisp code implementing its semantics (and maybe then use the
built-in Lisp compiler to further compile it to bytecode/machine code/
whatever your Lisp implementation compiles to).

The idiomatic way to do what you want to do in Lisp is to write a
parser for your language's syntax, that outputs s-expressions; then
manipulate the s-expressions to generate valid Lisp code (usually by
using macros that transform those s-expressions into lower-level Lisp
code); then, evaluate or compile the generated code.
Your case is (or seems to be) particularly simple because your
"parser" (that is, deftemplate) only needs to read its input line-by-
line, and your generated s-expressions need no further processing
(because it's just a list of calls to the "print" function). The next
step, evaluation or compilation, is achieved using eval or compile
directly, or using higher-level operators that actually use eval,
compile or something equivalent under the hood. e.g. your use of defun
in deftemplate will compile code at definition time in certain
implementations, or evaluate it at invocation time in others; and will
handle redefinition correctly in all implementations, that is, code
calling your function will call the updated version after you call
defun again, except if your function has been inlined or if someone
has saved a "pointer" to it somewhere (e.g. using the "function"
special operator, or its shortcut syntax #').
Use of eval/compile in these cases is not necessarily "evil", although
usually it's better to deal with functions rather than evalutating raw
code, but you're already doing that.

In short: you want to update the "foo" function whenever the contents
of the "foo" file change? Just call (deftemplate foo () #p"foo") again
every time the file changes! ;)

hth,
Alessio
From: Francisco Vides =??B?RmVybsOhbmRleg==?=
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <WcadnfYZpKuapHrURVn_vwA@giganews.com>
Alessio Stalla wrote:

> On Apr 15, 10:44 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
> <······@dedaloingenieros.com> 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?
> 
> If I have understood it correctly, you are effectively designing a
> "language" whose source is a list of lines of text, and whose
> semantics are simply to print those lines (probably there's more, but
> it's not important right now); and you want to "compile" it to Lisp,
> that is, given a source file in your "language" you want to translate
> it to Lisp code implementing its semantics (and maybe then use the
> built-in Lisp compiler to further compile it to bytecode/machine code/
> whatever your Lisp implementation compiles to).

That's it! You hit the nail. I guess I have to get the proper vocabulary :) 
In fact, what I'm trying something like Lisp inside text, for creating and 
filling generic text templates (maybe html but not limited to).

> The idiomatic way to do what you want to do in Lisp is to write a
> parser for your language's syntax, that outputs s-expressions; 
> then manipulate the s-expressions to generate valid Lisp code (usually by
> using macros that transform those s-expressions into lower-level Lisp
> code); then, evaluate or compile the generated code.
> Your case is (or seems to be) particularly simple because your
> "parser" (that is, deftemplate) only needs to read its input line-by-
> line, and your generated s-expressions need no further processing
> (because it's just a list of calls to the "print" function). The next
> step, evaluation or compilation, is achieved using eval or compile
> directly, or using higher-level operators that actually use eval,
> compile or something equivalent under the hood. e.g. your use of defun
> in deftemplate will compile code at definition time in certain
> implementations, or evaluate it at invocation time in others; and will
> handle redefinition correctly in all implementations, that is, code
> calling your function will call the updated version after you call
> defun again, except if your function has been inlined or if someone
> has saved a "pointer" to it somewhere (e.g. using the "function"
> special operator, or its shortcut syntax #').

> Use of eval/compile in these cases is not necessarily "evil", although
> usually it's better to deal with functions rather than evalutating raw
> code, but you're already doing that.

Ok, thanks a lot. I plan to work on it a bit more then I will release this 
small utility.

> In short: you want to update the "foo" function whenever the contents
> of the "foo" file change? Just call (deftemplate foo () #p"foo") again
> every time the file changes! ;)

Yes, that works, but it would be more nice and dynamic if the function do 
itself  (and also would prove the power of Lisp, I'm trying to push mi 
limits a bit here and learn something valuable)

Many thanks to everybody

-- 
+-----------------
| Francisco Vides Fernández <······@dedaloingenieros.com>
| Director técnico.
| Dédalo Ingenieros http://www.dedaloingenieros.com/
| PGP: http://pgp.rediris.es:11371/pks/lookup?op=index&search=0xB1299C15
+------
From: Alessio Stalla
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <8f6a2074-f2ed-4863-a6df-9975a5bbea0e@j8g2000yql.googlegroups.com>
On Apr 16, 3:56 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
<······@dedaloingenieros.com> wrote:
> Alessio Stalla wrote:
> > In short: you want to update the "foo" function whenever the contents
> > of the "foo" file change? Just call (deftemplate foo () #p"foo") again
> > every time the file changes! ;)
>
> Yes, that works, but it would be more nice and dynamic if the function do
> itself  (and also would prove the power of Lisp, I'm trying to push mi
> limits a bit here and learn something valuable)

that's not hard:

(make-template #p"foo") ==> '((print "bar") (print "baz")) ;the
"parser"

(compile-template template) ==> '(lambda () (print "bar") (print
"baz")) ;the "compiler"

"parser" and "compiler" could be a single function, I'm presenting
them as different ones for clarity.

(deftemplate foo #p"foo")

expands to

(defun foo ()
  (when (template-needs-updating-p 'foo #p"foo")
    (setf (template-function 'foo)
          (compile nil (compile-template (make-template #p"foo")))))
  (funcall (template-function 'foo)))

This is just a sketch, of course. Template-function can be stored e.g.
in an hash-map, or in foo's property list. I'll leave to your fantasy
how to implement template-needs-updating-p ;)

Ale
From: Zach Beane
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <m3hc0omwa6.fsf@unnamed.xach.com>
Alessio Stalla <·············@gmail.com> writes:

> On Apr 16, 3:56 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
> <······@dedaloingenieros.com> wrote:
>> Alessio Stalla wrote:
>> > In short: you want to update the "foo" function whenever the contents
>> > of the "foo" file change? Just call (deftemplate foo () #p"foo") again
>> > every time the file changes! ;)
>>
>> Yes, that works, but it would be more nice and dynamic if the function do
>> itself  (and also would prove the power of Lisp, I'm trying to push mi
>> limits a bit here and learn something valuable)
>
> that's not hard:
>
> (make-template #p"foo") ==> '((print "bar") (print "baz")) ;the
> "parser"
>
> (compile-template template) ==> '(lambda () (print "bar") (print
> "baz")) ;the "compiler"
>
> "parser" and "compiler" could be a single function, I'm presenting
> them as different ones for clarity.
>
> (deftemplate foo #p"foo")
>
> expands to
>
> (defun foo ()
>   (when (template-needs-updating-p 'foo #p"foo")
>     (setf (template-function 'foo)
>           (compile nil (compile-template (make-template #p"foo")))))
>   (funcall (template-function 'foo)))
>
> This is just a sketch, of course. Template-function can be stored e.g.
> in an hash-map, or in foo's property list. I'll leave to your fantasy
> how to implement template-needs-updating-p ;)

There's no need to involve the compiler at all:

  (defun make-template-function (file)
    (let ((lines (read-lines file)))
      (lambda ()
        (dolist (line lines)
          (print line)))))

CL-PPCRE and HTML-TEMPLATE do something like this (but much more
sophisticated). Not an EVAL or COMPILE to be found.

http://xach.livejournal.com/131456.html has a bit of stuff I wrote a
while ago on the topic.

Zach
From: Alessio Stalla
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <9d3fe1c9-7999-45e6-adbc-62c3805a8f0c@w40g2000yqd.googlegroups.com>
On Apr 16, 5:51 pm, Zach Beane <····@xach.com> wrote:
> Alessio Stalla <·············@gmail.com> writes:
> > On Apr 16, 3:56 pm, Francisco Vides =??B?RmVybsOhbmRleg==?=
> > <······@dedaloingenieros.com> wrote:
> >> Alessio Stalla wrote:
> >> > In short: you want to update the "foo" function whenever the contents
> >> > of the "foo" file change? Just call (deftemplate foo () #p"foo") again
> >> > every time the file changes! ;)
>
> >> Yes, that works, but it would be more nice and dynamic if the function do
> >> itself  (and also would prove the power of Lisp, I'm trying to push mi
> >> limits a bit here and learn something valuable)
>
> > that's not hard:
>
> > (make-template #p"foo") ==> '((print "bar") (print "baz")) ;the
> > "parser"
>
> > (compile-template template) ==> '(lambda () (print "bar") (print
> > "baz")) ;the "compiler"
>
> > "parser" and "compiler" could be a single function, I'm presenting
> > them as different ones for clarity.
>
> > (deftemplate foo #p"foo")
>
> > expands to
>
> > (defun foo ()
> >   (when (template-needs-updating-p 'foo #p"foo")
> >     (setf (template-function 'foo)
> >           (compile nil (compile-template (make-template #p"foo")))))
> >   (funcall (template-function 'foo)))
>
> > This is just a sketch, of course. Template-function can be stored e.g.
> > in an hash-map, or in foo's property list. I'll leave to your fantasy
> > how to implement template-needs-updating-p ;)
>
> There's no need to involve the compiler at all:
>
>   (defun make-template-function (file)
>     (let ((lines (read-lines file)))
>       (lambda ()
>         (dolist (line lines)
>           (print line)))))
>
> CL-PPCRE and HTML-TEMPLATE do something like this (but much more
> sophisticated). Not an EVAL or COMPILE to be found.
>
> http://xach.livejournal.com/131456.html has a bit of stuff I wrote a
> while ago on the topic.

Hmm yes, that's a very valuable piece of advice! Basically you do not
generate new code each time from your input data, rather you combine
preexisting (and possibly precompiled!) pieces of code, based on your
input data. That way, you never call eval/compile - it gets called
when your system is first loaded/compiled, and never again.

I have a couple of questions about this interesting approach (I hope
this is not too off-topic).

First, how would you handle the presence of regular Lisp code
intermixed with your language's code? (e.g. in your string-matcher
example, allowing the presence of both string literals and Lisp
expressions that produce strings). I guess in this case you have no
other option besides eval/compile, or am I missing something? (this is
not a critique of your technique, I'm just wondering).

The second question is less relevant, but more complicated, and I'd
better try to explain it with an example, still based on your string-
matcher example. Suppose that you had not used cl:or and cl:and, but
my:or and my:and.
I'd be tempted(*) to do

(defmacro my:or (&whole form)
  `(make-matcher ',form))

and the same with my:and. I think that it would make the language look
more embedded into Lisp. Do you think it's an abomination? ;-)

Ale

(*) Well, not in your example, but in a more complex language
consisting of many operators freely mixed with Lisp code.
From: Zach Beane
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <m3ab6gmn0y.fsf@unnamed.xach.com>
Alessio Stalla <·············@gmail.com> writes:

> First, how would you handle the presence of regular Lisp code
> intermixed with your language's code? (e.g. in your string-matcher
> example, allowing the presence of both string literals and Lisp
> expressions that produce strings). I guess in this case you have no
> other option besides eval/compile, or am I missing something? (this is
> not a critique of your technique, I'm just wondering).

No, I don't think you're missing anything. If you want to have unconstrained Common Lisp expressions, the full
Common Lisp compiler or evaluator seems like the best way to handle
them.

> The second question is less relevant, but more complicated, and I'd
> better try to explain it with an example, still based on your string-
> matcher example. Suppose that you had not used cl:or and cl:and, but
> my:or and my:and.
> I'd be tempted(*) to do
>
> (defmacro my:or (&whole form)
>   `(make-matcher ',form))
>
> and the same with my:and. I think that it would make the language look
> more embedded into Lisp. Do you think it's an abomination? ;-)

I don't get it, sorry.

Zach
From: Alessio Stalla
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <8a576c2b-ff67-48fa-979c-f683081ef1e5@z19g2000yqe.googlegroups.com>
On 16 Apr, 21:11, Zach Beane <····@xach.com> wrote:
> I don't get it, sorry.

Nevermind, it was just a quick thought that crossed my mind; a little
stylistic question that probably can only matter on a case-by-case
basis.

A.
From: Francisco Vides =??B?RmVybsOhbmRleg==?=
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <mpKdnSNv8Il08nrU4p2dnAA@giganews.com>
Zach Beane wrote:

> There's no need to involve the compiler at all:
> 
> (defun make-template-function (file)
> (let ((lines (read-lines file)))
> (lambda ()
> (dolist (line lines)
> (print line)))))
> 
> CL-PPCRE and HTML-TEMPLATE do something like this (but much more
> sophisticated). Not an EVAL or COMPILE to be found.
> 
> http://xach.livejournal.com/131456.html has a bit of stuff I wrote a
> while ago on the topic.

The article from Gary King isn't available, but Peter Seibel and your 
article are very interesting (I remember I've read all three before).

But I think the problem here is very different. You can form a tree of 
closures to query something, that's true. But in this case, I can have 
something like:

Hi <% (princ name) %>!

Which I want to compile to

(lambda (name)
  (write-string "Hi ")
  (princ name)
  (write-string "!"))

I think that '(princ name) can be processed and converted in a tree of 
closures, but that would imply to do the same for the whole language. I 
think that would be overkill in this case, and in fact, that's what the 
compiler is for. So, IMHO, using compile (better than eval) is appropiate in 
this case.

Please tell me if I'm wrong. Thanks.

-- 
+-----------------
| Francisco Vides Fernández <······@dedaloingenieros.com>
| Director técnico.
| Dédalo Ingenieros http://www.dedaloingenieros.com/
| PGP: http://pgp.rediris.es:11371/pks/lookup?op=index&search=0xB1299C15
+------
From: Pascal J. Bourguignon
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <7cr5zsfz6a.fsf@pbourguignon.anevia.com>
Francisco Vides =??B?RmVybsOhbmRleg==?= <······@dedaloingenieros.com> writes:
> Yes, that works, but it would be more nice and dynamic if the function do 
> itself  (and also would prove the power of Lisp, I'm trying to push mi 
> limits a bit here and learn something valuable)

What I have not explained in the solution I proposed is that it means
a change of point of view.  The idea is that the function goes reading
the file everytime it needs to output its contents.  This is the basic
functionally you've described.  Then you may want to cache that data
to avoid rereading it when the file didn't change.  For this however,
we don't have a lot of features to rely on in CL.  We can use
FILE-WRITE-DATE, but an implementation may return NIL, in which case
we're at the same point and we have to read the whole file again to
see if it changed.  

In anycase, caching and processing are orthogonal concerns that you
should consider separately.

-- 
__Pascal Bourguignon__
From: Francisco Vides =??B?RmVybsOhbmRleg==?=
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <zpCdnZWRHoy5yXrU4p2dnAA@giganews.com>
Pascal J. Bourguignon wrote:

> Francisco Vides =??B?RmVybsOhbmRleg==?= <······@dedaloingenieros.com>
> writes:
>> Yes, that works, but it would be more nice and dynamic if the function do
>> itself  (and also would prove the power of Lisp, I'm trying to push mi
>> limits a bit here and learn something valuable)
> 
> What I have not explained in the solution I proposed is that it means
> a change of point of view.  The idea is that the function goes reading
> the file everytime it needs to output its contents.  This is the basic
> functionally you've described.  

Yes, I should have explained better.

> Then you may want to cache that data
> to avoid rereading it when the file didn't change.  For this however,
> we don't have a lot of features to rely on in CL.  We can use
> FILE-WRITE-DATE, but an implementation may return NIL, in which case
> we're at the same point and we have to read the whole file again to
> see if it changed.
> In anycase, caching and processing are orthogonal concerns that you
> should consider separately.

Yes, thank for the advice



-- 
+-----------------
| Francisco Vides Fernández <······@dedaloingenieros.com>
| Director técnico.
| Dédalo Ingenieros http://www.dedaloingenieros.com/
| PGP: http://pgp.rediris.es:11371/pks/lookup?op=index&search=0xB1299C15
+------
From: Kazimir Majorinc
Subject: Re: Rebuilding functions at run-time
Date: 
Message-ID: <op.usgcyysh1cfios@kazimir-pc>
In Newlisp:

(setf f (lambda ()(print "bar")))
(push '(print "baz") f -1)

After that f = (lambda () (print "bar") (print "baz"))

--
Blog:    http://kazimirmajorinc.blogspot.com
WWW:     http://www.instprog.com