#lang racket (require racket/generic rackunit) (define-namespace-anchor generic-env) (define-syntax-rule (check-good-syntax exp ...) (begin (check-not-exn (lambda () (eval '(module foo racket/base (require racket/generic) exp) (namespace-anchor->namespace generic-env)))) ...)) (define-syntax-rule (check-bad-syntax exp ...) (begin (check-exn exn:fail:syntax? (lambda () (eval '(module foo racket/base (require racket/generic) exp) (namespace-anchor->namespace generic-env)))) ...)) (check-good-syntax (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream)) (define-generics stream #:defined-table stream-table (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-empty? null?)])) (define-generics stream #:defined-table stream-table #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-empty? null?)]) (stream-first stream) (stream-rest stream) (stream-empty? stream)) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defined-table stream-table #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-empty? null?)])) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-empty? null?)]) #:defined-table stream-table) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([box? (define/generic first stream-first) (define/generic rest stream-rest) (define/generic empty? stream-empty?) (define stream-first (compose first unbox)) (define stream-rest (compose rest unbox)) (define stream-empty? (compose empty? unbox))]))) (check-bad-syntax (define-generics stream (stream-first stream) (stream-rest stream) #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-empty? null?)]) (stream-empty? stream)) (define-generics stream (stream-first stream) (stream-rest stream) #:defined-table stream-table (stream-empty? stream)) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults foo) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([list? (define stream-first car) (define stream-rest cdr) (define stream-rest 5) (define stream-empty? null?)])) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([]))) (check-good-syntax (define-generics foo (bar foo)) (define-generics foo (bar x foo)) (define-generics foo (bar foo x)) (define-generics foo (bar foo [x])) (define-generics foo (bar foo x y)) (define-generics foo (bar foo x [y])) (define-generics foo (bar foo [x] [y])) (define-generics foo (bar foo x #:k z y)) (define-generics foo (bar foo x #:k z [y])) (define-generics foo (bar foo [x] #:k z [y])) (define-generics foo (bar foo x #:k [z] y)) (define-generics foo (bar foo x #:k [z] [y])) (define-generics foo (bar foo [x] #:k [z] [y])) (define-generics foo (bar foo [x] #:k z [y] #:j w)) (define-generics foo (bar foo [x] #:k z [y] #:j [w])) (define-generics foo (bar foo [x] #:k [z] [y] #:j w)) (define-generics foo (bar foo [x] #:k [z] [y] #:j [w]))) (check-bad-syntax (define-generics foo (bar)) (define-generics foo (bar x)) (define-generics foo (bar [foo])) (define-generics foo (bar [x] foo)) (define-generics foo (bar foo [x] y)) (define-generics stream (stream-first stream) (stream-rest stream) (stream-empty? stream) #:defaults ([list? (define/generic super not-a-stream-method) (define stream-first first) (define stream-rest rest) (define stream-empty? empty?)]))) (check-good-syntax (begin (module gen racket (require racket/generic) (provide gen:foo (rename-out [*bar bar])) (define-generics foo (bar foo)) (define *bar bar)) (module impl racket (require racket/generic (submod ".." gen)) (struct thing [] #:methods gen:foo [(define/generic gbar bar)])))) (check-bad-syntax (begin (module gen racket (require racket/generic) (provide gen:foo (rename-out [*bar bar])) (define-generics foo (*bar foo)) (define bar *bar)) (module impl racket (require racket/generic (submod ".." gen)) (struct thing [] #:methods gen:foo [(define/generic gbar bar)]))))