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

Reply via email to