From pc at p-cos.net Sun Dec 12 18:45:26 2004 From: pc at p-cos.net (Pascal Costanza) Date: Sun, 12 Dec 2004 19:45:26 +0100 Subject: [aspectl-devel] with-special-function-scope In-Reply-To: <3CBE8DB0-4073-11D9-8CAE-00039345C8B0@onlinehome.de> References: <3CBE8DB0-4073-11D9-8CAE-00039345C8B0@onlinehome.de> Message-ID: Hi Peter, Sorry for the really long delay, but I am only slowly regaining my normal life... ;-) On 27 Nov 2004, at 13:52, ml13 at onlinehome.de wrote: > Hi, > > I am trying to extend the test example to use a special function that > is recursive. > As an example, I am defining f(x) to compute the sum of the squares >> from 0 to x. > > When I am trying to dynamically redefining the function to simply add > 1 to its result, this new definition seems to get called "inside" as > well. Yes, that's right. The methods that you add with dynamic scope are active for the respective generic function no matter when and how you call it. So even in a recursive call they get called as well when they are applicable. > What do I have to do to get the (assert (eql (f 5) 56))) working?? Special functions use the special method combination by default that allows you to :override an existing method. This means that an overriden method is canceled out for the current dynamic scope - i.e., it is never executed in the current dynamic scoped. You can make use of this to do what you want. Here is the code: (in-package :al-user) (define-special-function f (x) (:definer f*)) (defmethod f* ((scope t) x) (if (zerop x) 0 (+ (* x x) (f (1- x))))) (assert (eql (f 5) 55)) (with-special-function-scope (f*) (defmethod* f* :around ((scope dynamic) x) (1+ (with-special-function-scope (f*) (defmethod* f* :override :around ((scope dynamic) x) (call-next-method)) (call-next-method)))) (assert (eql (f 5) 56))) (assert (eql (f 6) 91)) The trick is a) to use an :around method and b) to :override that :around method with a "skipping" method inside itself. a) is important because if you would otherwise use a primary method there would be no way to override just the newly added one. (It might be a good idea to draw a diagram for the interaction in order to understand the control flow.) I hope this helps. Maybe you're right that this should be simpler, so I will keep this in mind for possible future changes or additions. > PS: By the way, is there possibly any example existing of the cached > fibonacci function using the current version of aspectL? I don't have any at hand at the moment, sorry. Should be simple though, right? ;) Cheers, Pascal -- Tyler: "How's that working out for you?" Jack: "Great." Tyler: "Keep it up, then."