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

发布于 2024-10-21 03:29:09 字数 274 浏览 1 评论 0原文

我很惊讶地发现 Hacker News 的源代码只是一个包含函数定义的平面列表的大文件。 Git 中心 - news.arc

这对于函数式编程来说是典型的吗?像 OOP 项目中常见的那样,在潜在较深的目录结构中包含大量短文件的源代码是否不常见?

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

I was surprised to see that the source code for Hacker News is just one big file containing a flat list of function definitions.
Git Hub - news.arc

Is that typical for functional programming? Is it uncommon to have source in a lot of short files in a potentially deep directory structure as is common in OOP projects?

Are modules in FP the same thing as namespaces in OOP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你在看孤独的风景 2024-10-28 03:29:09

函数式编程语言 (FPL) 有很多种,而且它们各不相同。 Lisp 方言(如Scheme、Common Lisp、Logo、Arc 等)也是如此。

它们通常不是围绕类(或类似概念)组织的,并且类通常不与名称空间混为一谈。

在某些面向对象语言中,程序由许多类组成,类层次结构(或类似的东西)映射到目录结构,每个类都是一个或多个文件。这导致软件系统由许多文件和一个以层次结构形式浏览这些文件/类的 IDE 组成。 (这与原来的Smalltalk不同,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)

上面的列表告诉我,这些符号中的每一个都有定义的功能,并且带有单个冒号的符号是“导出的”。

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

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

There are many Functional Programming Languages (FPL) and they are very different. As are Lisp dialects (like Scheme, Common Lisp, Logo, Arc and others).

Often they are not organized around classes (or similar concepts) and classes are often not conflated with namespaces.

In some object oriented languages programs are composed of a lot of classes, the class hierarchy (or something similar) gets mapped to the directory structure and each class is one or more files. This leads to software systems composed of many files and an IDE that browses these files/classes as a hierarchy. (this is different from the original Smalltalk, where code is accessed by browsers and not retrieved based on files).

In Common Lisp for example, classes are not namespaces and methods are not attached to single classes (since there are multi-methods). There is a separate construct called 'package' which provides namespaces for Lisp symbols. There a typical software system is composed of files which bundle several related functionalities. Typically a larger unit of functionality gets its own namespace.

For example a graphics toolkit may have several namespaces: ui-backend, ui-user, ui-system, ui-drawing, ui-animation. The ui-drawing namespace may be used in several files: ui-draw-2d-objects.lisp, ui-draw-3d-objects.lisp, ui-draw-macros.lisp and more. A single file ui-draw-2d-objects.lisp would bundle all classes, methods and variables needed to draw 2d objects (lines, polygons, circles, bitmaps, ...).

The development system then is responsible to provide navigation. But often the navigation is not hierarchical, but based on searching and retrieving symbols. Then it is not really important how large files are. It is more important that files group the right functionality and are internally organized such that related functionality can be identified in some way.

If I want for example to identify all rectangle drawing functions I would then use the REPL.

In LispWorks the drawing primitives are in the package "GP" or "GRAPHICS-PORTS". I can then ask LispWorks to tell me all symbols which contain "draw-rect" in the package "GP".

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)

Above list tells me that each of these symbols has a defined functionality and the ones with the single colon are 'exported'.

Then I can use these symbols to find more information: the argument list, the source code, the documentation and more. Common Lisp even provides standard functions like DOCUMENTATION, DESCRIBE and ED.

Thus developing here is not based on lots of small files organized to some class hierarchy, but as a hierarchy of modules and namespaces, with each namespace bundling a larger amount of functionality stored in one or more files. The IDE is then responsible to support non-hierarchical browsing and searching.

与风相奔跑 2024-10-28 03:29:09

不,模块化编程在 FP 中也很常见。模块化的一般原则同样适用。

例如,在 Haskell 中,您可以说

import qualified Parsec as P

which 为您提供了命名空间 P 中的 Parsec 解析库。

模块和命名空间是否“与 OOP 中的命名空间相同”取决于您的函数式语言和 OOP 语言。 (ML 模块与其他语言有点不同。)

No, modular programming is quite common in FP as well. The same general principles of modularity apply.

In Haskell, for example, you can say

import qualified Parsec as P

which gives you the Parsec parsing library in the namespace P.

Whether modules and namespaces are the "the same thing as namespaces in OOP" depends on your functional language and your OOP language. (ML modules are a bit different from other languages.)

蓝色星空 2024-10-28 03:29:09

实现语言为Arc,其中简洁是一个主要的设计目标。 news.arc 包含在 Arc 发行版中,很可能旨在通过将有用的应用程序打包在单个源文件中来演示这种简洁性。

这种打包并不一定代表函数式编程中的常见做法,尽管如programm/5278728#5278728">@Rainer 指出 (+1),文件边界在函数式编程环境中通常不太重要。

The implementation language is Arc, in which succintness is a major design goal. news.arc is included in the Arc distro, and may well be intended as a demonstration of that succintness by packaging a useful application in a single source file.

Such packaging is not necessarily indicative of common practice in functional programming, although as @Rainer points out (+1), file boundaries are often less important in functional programming environments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文