在C型语言中,从一开始和每本入门书中都非常强调结构/记录和对象。然后,围绕管理此类结构,相互关系和继承来设计它们的完整系统。
在Lisp文档中,通常可以找到1-2页,关于Lisp“也”如何具有defstruct,一个简单的示例,通常就是这样。而且,根本没有提到结构的嵌套。
对于有C背景的人来说,首先看起来分层组织不同的数据类型并不是Lisp的首选方法,但是除了CLOS(这是一个成熟的对象系统,如果您只想使用结构,它太复杂了)之外,除了使一切陷入困境之外,到列表中,没有一种明显的方式来传递您的C结构知识。
Lisp最常见的类似于C结构的分层组织数据的Lisp方法是什么?
-
我认为我的问题的简要答案将是:为了初学者学习,可以使用defstruct和/或plists,尽管“传统功能”由于与C结构最相似,但是被更多的C结构所取代。灵活的defclass / CLOS,今天大多数Lisp程序都使用。
这是我关于SO的第一个问题,因此感谢大家的宝贵时间。
最佳答案
使用CLOS。这并不复杂。
否则使用结构。
如果您对如何使用它们有特定疑问,请询问。
(defclass point ()
((x :type number)
(y :type number)))
(defclass rectangle ()
((p1 :type point)
(p2 :type point)
(color :type color)))
这样的东西最终会导致出现诸如Rectangles in CLIM(Common Lisp接口(interface)管理器)之类的接口(interface)。
历史
进一步扩展一下:历史上,“结构”已用于某些低级别的情况。结构具有单一继承,并且插槽访问“快速”。一些Lisp方言的结构比Common Lisp提供的更多。从70年代中期开始,为Lisp开发了各种形式的面向对象的表示形式。结构化对象的大多数表示形式都从结构转移到某种面向对象的Lisp扩展。在80年代流行的是基于类的系统,例如Flavors,LOOPS等。基于框架或基于原型(prototype)的系统(例如KEE Units或Object Lisp)也很流行。第一个Macintosh Common Lisp将Object Lisp用于其所有UI和IO功能。 MIT Lisp机器基本上在所有地方都使用Flavors。从80年代中期开始开发ANSI CL。专门为Common Lisp开发了一个通用的OO系统:CLOS。它基于口味和圈。在那段时间里,几乎没有采取任何措施来真正改善结构-除了实现者们发现了改进实现并提供浅层CLOS集成的方法。例如,结构不提供任何数据打包。如果有两个4位内容的插槽,则无法指示Common Lisp将两个插槽编码为单个8位存储区。
例如,您可以在Lisp Machine Manual, chapter on structures (PDF)中看到,它的结构比Common Lisp提供的结构复杂得多。其中一些已经在70年代的Maclisp中出现:DEFSTRUCT in the Maclisp manual。
CLOS,通用Lisp对象系统
大多数人会同意CLOS是一个不错的设计。有时会导致“更大”的代码,主要是因为标识符会变长。但是有一些CLOS代码,例如AMOP书中的代码,确实写得很好,并显示了应如何使用它。
随着时间的流逝,实现者不得不应对开发人员想要使用CLOS的挑战,但同时也想要拥有结构的“速度”。对于“完整” CLOS,这甚至是一项任务,其中包括用于CLOS的几乎标准的元对象协议(protocol)(MOP)。因此,实现者提供了一些技巧。在80年代,某些软件使用了开关,因此可以使用结构或CLOS-CLX进行编译(低级Common Lisp X11接口(interface)就是一个示例)。原因:在某些计算机和实现上,CLOS比结构慢得多。今天,提供这样的编译开关已经不寻常了。
如果今天我看一个很好的Common Lisp实现,我希望它几乎在所有地方都使用CLOS。流是CLOS类。条件是CLOS类。 GUI工具箱使用CLOS类。编辑器使用CLOS。甚至可以将外部类(例如,Objective C类)集成到CLOS中。
在任何非玩具Common Lisp实现中,CLOS都是提供结构化数据,通用行为和许多其他东西的工具。
如在其他一些答案中所述,在某些地方可能不需要CLOS。
Common Lisp可以从一个函数返回多个值:
(defun calculate-coordinates (ship)
(move-forward ship)
(values (ship-x ship)
(ship-y ship)))
可以将数据存储在闭包中:
(defun create-distance-function (ship x y)
(lambda ()
(point-distance (ship-x ship) (ship-y ship) x y)))
对于配置,可以使用某种列表:
(defship ms-germany :initial-x 0 :initial-y 0)
您可以打赌,我将在CLOS中实现飞船模型。
编写和维护CLOS软件的一个教训是,需要精心设计CLOS,CLOS如此强大,以至于可以使用它创建非常复杂的软件-复杂度通常不是一个好主意。重构和简化!幸运的是,对于许多任务而言,基本的CLOS功能就足够了:DEFCLASS,DEFMETHOD和MAKE-INSTANCE。
指向CLOS简介的指针
首先,Richard P. Gabriel的CLOS papers可供下载。
另请参阅:
关于c - Lisp中C结构的惯用等效词是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4546118/