[Openmcl-devel] Re: "leaking" call-method

Gary Byers gb at clozure.com
Sun Jun 5 02:38:45 UTC 2005



On Sat, 4 Jun 2005, Marco Baringer wrote:

> "Marco Baringer" <mb at bese.it> writes:
>
>> here's my current attempt:
>>
>> --------------------------------
>> (in-package :common-lisp-user)
>>
>> (define-method-combination test-combination ()
>>   ((after (:after))
>>    (primary () :required t))
>>   `(let ((*after* ,(when after
>>                      `(lambda ()
>>                         (call-method ,(first after))))))
>>      (declare (special *after*))
>>      (call-method ,(first primary))))
>>
>> (defgeneric foo (a)
>>   (:method-combination test-combination)
>>   (:method (a)
>>     (declare (special *after*))
>>     *after*)
>>   (:method :after (a)
>>     'after))
>>
>> (funcall (foo 4))
>> --------------------------------
>
> after looking into this a bit more it would appear that the lambda
> returned by foo's primary method is not "well formed" (the environment
> of the closure is a #<bogus object> pointing to a cons cell containing
> the numbers we get an error about when calling the closure).

Closures don't really reference an explicit "envionment" object in
OpenMCL; they basically just reference the values that they capture
as constants.  The situation that you're seeing is probably very
similar to what you'd see if you did:

(defun make-bogus-closure (&rest args)
   (declare (dynamic-extent args))
   #'(lambda ()
      args))

[Yes, the compiler could probably catch this, or at least warn if it
thinks that there might be a problem.]

>
> looking through method-combination.lisp make we think that by putting
> call-method into a lambda i'm losing some dynamic state which is setup
> by the normal method-combination machinery, colud this be the case?
> any ideas how to work around this?

The normal method-combination machinery makes heavy use of
stack-allocation (as does a lot of the GF-dispatch code); in the method-
combination case, it does so under the assumption that user code can't
really try to persistently capture any of this state (e.g., that what
you're trying to do isn't really kosher.)

I think that that's a reasonable assumption, and that policy means that
correct ("kosher") programs do less consing.

In the bogus example above, I don't think that there's any way that
the inner lambda can be written in a way that allows it to safely
capture a heap-allocated copy of the outer function's arguments; you'd
have to change the outer function to remove the DYNAMIC-EXTENT
declaration or to make a heap-allocated copy or something.  In your
case, I think that you'd have to make similar changes to the code
in "method-combination.lisp" (and possibly in some of the lower-level
parts of CLOS) to remove DYNAMIC-EXTENT declarations. (See the macro
WITH-LIST-FROM-LEXPR.)




>
> -- 
> -Marco
> Ring the bells that still can ring.
> Forget the perfect offering.
> There is a crack in everything.
> That's how the light gets in.
> 	-Leonard Cohen
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list