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