[plt-scheme] detecting duplicate internal definitions
This is both a Swindle bug report and a macro question/feature-request.
I think this should work in Swindle, but it doesn't:
Welcome to MzScheme version 206.1, Copyright (c) 2004 PLT Scheme, Inc.
> (require (lib "swindle.ss" "swindle")) ;version 20040114
=> (error-print-width 999)
=> (defmethod (f x) x)
=> (let () (defmethod (f (x = 1)) 0) (defmethod (f (x = 0)) 1) (f 0))
letrec-values: duplicate binding name at: f in: (letrec-values (((f) (let ((g (or (no-errors f) (generic f)))) (add-method g (qualified-method #f ((x = 1)) 0)) g)) ((f) (let ((g (or (no-errors f) (generic f)))) (add-method g (qualified-method #f ((x = 0)) 1)) g))) (f 0))
The defmethods in internal-definition position shouldn't be expanding
to definitions (which are turning into a `letrec'), but should just be
expanding to calls to `add-method' (for the generic `f' defined at the
top level); the bug is in `method-def-adder' in "clos.ss":
(if (or
[...]
;; local definition -- don't know which is first => no define
(eq? 'lexical (syntax-local-context)))
(syntax/loc stx (add-method name method-make))
As of a few versions ago, `syntax-local-context' no longer returns
'lexical for internal definitions; it returns a list of values
identiifying the scopes. I think you can just change this to
(list? (syntax-local-context)) and it should do the right thing.
Now here's my macro question: if `f' hadn't been defined at the top
level, would there be any way to do the right thing here? Namely, the
first `defmethod' should define a generic, but the second one should
not. Can a macro get at the other bindings in the same
internal-definition context to see whether a variable has already been
bound? If not, would this be something easy to enable? Perhaps the
list returned by `syntax-local-context' could be an alist instead?
I.e. (cdar (syntax-local-context)) would be the list of identifiers
already bound in the innermost internal definition context. Forgive
me if I'm being naive about why this would be impossible (or a bad
idea)...
--dougo at place.org