| 1 | |
|---|
| 2 | Below is a DRAFT e-mail that I intend to send to the mailing list, |
|---|
| 3 | however, having it in the repository (probably rephrased) is better |
|---|
| 4 | long-term documentation. |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | Over the past days, I've been working on porting SBCL's D-M-C tests to ABCL's |
|---|
| 9 | test suite and testing+fixing our implementation. A number of use-cases have |
|---|
| 10 | been fixed, however, I'm now down to the more complex cases, in particular |
|---|
| 11 | the case for the (:arguments . lambda-list). |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | Context |
|---|
| 15 | ----------- |
|---|
| 16 | |
|---|
| 17 | When handling EMF computation, there are two sets of arguments (lambda lists): |
|---|
| 18 | |
|---|
| 19 | 1. the arguments passed to the METHOD-COMBINATION through the |
|---|
| 20 | (:method-combination ...) form in the generic function definition |
|---|
| 21 | 2. the arguments passed to the generic function when it is being called |
|---|
| 22 | |
|---|
| 23 | This distinction is very important, yet not particularly clear from our |
|---|
| 24 | sources. The former set of arguments is available from the instantiation of |
|---|
| 25 | the generic function (DEFGENERIC evaluation) and constant throughout the life |
|---|
| 26 | of the GF. The latter is set of arguments is not available until the function |
|---|
| 27 | is being called and will presumably be different for each invocation of the GF. |
|---|
| 28 | |
|---|
| 29 | The former set is passed to the D-M-C form in the second position: |
|---|
| 30 | (D-M-C <name> <arguments> ....). The latter set is made accessible by |
|---|
| 31 | providing the (:arguments ...) form to the D-M-C form -- binding of the |
|---|
| 32 | variables happens at "EMF-calculation-time". |
|---|
| 33 | |
|---|
| 34 | Current implementation |
|---|
| 35 | --------------------------------- |
|---|
| 36 | |
|---|
| 37 | Our existing implementation does not work at all with the (:arguments ...) |
|---|
| 38 | option in the D-M-C definition. [SBCL didn't either, btw, |
|---|
| 39 | until 0.7.<something>] |
|---|
| 40 | What happens in our implementation is that the function |
|---|
| 41 | STD-COMPUTE-EFFECTIVE-METHOD-FUNCTION calls a function created by the D-M-C. |
|---|
| 42 | That function returns forms to be used as the EMF. S-C-E-M-F wraps the returned |
|---|
| 43 | forms in a function and returns it as the EMF. |
|---|
| 44 | |
|---|
| 45 | This works as long as the EMF does not depend on the arguments supplied |
|---|
| 46 | to the GF (generic function) call. |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | The problem |
|---|
| 50 | ------------------ |
|---|
| 51 | |
|---|
| 52 | Our implementation tries to access the function call parameters (resulting |
|---|
| 53 | in "unbound variable errors") from the EMF-generating function. However, |
|---|
| 54 | that function won't (ever) be passed the call arguments. |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | The solution |
|---|
| 58 | ----------------- |
|---|
| 59 | |
|---|
| 60 | Writing down the above and taking into account that we want to cache as much |
|---|
| 61 | of our EMF as possible for performance reasons as well as considering that |
|---|
| 62 | the EMF depending on the function call arguments can't be cached, I think |
|---|
| 63 | this is the solution: |
|---|
| 64 | |
|---|
| 65 | The forms being returned (and later wrapped in a lambda) should include code |
|---|
| 66 | which does another code-generation step --with access to the call parameters-- |
|---|
| 67 | and include a call to the forms having been generated. |
|---|
| 68 | |
|---|
| 69 | Examples |
|---|
| 70 | -------------- |
|---|
| 71 | |
|---|
| 72 | A call to the EMF-generating function which does not depend on the call |
|---|
| 73 | arguments would return something like: |
|---|
| 74 | |
|---|
| 75 | '(CALL-METHOD (MAKE-METHOD (error "ABC 123"))) |
|---|
| 76 | |
|---|
| 77 | This form will be wrapped in a lambda roughly like this: |
|---|
| 78 | (lambda (args) (macrolet ((call-method ...)) <forms>)) |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | A call to the EMF-generating function which *does* depend on the arguments |
|---|
| 82 | would return something like: |
|---|
| 83 | |
|---|