From: levy
Subject: Macro dependency tracking
Date: 
Message-ID: <1166649269.324324.281120@i12g2000cwa.googlegroups.com>
Hi,

I always wondered why macro calls are not reexpanded automatically each
time the macro is redefined. Whenever I recompile a macro definition I
should recompile all places where the macro was expanded which is
sometimes nearly impossible to do, so it's easier to restart and
recompile everything.

This is an incomplete and simple implementation to automatically
recompile functions using the computed-class package at
http://common-lisp.net/project/computed-class

The idea is that each function and macro definition will have it's own
computed-state and the dependency will be tracked automatically during
compiling a function at macroexpand time.

Each time a macro is redefined it will invalidate the computed-states
of the functions where it was used. Whenever a function is called it
will first check if the function needs to be recompiled. This runtime
overhead can be eliminated, see later.

Ok, don't take this too seriously, but still it might be interesting
how short it is...

CC> (define-computed-universe mdt-compute-as)
MDT-COMPUTE-AS

CC> (defmacro defun/mdt (name args &body forms)
      `(clet ((f (mdt-compute-as
                    (progn
                      (format t "Recompiling ~A" ',name)
                      (compile nil `(lambda ,',args ,',@forms))))))
        (defun ,name ,args
          (funcall f ,@args))))
DEFUN/MDT

CC> (defmacro defmacro/mdt (name args &body forms)
      (let ((m (or (get name 'mdt)
                   (setf (get name 'mdt) (mdt-compute-as nil)))))
        (invalidate-computed-state m)
        `(defmacro ,name ,args
          (computed-state-value (get ',name 'mdt))
          ,@forms)))
DEFMACRO/MDT

CC> (defmacro/mdt with-a (&body forms)
      `(let ((a 1))
        ,@forms))
WITH-A

CC> (defun/mdt add (b)
      (with-a
        (+ a b)))
ADD

CC> (add 1)
Recompiling ADD
2

CC> (add 1)
2

CC> (defmacro/mdt with-a (&body forms)
      `(let ((a 2))
        ,@forms))
WITH-A

CC> (add 1)
Recompiling ADD
3

CC> (add 1)
3

Unfortunately there is no forward invalidation in the computed class
package yet, so there is an extra runtime check each time the function
add is called whether it has to be recompiled or not. This can be
easily fixed by the following definition as soon as forward
invalidation becomes available.

(defmacro defun/mdt* (name args &body forms)
  `(computed-state-value
    (mdt-compute-as
      (progn
        (format t "Recompiling ~A" ',name)
        (defun ,name ,args
          ,@forms)))))

The function's computed state will be captured by the macros' computed
states as the compiler expands macro calls. If there were no macro
calls at all then the function's computed state will be garbage
collected. Whenever a called macro definition changes its computed
state gets invalidated and thus the functions depending on it will be
immediately redefined.

Cheers,
levy

From: Ken Tilton
Subject: Re: Macro dependency tracking
Date: 
Message-ID: <jfiih.29$eq5.20@newsfe09.lga>
levy wrote:
> Hi,
> 
> I always wondered why macro calls are not reexpanded automatically each
> time the macro is redefined. Whenever I recompile a macro definition I
> should recompile all places where the macro was expanded which is
> sometimes nearly impossible to do, so it's easier to restart and
> recompile everything.
> 
> This is an incomplete and simple implementation to automatically
> recompile functions using the computed-class package at
> http://common-lisp.net/project/computed-class
> 

Yes, and this marks quite a milestone with the number of Cells spin-offs 
now exceeding the number of users.

Similarly, I never thought my failure to document could be surpassed, 
but here is the computed-class documentation:

> See test.lisp for more examples and/or read the Cells docs.

I underestimated you yobs.

:)

ken
From: levy
Subject: Re: Macro dependency tracking
Date: 
Message-ID: <1166652120.098116.262580@48g2000cwx.googlegroups.com>
Ken Tilton wrote:
> Yes, and this marks quite a milestone with the number of Cells spin-offs
> now exceeding the number of users.
Count me to the users too, at least for some time!

> > See test.lisp for more examples and/or read the Cells docs.
Well, what can I say... ;-)

The point is not comparison but that the compiler, CLOS mop or a
structured editor could use stuff like that.

Cheers,
levy
From: Ken Tilton
Subject: Re: Macro dependency tracking
Date: 
Message-ID: <mGiih.31$eq5.17@newsfe09.lga>
levy wrote:
> Ken Tilton wrote:
> 
>>Yes, and this marks quite a milestone with the number of Cells spin-offs
>>now exceeding the number of users.
> 
> Count me to the users too, at least for some time!
> 
> 
>>>See test.lisp for more examples and/or read the Cells docs.
> 
> Well, what can I say... ;-)
> 
> The point is not comparison but that the compiler, CLOS mop or a
> structured editor could use stuff like that.

No argument there. Hell, Cells once had (and I think someday will have 
again) the moral equivalent of a Gosub, using itself a Cell to know when 
to "return".

Have you heard about the annual conference for dataflow hacks? Trying to 
keep talks shorter and more memorable. All must be written in the form 
of substitute lyrics to popular songs and sung karoake-style. Words to 
the chorus should be distributed beforehand so the audience can sing 
along. Venues must be cities with casinos.

ken

-- 
Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

"Well, I've wrestled with reality for thirty-five
years, Doctor, and I'm happy to state I finally
won out over it." -- Elwood P. Dowd

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon