[plt-scheme] detecting duplicate internal definitions

From: Doug Orleans (dougo at place.org)
Date: Mon May 10 23:58:14 EDT 2004

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


Posted on the users mailing list.