lisp缺少哪些功能?

时间:2010-02-28 10:42:21

标签: lisp language-features

我读过大多数语言变得越来越像lisp,采用了lisp长期以来的功能。我想知道,lisp没有什么功能,无论是旧功能还是新功能?通过lisp我的意思是最常见的方言,如Common Lisp和Scheme。

9 个答案:

答案 0 :(得分:10)

这个问题已被问过一百万次了,但是这里有。 Common Lisp是在人们被认为是廉价的时候创建的,并且机器被认为是昂贵的。 Common Lisp使人们更容易,而不是让计算机变得更难。 Lisp机器价格昂贵;有DOS的电脑很便宜。这对它的受欢迎程度不利;与购买更好的计算机相比,用更少表达的语言让更多的人犯错误。

快进30年,事实证明这不是真的。人类非常非常昂贵(并且供应非常短缺;尝试雇用程序员),而且计算机非常便宜。甚至比污垢便宜。今天的世界需要正是Common Lisp所提供的;如果现在发明了Lisp,它会变得非常受欢迎。然而,由于它已经有30年历史了(加上!)技术,没有人想过要看它,而是用类似的概念创建自己的语言。那些是你今天使用的那些。 (Java +垃圾收集是一项重大创新。多年来,GC一直被视为“太慢”,但当然,一点点研究,现在它比管理自己的内存更快 对人类来说也更容易。时代如何变化......)

答案 1 :(得分:7)

  • 传递引用(C ++ / C#)
  • 字符串插值(Perl / Ruby)(虽然是CL21的一个特性)
  • 漂亮的中缀语法(虽然不太清楚它是否值得)(Python)
  • Monadic'迭代'构造,可以重载用于其他用途(Haskell / C#/ F#/ Scala)
  • 静态打字(虽然不清楚它是否值得)(多种语言)
  • 类型推断(至少不在标准中)(Caml和许多其他)(尽管CL做了一些类型推断,与Python不同)
  • 抽象数据类型(Haskell / F#/ Caml)
  • 模式匹配(Haskell / F#/ Caml / Scala /其他)(在CL中,有像optima这样的库)
  • 回溯(虽然不清楚它是否值得)(Prolog)
  • ad-hoc polymorphism (参见Andrew Myers的回答)
  • 不可变数据结构(多种语言)(可通过库获取,如Fsets
  • 懒惰评估(Haskell)(可通过库获取,如clazycl21 module

(请添加到此列表中,我已将其标记为社区维基。)

这只是指Common Lisp和Scheme标准,因为特定的实现已经独立地添加了许多这些功能。事实上,这个问题有点误。向Lisp添加功能非常容易,因为拥有一个没有很多功能的核心语言,更好。这样,人们可以自定义他们的语言,以完全满足他们的需求。

当然,有些实现将核心Lisp与一堆这些功能打包为库。至少对于Scheme,PLT Scheme提供了所有上述功能*,主要是作为库。我不知道Common Lisp的等价物,但可能有一个。

*也许不是中缀语法?我不确定,我从来没有找过它。

答案 2 :(得分:3)

对于Common Lisp,我认为以下特征值得添加到未来的标准中,在另一个标准产生的极其不可能的假设情况下。所有这些都是由几乎所有主动维护的CL实现以微妙的不兼容方式提供的,或存在于广泛使用的可移植库中,因此拥有标准将为用户提供显着的好处,同时不会使实现者的生活变得过于困难。 / p>

  • 使用底层操作系统的一些功能,例如调用其他程序或处理命令行参数。我使用的CL的每个实现都有类似的东西,并且它们都非常相似。

  • BACKQUOTEUNQUOTEUNQUOTE-SPLICING的基础宏或特殊表格。

  • CLOS的元对象协议。

  • 用户定义的LOOP子句的协议。还有一些其他方式可以增强LOOP,这可能不会太痛苦,比如绑定多个值的子句,或迭代一般序列(而不是LIST s需要不同的子句和VECTOR s)。

  • PROVIDEREQUIRE集成的系统定义工具,同时取消激活PROVIDEREQUIRE

  • 更好,更可扩展的流设施,允许用户定义自己的流类。这可能会有点痛苦,因为有两个竞争的提议,灰色流和“简单流”,这两个都是由一些CL实现实现的。

  • 更好地支持“环境”,如CLTL2中所述。

  • 合并尾调用的声明和对看起来像尾调用的调用的情况的描述(因为UNWIND-PROTECT形式,DYNAMIC-EXTENT声明,特殊变量绑定等等角)。

  • 取消预订REMOVE-IF-NOT和朋友。消除:TEST-NOT关键字参数和SET

  • 弱引用和弱哈希表。

  • 用户提供的哈希表测试。

  • PARSE-FLOAT。目前,如果要将字符串转换为浮点数,则必须使用READ(可能会执行各种不需要的操作)或滚动自己的解析函数。这太傻了。

以下是一些我认为值得的雄心勃勃的功能。

  • 用于定义将与标准通用序列函数(如MAPREMOVE和朋友)一起使用的序列类的协议。添加不可变的字符串和conses以及它们的可变亲属也可能很好。

  • 提供更丰富的关联数组/“地图”数据类型。现在我们有一些由conses(alists和plists)和hash-tables构建的ad-hoc东西,但是没有平衡的二叉树。提供通用序列函数来使用它们。

  • 修复DEFCONSTANT所以它做了一些不那么无用的东西。

  • 更好地控制读者。它是一个非常强大的工具,但必须非常小心地使用它,以避免做一些新的符号实习。此外,如果有更好的方法来管理readtables和自定义阅读器语法,那将是很好的。

  • “原始字符串”的读取语法,类似于Python提供的内容。

  • CLOS类和插槽的更多选项,允许更多优化和更好的性能。一些示例是“主要”类(在类的超类列表中只能有一个“主类”),“密封”泛型函数(因此您无法向它们添加更多方法,从而允许编译器生成很多关于它们的更多假设)和保证受约束的插槽。

  • 线程支持。大多数实现现在都支持SMP,或者在不久的将来支持它。

  • 指出更多的路径名行为。实现之间存在许多无端的烦恼不兼容性,例如CLISP在目录上使用PROBE-FILE时发出错误信号,或者事实上没有标准函数告诉您路径名是否是名称目录与否。

  • 支持网络套接字。

  • 常见的外部函数接口。这将是不可避免的最低共同点,但我认为有一些你可以依赖的东西将是一个真正的优势,即使使用一些实现提供的一些较酷的东西仍然会降级到扩展领域。

答案 3 :(得分:2)

这是对Nathan Sanders回复中的评论中的讨论的回应。这有点评论,所以我在这里添加它。我希望这不违反Stackoverflow礼仪。

ad-hoc多态定义为基于指定类型的不同实现。在使用泛型方法的Common Lisp中,您可以定义类似下面的内容,它们可以为您提供完全相同的内容。

;This is unnecessary and created implicitly if not defined.  
;It can be explicitly provided to define an interface.
(defgeneric what-am-i? (thing))

;Provide implementation that works for any type.
(defmethod what-am-i? (thing)
  (format t "My value is ~a~%" thing))

;Specialize on thing being an integer.
(defmethod what-am-i? ((thing integer))
  (format t "I am an integer!~%")
  (call-next-method))

;Specialize on thing being a string.
(defmethod what-am-i? ((thing string))
  (format t "I am a string!~%")
  (call-next-method))


CL-USER> (what-am-i? 25)
I am an integer!
My value is 25
NIL
CL-USER> (what-am-i? "Andrew")
I am a string!
My value is Andrew
NIL

答案 4 :(得分:1)

  • 找到好的图书馆比使用更流行的语言更难。
  • 它不像haskell那样纯粹的功能

答案 5 :(得分:1)

  • 整个程序转换。 (它就像宏,但是对于一切。您可以使用它来实现声明性语言功能。)等效地,能够将附加组件写入编译器。 (至少,Scheme错过了.CL可能不是。)
  • 内置定理助手/证明检查器,用于证明您的程序断言。

当然,我不知道有任何其他语言,所以我认为在功能方面没有太多的竞争。

答案 6 :(得分:0)

你在问这个问题。具有最多功能的语言不是最好的。语言需要一个目标。

我们可以添加所有这些以及更多

* Pass-by-reference (C++/C#)
* String interpolation (Perl/Ruby)
* Nice infix syntax (though it's not clear that it's worth it) (Python)
* Monadic 'iteration' construct which can be overloaded for other uses (Haskell/C#/F#/Scala)
* Static typing (though it's not clear that it's worth it) (many languages)
* Type inference (not in the standard at least) (Caml and many others)
* Abstract Data Types (Haskell/F#/Caml)
* Pattern matching (Haskell/F#/Caml/Scala/others)
* Backtracking (though it's not clear that it's worth it) (Prolog)
* ad-hoc polymorphism (see Andrew Myers' answer)
* immutable data structures (many languages)
* lazy evaluation (Haskell)

但这会成为一种好语言。如果您使用ref的调用,则语言不起作用。

如果你看一下新的名单Clojure。其中一些已经实现,但CL没有实现,这是一个很好的语言。

Clojure例如增加了一些:

ad-hoc多态性 懒惰的评价 不可变数据结构 类型推断(大多数动态语言都有编译器)

我的回答是:

计划受教育的原样。 CL可以为标准添加一些ideo,如果它们会创建一个新的。

它的LISP最多可以添加libs。

答案 7 :(得分:-1)

体面的语法。 (有人不得不说。)它可能是简单/统一/同性/宏观/等等,但作为一个人,我只是厌恶看着它:)

答案 8 :(得分:-3)

它缺少一个出色的IDE