[racket-dev] TR: exporting a variable-arity map to untyped code (a bit urgent; release is imminent)

From: Neil Toronto (neil.toronto at gmail.com)
Date: Mon Jan 14 22:21:21 EST 2013

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 ⊥

Posted on the dev mailing list.