Lisp 当racket将检查结构时';函数中的类型是什么?

Lisp 当racket将检查结构时';函数中的类型是什么?,lisp,racket,Lisp,Racket,该计划: (struct pt (x y)) (define (distance p1 p2) (sqrt (+ (sqr (- (pt-x p2) (pt-x p1))) (sqr (- (pt-y p2) (pt-y p1)))))) (distance (pt 0 0) (pt 3.1415 2.7172)) 很好。如果添加一行: (struct pt2 (x y)) 然后 出错 pt-x: contract violation expected: pt? given

该计划:

(struct pt (x y))

(define (distance p1 p2)
(sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
       (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))
很好。如果添加一行:

(struct pt2 (x y))
然后

出错

pt-x: contract violation
expected: pt?
given: #<pt2>
所以作为球拍,如果在“(定义(距离p1p2)”,之后有…可能100行代码,需要1分钟,那么行“(sqrt(+(sqr(-(pt-x p2)(pt-x p1)))发现类型错误,那么它将浪费1分钟


谢谢!

我不知道你说的“浪费1分钟”是什么意思

  • 从某种意义上说,在调用
    distance
    后,执行
    (pt-x p2)
    可能需要1分钟
  • 或者在某种意义上,整个程序可能需要1分钟才能执行
    (pt-x p2)

如果您指的是第一个,您可以将合同添加到距离中。例如

#lang racket

(struct pt (x y))

(define/contract (distance p1 p2) (-> pt? pt? number?)
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))
每次调用
distance
时,它都会检查
p1
p2
是否满足
pt?
,如果检查失败,它会立即出错。请注意,这会在运行时发生,并且只有在调用
distance
时才会发生。程序可能会运行很长时间而没有任何问题,然后执行e> (距离(pt2 0 0)(pt2 3.1415 2.7172)),然后才会发生错误


如果您指的是第二个错误,那么您根本不希望为了发现错误而运行程序。也就是说,您希望静态地发现错误。您需要使用类型化Racket或类似的东西。这类似于使用静态类型检查的语言

#lang typed/racket

(struct pt ([x : Number] [y : Number]))

(: distance : pt pt -> Number)
(define (distance p1 p2) 
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))

所以,如果我使用类型化的racket,我可以在函数的第一行执行静态类型检查吗?
#lang racket

(struct pt (x y))

(define/contract (distance p1 p2) (-> pt? pt? number?)
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))
#lang typed/racket

(struct pt ([x : Number] [y : Number]))

(: distance : pt pt -> Number)
(define (distance p1 p2) 
  (sqrt (+ (sqr (- (pt-x p2) (pt-x p1)))
           (sqr (- (pt-y p2) (pt-y p1))))))

(distance (pt 0 0) (pt 3.1415 2.7172))