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

wea*_*ish 5 legacy annotations racket typed-racket

ts-guide说:

除了:形式之外,几乎所有球拍的绑定形式都有允许指定类型的对应形式。

但它没有说明何时使用哪一个。

并且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)
Run Code Online (Sandbox Code Playgroud)

ben*_*ers 2

第一种形式

第一种形式使用特殊形式define:。它和其他以 结尾的形式:是当前版本的 Racket 中的遗留形式(在本答案时为v 6.1.1 )。它相当于typed/racketsdefine但不接受第二种形式。它可用于向后兼容。

第二形式

第二种形式更接近地反映了函数签名的思想,如《如何设计程序*》一书中的函数设计过程中所描述的那样。更好的是,因为允许写作typed/racket

(: id (Number . -> . Number) 
Run Code Online (Sandbox Code Playgroud)

使用读者的中缀宏,我们可以以一些额外字符的价格获得与如何设计程序更接近的对应关系。

第三种形式

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

> ((lambda ((x : Number)) : Number (+ x 10)) 4)
- : Number
14 
Run Code Online (Sandbox Code Playgroud)

关于类型推断的备注

请注意,typed/racket具有类型推断,并且无需指定返回类型,如下所示:

> ((lambda ((x : Number))(+ x 10)) 4)
- : Number
14
Run Code Online (Sandbox Code Playgroud)

如果没有指定类型, Indeedtyped/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
Run Code Online (Sandbox Code Playgroud)

结论

当然,typed/racket推断的结果可能不是程序员所期望的。使用第二种形式的优点是使程序员的意图明确,而使程序员的意图明确是如何设计程序的核心原则,也是开发动机的核心typed/racket