何时在 Typed Racket 中使用 `form:`?

When to use `form:` in Typed Racket?

ts-guide 说:

In addition to the : form, almost all binding forms from racket have counterparts which allow the specification of types.

但是并没有说什么时候使用哪个。

并且 ts-referenceform: 是遗留的,为了向后兼容。

但是在ts-guide中,form:用的地方很多

那么 : v tform: 更受欢迎吗? 那么 form 呢?

例如:

; form:
(define: (id [z : Number]) : Number z)

; : v t + form
(: id (-> Number Number))
(define (id z) z)

; form (it seems recent versions of Racket add this?)
(define (id [z : Number]) : Number z)

But it does not say when to use which one.

在大多数情况下它们是等价的。

我喜欢第二种形式 - 它可以很容易地再次删除 TR 注释。

初一

第一种形式使用特殊形式define:。它和其他以 : 结尾的形式在当前版本的 Racket 中是 legacy formsv 6.1.1 在这个答案的时候)。它等同于 typed/racketdefine 但不接受第二种形式。它可用于向后兼容。

中学

第二种形式更接近地反映了 函数签名 的想法,如 designing functions in the book How to Design Programs* 的过程中所述。更好的是,因为 typed/racket 允许写

(: id (Number . -> . Number) 

使用 reader's infix macro 我们可以得到更接近 如何设计程序 的对应关系,但要多加一些字符。

第三种形式

第三种形式在静态类型语言方面更传统...我的意思是它更接近于 C 语言、Java、ML 等。它也更通用,因为它可以在匿名函数中使用:

> ((lambda ((x : Number)) : Number (+ x 10)) 4)
- : Number
14 

关于类型推断的备注

请注意,typed/racket 具有类型推断,无需指定 return 类型,如:

> ((lambda ((x : Number))(+ x 10)) 4)
- : Number
14

确实,如果指定 none,typed/racket 将始终尽最大努力推断类型:

> ((lambda (x)(+ x 10)) 4)
- : Integer [more precisely: Positive-Index]
14
> ((lambda (x)(+ x 10)) 4.0)
- : Flonum [more precisely: Positive-Flonum]
14.0
> ((lambda (x)(+ x 10)) 4/1)
- : Integer [more precisely: Positive-Index]
14

结论

当然,typed/racket推断出的不一定是程序员所期望的。使用第二种形式的优点是使程序员的意图明确,使程序员的意图明确是如何设计程序的核心原则,也是开发[=16的动机的核心=] 排在首位。