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