为什么大多数S表达式语言都是动态输入的?

kei*_*ter 25 lisp scheme programming-languages s-expression

为什么大多数Lisps和Schemes都是动态输入的?静态类型是否与其某些常见功能混合在一起?

Dou*_*rie 16

键入和s表达式可以一起使用,请参阅类型化方案.

部分是s表达式语言是动态类型的历史巧合.这些语言往往更多地依赖于,并且在s表达式上解析和模式匹配的简易性使得宏处理变得更加容易.对复杂宏的大多数研究都是用s表达式语言进行的.

键入的卫生宏很难.

  • 键入的Racket**是**静态类型的:类型检查在编译时发生.如果你没有通过Typed Racket类型检查器,它就会拒绝继续.在正常操作下,一旦类型检查通过,Typed Racket将应用优化(http://docs.racket-lang.org/ts-reference/Optimization_in_Typed_Racket.html),如果没有从类型检查中获知的类型保证,这将是不安全的. (6认同)
  • 类型化方案不是静态类型,它提供类型作为错误检查.静态类型拒绝编译,除非编译器可以证明程序是完全类型安全的.类型化方案仍会产生运行时类型错误,在静态类型中这是不可能的. (3认同)
  • @Lajla,是的,虽然我没有说打字方案是静态打字的. (2认同)

Rai*_*wig 13

当Lisp从1958年到1960年发明时,它引入了许多功能,无论是语言还是实现(垃圾收集,自托管编译器......).某些功能是从其他语言继承(有一些改进)(列表处理,...).该语言使用函数实现计算.与语言特征相比,s表达式更像是一个实现细节(当时).类型系统不是语言的一部分.以交互方式使用该语言也是早期实现功能.

功能语言的有用类型系统当时尚未发明.直到今天,以交互方式使用静态类型语言也相对困难.静态类型语言的许多实现也提供了一些交互式接口 - 但是大多数它们不像典型的Lisp系统那样提供相同级别的交互式使用支持.在交互式Lisp系统中进行编程意味着可以随时更改许多内容,如果类型更改必须通过这样的交互式Lisp系统中的整个程序和数据传播,则可能会出现问题.请注意,一些Schemers对这些事情有不同的看法.R6RS主要是一种批处理语言,在Lisp的精神上一般没那么多......

后来使用静态类型系统发明的函数式语言也得到了非s表达式语法 - 它们不提供对宏或相关功能的支持.后来这些语言/实现中的一些使用了语法扩展的预处理器.

  • R6RS中没有描述语言的交互使用语义.例如,EVAL是一个库函数,完全没有指定.实现可能会尝试解决这个问题,但似乎R6RS的作者对交互式使用不感兴趣.因此,没有任何关于库和REPL的讨论.除了所描述语言的技术限制外,一般来说,我对R6RS标准的质量完全不知所措.我希望R7RS变得更好. (5认同)
  • 有意思,你为什么说R6RS主要是一种批处理语言? (2认同)

Zor*_*orf 5

静态类型是词法,它意味着可以从读取源代码推断出有关类型的所有信息,而无需评估任何表达式或计算任何事物,条件在这里是最重要的.设计静态类型语言是为了使这种情况发生,一个更好的术语将是"词法类型",例如,编译器可以通过单独读取源来证明不会发生类型错误.

在lisp的情况下,这是不同的,因为lisp的源代码本身不是静态的,lisp是同构的,它使用数据作为代码,并且可以在某种程度上动态编辑自己的运行源.

Lisp是第一种动态类型语言,可能由于这个原因,程序代码本身在Lisp中不再是词法.

编辑:一个更强大的原因,在静态类型的情况下,您必须键入列表.您可以为每个列表具有极其复杂的类型,这些类型考虑了所有元素,每个元素具有相同类型的需求,并将其键入为列表.前一个选项将产生列表列表的地狱.后一个选项要求源代码仅为每个数据包含相同的类型,这意味着您甚至无法构建表达式,因为列表无论如何都是一个不同于整数的类型.

所以我敢说,实现它是完全不可能的.

  • 这只是困难,而不是不可能.有关反例,请参阅MetaML和MetaOCaml.依赖类型的语言也可以这样做 - 参见Idris中的部分评估实验. (2认同)