Lisp和Scheme中的类型


10

我现在看到球拍具有类型。乍一看,它似乎与Haskell键入几乎相同。但是Lisp的CLOS是否涵盖了Haskell类型涵盖的某些空间?创建一个非常严格的Haskell类型和任何OO语言的对象似乎都差不多。只是我喝了一些Haskell kool-aid,而我完全偏执地认为,如果我沿着Lisp的路走,由于动态打字,我会被搞砸了。

Answers:


6

CL类型系统比Haskell 系统更具表现力,例如,您可以(or (integer 1 10) (integer 20 30))为value 使用类型1,2,...9,10,20,21,...,30

但是,Lisp编译器不会强加他们对类型安全性的理解,因此您可以忽略它们的“注释” ,这需要您自担风险

这意味着您可以通过声明所有值类型并仔细确保推断出所有必需的类型而用Lisp编写Haskell,但是首先可以更轻松地使用Haskell。

基本上,如果要使用强动态类型,请使用Haskell或OCaml,如果要使用强动态类型,请使用Lisp。如果要使用弱静态类型,请使用C;如果要使用弱动态类型,请使用Perl / Python。每条路径都有其优点(和狂热者)和缺点(和and弱者),因此您将从所有这些中受益。


19
任何使用“强制类型安全”的人都无法理解什么是类型安全或为什么有用。
梅森惠勒

11
@MasonWheeler:任何人从一个简单的词句中得出结论,就会发现自己比其他情况更容易犯错。例如,在这种情况下。
2013年

4
由于主题是语言,因此术语“顺其自然”是恰当且恰当的图像。
luser droog

1
@KChaloux:如示例所示,我的意思是“富有表现力”。
2013年

4
一切都倒退了。动态类型化是静态类型化的一种特殊情况,在这种情况下,您迫使程序员对所有内容都使用一种类型。通过将每个变量声明为类型Object或类型树的根,我可以在大多数静态类型的语言中(详细地)执行相同的操作。这是的表现,因为你剥夺了的选项说某些变量只能包含一定的值。
2014年

5

类型化球拍与Haskell有很大不同。Lisp和Scheme中的类型系统,以及实际上通常是传统上无类型的语言生态系统中的类型系统,都有一个基本目标,即其他类型的系统不与现有的无类型代码互操作。例如,Typed Racket引入了全新的打字规则,以适应各种Racket习惯用法。考虑以下功能:

(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

对于非空列表,这将返回第一个元素。对于空列表,这将返回false。这在无类型语言中很常见;一种类型化的语言会使用类似的包装类型,Maybe或者在空情况下抛出错误。如果要向此函数添加类型,应使用哪种类型?它不是[a] -> a(用Haskell表示法),因为它可以返回false。它也不是[a] -> Either a Boolean,因为(1)在空情况下,它总是返回false,而不是任意布尔值;(2)Either类型将在其中包装元素Left并在其中添加false,Right并要求您“拆开任一个”以获取实际元素。相反,该值返回一个真联合-没有包装构造函数,在某些情况下它仅返回一种类型,而在其他情况下仅返回另一种类型。在类型化球拍中,这用联合类型构造函数表示:

(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

类型(U A #f)表示函数可以返回列表的元素,或者返回false,而无需任何包装Either实例。类型检查器可以推断出some-list是类型(Pair A (Listof A))列表还是空列表,此外,它推断出,在if语句的两个分支中,知道是哪种情况。类型检查器知道(car some-list)表达式中的列表必须具有类型,(Pair A (Listof A))因为if条件确保了它。这称为出现类型,旨在简化从未键入代码到已键入代码的过渡。

问题是迁移。这里有大量的无类型的Racket代码,而有类型的Racket不能仅仅强迫您放弃所有您喜欢的无类型的库,而是花一个月的时间向您的代码库添加类型。只要将类型逐渐添加到现有代码库中,就会出现此问题,有关这些想法的javascript应用程序,请参阅TypeScript及其任何类型。

渐变类型系统必须提供用于处理常见的无类型习语并与现有的无类型代码进行交互的工具。否则使用它会很痛苦,有关Clojure的示例,请参见“为什么不再使用Core.typed”


1
在经济学中,这就是所谓的格雷沙姆定律差钱驱逐良货。 它也倾向于在工程中找到应用。当您的系统中有两个理论上等效的子系统时,通常情况下,最糟糕的子系统会导致太多问题,使更好的子系统值得使用,正如我们在此处看到的那样。
梅森惠勒

“设计类型系统的示例”:这句话不完整
coredump

@MasonWheeler最糟糕的是,动态类型检查。因此,一经介绍,就不值得进行静态分析吗?
coredump

1
@coredump-逐步输入是值得的,除非您与未键入的代码交互不良。例如,TypeScript中的Any类型只是告诉类型检查器放弃,从根本上放弃了类型系统的好处,因为它可能导致错误的值通过大量静态检查的代码传播。类型化球拍使用合同和模块边界来避免此问题。
杰克

1
@coredump阅读Clojure文章。有了动态类型,尤其是对于所有没有静态类型可用的第三方代码,确实使他们为尝试使用静态类型改进代码库而费解。
梅森惠勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.