I discovered that afterwards, yes. However I do want to short-circuit just calls to free to use the defaults, not free-box. Currently I have to check the box in each instance. -Ian ----- Original Message ----- From: Carl Eastlund <c...@ccs.neu.edu> To: J. Ian Johnson <i...@ccs.neu.edu> Cc: dev <dev@racket-lang.org> Sent: Fri, 16 Aug 2013 19:48:58 -0400 (EDT) Subject: Re: [racket-dev] Generics scoping issues
Mind you, I don't think this example -- using a method in a #:fast-defaults predicate -- can work. The implementation of free-box will have to check the predicate in order to perform generic dispatch, and the predicate has to call free-box, so it will diverge. Carl Eastlund On Fri, Aug 16, 2013 at 6:51 PM, Carl Eastlund <c...@ccs.neu.edu> wrote: > The method name you give to define/generic is interpreted in the context > of the generic interface name you provide. So if you supply the name > "free" inside a macro, that's the wrong context. That error goes away, as > you found, if you pass "free" as an argument to def-free. > > After that, you get the error "free-box: undefined" because the > #:fast-defaults predicate is lifted to a definition that comes before the > definition of the free-box method. I'll fix that by reordering the > definitions; meanwhile you can fix that by just eta-expanding your use of > "compose". > > Carl Eastlund > > > On Fri, Aug 16, 2013 at 5:41 PM, Carl Eastlund <c...@ccs.neu.edu> wrote: > >> The method names are always going to be in the context of the generic >> interface name. There's nowhere else they can come from. >> >> Carl Eastlund >> >> >> On Fri, Aug 16, 2013 at 5:39 PM, J. Ian Johnson <i...@ccs.neu.edu> wrote: >> >>> WRT the struct abstraction, using syntax-local-introduce on >>> #'gen:binds-variables seemed to do the trick, oddly. >>> -Ian >>> ----- Original Message ----- >>> From: "Carl Eastlund" <c...@ccs.neu.edu> >>> To: "J. Ian Johnson" <i...@ccs.neu.edu> >>> Cc: "dev" <dev@racket-lang.org> >>> Sent: Friday, August 16, 2013 5:23:33 PM GMT -05:00 US/Canada Eastern >>> Subject: Re: [racket-dev] Generics scoping issues >>> >>> >>> Okay, let me dig into this. The expansion of define/generic is an odd >>> thing in the way it treats the method names; I'm not at all sure I've >>> gotten it right, or that it's clear what "right" should even be. I'll get >>> back to you shortly. >>> >>> >>> >>> Carl Eastlund >>> >>> >>> On Fri, Aug 16, 2013 at 5:17 PM, J. Ian Johnson < i...@ccs.neu.edu > >>> wrote: >>> >>> >>> Re: problem 1 - ah yes I see. >>> Problem 2: >>> In the body of def-free: >>> >>> generic-problems.rkt:16:26: define/generic: free is not a method of >>> generic interfaces gen:binds-variables >>> at: free >>> in: (define/generic gfree free) >>> >>> This compiles if I additionally supply def-free with free, but it >>> doesn't run: >>> free-box: undefined; >>> cannot reference an identifier before its definition >>> in module: "/home/ianj/projects/oaam/code/generic-problems.rkt" >>> context...: >>> /home/ianj/projects/oaam/code/generic-problems.rkt: [running body] >>> >>> Furthermore, if I abstract over the struct form so that #:methods >>> gen:binds-variables is part of the macro expansion, even passing free to >>> def-free won't work anymore: >>> >>> (define-syntax-rule (astruct name (fields ...) (methods ...)) >>> (struct name exp (fields ...) #:transparent #:methods >>> gen:binds-variables [methods ...])) >>> >>> (astruct avar (name) >>> [(def-free e gfree free bound avar [(x) (if (x . ∈ . bound) ∅ (set >>> x))])]) >>> >>> generic-problems.rkt:31:27: define/generic: free is not a method of >>> generic interfaces gen:binds-variables >>> at: free >>> in: (define/generic gfree free) >>> >>> >>> >>> >>> ----- Original Message ----- >>> From: "Carl Eastlund" < c...@ccs.neu.edu > >>> To: "J. Ian Johnson" < i...@ccs.neu.edu > >>> Cc: "dev" < dev@racket-lang.org > >>> Sent: Friday, August 16, 2013 4:50:53 PM GMT -05:00 US/Canada Eastern >>> Subject: Re: [racket-dev] Generics scoping issues >>> >>> >>> >>> Problem 1 -- you have to use define/generic if you want to use the >>> generic version of something in the context of a set of specific method >>> implementations. That's by design. >>> >>> Problem 2 -- what error message or unexpected behavior are you getting? >>> That should work, it sounds like a bug in define/generic if it's not >>> working. >>> >>> >>> >>> Carl Eastlund >>> >>> >>> On Fri, Aug 16, 2013 at 4:36 PM, J. Ian Johnson < i...@ccs.neu.edu > >>> wrote: >>> >>> >>> I'm starting to use generics, and me being myself, I wrote some macros >>> to make writing method definitions easier. >>> But, I'm seeing that #:methods seems to rebind method identifiers in a >>> way that hygiene interferes with. >>> >>> I would expect to be allowed to do the following two things (problems >>> annotated): >>> >>> (struct exp (label fvs-box)) ;; parent struct for all expressions >>> (define-generics binds-variables >>> [free-box binds-variables] >>> [free binds-variables #:bound [bound]] >>> #:fallbacks [(define (free e #:bound [bound ∅]) ∅) >>> (define free-box exp-fvs-box)] >>> #:fast-defaults ([(compose unbox free-box) >>> (define (free e #:bound bound) (unbox (free-box e)))])) ;; problem 1: >>> free-box not in scope >>> >>> (define-syntax-rule (def-free e gfree bound struct [(pats ...) rhss ...]) >>> (begin >>> (define/generic gfree free) ;; problem 2: since #:methods rebinds free, >>> this is not in the scope one would expect with its definition in the >>> define-generics form. >>> (define (free e #:bound [bound ∅]) >>> (match e [(struct _ fvs-box pats ...) >>> (set-box! fvs-box >>> (let () rhss ...))])))) >>> >>> (struct var exp (name) #:transparent >>> #:methods gen:binds-variables >>> [(def-free e gfree bound var [(x) (if (x . ∈ . bound) ∅ (set x))])]) >>> >>> I have workarounds thanks to stamourv, but they're unpleasant: >>> Problem 1: define free in fast-defaults as an eta-expansion of a >>> definition outside the define-generics form that does what you want. >>> Problem 2: add free as a parameter to def-free, and pass free in at all >>> uses of def-free. >>> >>> The first problem seems like more of a programming error than the use of >>> the wrong tool. >>> The second problem seems like generic method identifiers should be >>> syntax-parameters, if they indeed need to be rebound in the rhs of the >>> #:methods argument. >>> >>> Are these expectations unreasonable/against the design decisions for >>> generics? >>> Thanks, >>> -Ian >>> >>> _________________________ >>> Racket Developers list: >>> http://lists.racket-lang.org/dev >>> >>> >>> >>> >>> >> > _________________________ Racket Developers list: http://lists.racket-lang.org/dev