何时在 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-reference 说 form:
是遗留的,为了向后兼容。
但是在ts-guide中,form:
用的地方很多
那么 : v t
比 form:
更受欢迎吗?
那么 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 forms(v 6.1.1 在这个答案的时候)。它等同于 typed/racket
的 define
但不接受第二种形式。它可用于向后兼容。
中学
第二种形式更接近地反映了 函数签名 的想法,如 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的动机的核心=] 排在首位。
ts-guide 说:
In addition to the
:
form, almost all binding forms from racket have counterparts which allow the specification of types.
但是并没有说什么时候使用哪个。
并且 ts-reference 说 form:
是遗留的,为了向后兼容。
但是在ts-guide中,form:
用的地方很多
那么 : v t
比 form:
更受欢迎吗?
那么 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 forms(v 6.1.1 在这个答案的时候)。它等同于 typed/racket
的 define
但不接受第二种形式。它可用于向后兼容。
中学
第二种形式更接近地反映了 函数签名 的想法,如 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的动机的核心=] 排在首位。