[racket-dev] TR: exporting a variable-arity map to untyped code (a bit urgent; release is imminent)
A recent change to the contract barrier has rendered one of my tricks
useless. Worse, the change makes things more correct, so I can't submit
a bug report. :p
`math/array' exports `array-map', which has a type much like that of
`map'. Also like `map', its type can't be converted to a contract. (This
is obviously lame, but it's a bit late in the release cycle to demand a
fix.) So I pulled some tricks to turn `array-map' into a macro that
expands differently in untyped code. Here's a distillation of the problem:
#lang racket
(module defs typed/racket
(provide typed-map untyped-map)
(: typed-map
(All (c a b ...) ((a b ... b -> c) (Listof a) (Listof b) ... b
-> (Listof c))))
(define (typed-map f lst . lsts) (apply map f lst lsts))
(: untyped-map (All (c a) ((a a * -> c) (Listof a) (Listof a) *
-> (Listof c))))
(define (untyped-map f lst . lsts) empty) ; implementation elided
)
(require (submod "." defs))
The original problem:
> (typed-map make-rectangular '(1 2 3) '(10 20 30))
Type Checker: The type of typed-map cannot be converted to a contract
in: (typed-map make-rectangular (quote (1 2 3)) (quote (10 20 30)))
The version intended for use in untyped code works fine with
variable-arity functions:
> (untyped-map + '(1 2 3) '(10 20 30))
'()
But a recent change to the contract barrier means it *only* works with
variable-arity functions:
> (untyped-map make-rectangular '(1 2 3) '(10 20 30))
untyped-map4: contract violation
expected a procedure that accepts 1 argument and arbitrarily more
without any keywords
given: #<procedure:make-rectangular>
I'm stuck. The only thing I can think of is to inline the body of
`array-map' when it's used in untyped code, but I would really rather
that something so basic be a value. Help?
Neil ⊥