[racket] A (probably premature) concern about signatures
I was playing with the signatures that Matthias mentioned as being in
the pipeline for future inclusion, and just wanted to start a
discussion before they get locked in.
In full Racket, there's a form called define/contract that works like this:
#lang racket
(define/contract (distance x1 y1 x2 y2)
(number? number? number? number? . -> . number?)
(sqrt (+ (sqr (- x1 x2))
(sqr (- y1 y2)))))
And if you do something silly in the Interactions window, you get:
> (distance 0 0 3 "a")
...
broke the contract
(-> number? number? number? number? number?)
on distance; expected <number?>, given: "a"
In contrast, when I tried a signature (which needs Intermediate
Language, I think), I tried it like this:
(: distance (Number Number Number Number -> Number))
(check-expect (distance 0 0 3 4) 5)
(define (distance x1 y1 x2 y2)
(sqrt (+ (sqr (- x1 x2))
(sqr (- y1 y2)))))
which works just fine. Except when you use the function wrong in the
Interactions window,
> (distance 0 0 3 "a")
-: expects type <number> as 2nd argument, given: "a"; other arguments were: 0
it doesn't catch the signature error at all and just reports the error
when it finally tries to subtract "a"
At least for me, one of the main reasons to make contracts part of the
language is so that students are warned when they pass in wrong
argument types early rather than having to wade through all of the
calls that got them to that point, especially since backtraces aren't
available in the teaching languages. I'm hoping that the intention is
for signatures to do that and that it's possible to tweak them without
too much extra work to get that behavior.
Todd