函数式编程中的多个源文件,目录结构和命名空间

Jon*_*lus 7 lisp functional-programming arc-lisp

我很惊讶地看到Hacker News的源代码只是一个包含功能定义的平面列表的大文件. Git Hub - news.arc

那是函数式编程的典型吗?在OOP项目中常见的深层目录结构中有很多短文件来源是不常见的吗?

FP中的模块是否与OOP中的命名空间相同?

Rai*_*wig 5

有许多函数式编程语言(FPL),它们非常不同.和Lisp方言一样(如Scheme,Common Lisp,Logo,Arc等).

它们通常不是围绕类(或类似概念)组织的,并且类通常不与命名空间混淆.

在一些面向对象的语言中,程序由许多类组成,类层次结构(或类似的东西)被映射到目录结构,每个类是一个或多个文件.这导致由许多文件组成的软件系统和将这些文件/类作为层次结构浏览的IDE.(这与原始的Smalltalk不同,后者的代码由浏览器访问,而不是基于文件检索).

例如,在Common Lisp中,类不是名称空间,方法不附加到单个类(因为有多个方法).有一个名为'package'的独立构造,它为Lisp符号提供名称空间.典型的软件系统由包含若干相关功能的文件组成.通常,较大的功能单元获得其自己的命名空间.

例如,图形工具包可能有几个名称空间:ui-backend,ui-user,ui-system,ui-drawing,ui-animation.ui-drawing命名空间可用于多个文件:ui-draw-2d-objects.lisp,ui-draw-3d-objects.lisp,ui-draw-macros.lisp等.单个文件ui-draw-2d-objects.lisp将捆绑绘制2d对象(线,多边形,圆形,位图等)所需的所有类,方法和变量.

然后开发系统负责提供导航.但通常导航不是分层的,而是基于搜索和检索符号.那么大文件是多么重要.更重要的是,文件对正确的功能进行分组,并在内部进行组织,以便以某种方式识别相关功能.

如果我想要例如识别所有矩形绘图函数,那么我将使用REPL.

在LispWorks中,绘图原语位于包"GP"或"GRAPHICS-PORTS"中.然后,我可以让LispWorks告诉我包"GP"中包含"draw-rect"的所有符号.

CL-USER 10 > (apropos "draw-rect" "GP")
GRAPHICS-PORTS::%DRAW-RECTANGLE (defined)
GRAPHICS-PORTS::DRAW-RECTANGLE-BOUNDS (defined)
GRAPHICS-PORTS::%DRAW-RECTANGLES (defined)
GRAPHICS-PORTS::DRAW-RECTANGLES-BOUNDS (defined)
GRAPHICS-PORTS:DRAW-RECTANGLES (defined)
GRAPHICS-PORTS:DRAW-RECTANGLE (defined)
Run Code Online (Sandbox Code Playgroud)

上面的列表告诉我,这些符号中的每一个都具有已定义的功能,并且具有单个冒号的符号被"导出".

然后我可以使用这些符号来查找更多信息:参数列表,源代码,文档等.Common Lisp甚至提供标准功能,如DOCUMENTATION,DESCRIBE和ED.

因此,这里的开发不是基于组织到某个类层次结构的许多小文件,而是基于模块和命名空间的层次结构,每个命名空间捆绑存储在一个或多个文件中的大量功能.然后,IDE负责支持非分层浏览和搜索.