Scheme对所有变量使用单个命名空间,无论它们是绑定到函数还是其他类型的值。 Common Lisp将两者分开,使得标识符“hello”可以在一个上下文中引用一个函数,在另一个上下文中引用一个字符串。

(注1:这个问题需要上面的例子;随意编辑并添加一个,或者用原始作者发电子邮件给我,我会这样做。)

但是,在某些情况下,例如将函数作为参数传递给其他函数,程序员必须使用#'明确区分他指定的函数变量而不是非函数变量。 ,如:

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)

我一直认为这有点像疣,但我最近碰到了一个论证这实际上是一个特征:

...的 重要的区别实际上在于形式的语法,而不是形式 对象类型。不知道任何有关运行时值的信息 涉及,很明显,函数形式的第一个元素 必须是一个功能。 CL采用了这一事实并使其成为其中的一部分 语言,以及宏观和特殊形式,也可以(并且必须) 静态地确定。所以我的问题是:你为什么要这样做 函数名称和变量名称相同 命名空间,当主要使用函数名称时出现在哪里 变量名很少想出现?
考虑类名的情况:为什么名为FOO的类会阻止 使用名为FOO的变量?我唯一一次指的是 名称FOO的类位于期望类名的上下文中。如果,开 我需要获得绑定到的类对象的罕见场合 类名FOO,有FIND-CLASS。

这个论点从经验中对我有所帮助; Haskell中有一个类似的字段名称,它也是用于访问字段的函数。这有点尴尬:

data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)

这是通过一些额外的语法解决的, NamedFieldPuns 扩展名特别好:

isOrigin2 Point{x,y} = (x == 0) && (y == 0)

那么,对于问题,超越一致性,Common Lisp vs. Scheme以及一般来说,所有值的单个命名空间与函数和非函数值的单独命名空间有哪些优点和缺点?

有帮助吗?

解决方案

两种不同的方法有名称:Lisp-1和Lisp-2。 Lisp-1对变量和函数都有一个命名空间(如在Scheme中),而Lisp-2有变量和函数的独立命名空间(如在Common Lisp中)。我之所以提到这一点是因为你可能没有注意到这个术语,因为你没有在你的问题中提到它。

维基百科提到这场辩论

  

函数的单独命名空间是否有优势是Lisp社区中的争用来源。它通常被称为Lisp-1 vs. Lisp-2辩论。 Lisp-1指的是Scheme的模型,Lisp-2指的是Common Lisp的模型。这些名字是由Richard P. Gabriel和Kent Pitman在1988年的一篇论文中创造的,后者对这两种方法进行了广泛的比较。

Gabriel和Pitman的论文题为功能细胞和价值细胞分离的技术问题解决了这个问题。

其他提示

实际上,正如 Richard Gabriel和Kent Pitman撰写的论文中所述,争论的焦点是针对Lisp-6的Lisp-5,因为已经存在其他几个名称空间,本文中提到了类型名称,标签名称,块名称和声明名称。 编辑:这似乎是不正确的,正如Rainer在评论中指出的那样:Scheme实际上似乎是一个Lisp-1。但是,以下内容在很大程度上不受此错误的影响。

符号表示要执行的内容或要引用的内容始终从上下文中清楚。将函数和变量抛出到同一名称空间主要是一个限制:程序员不能对事物和动作使用相同的名称。 Lisp-5从中得到的只是避免了从当前上下文暗示的不同命名空间引用某些东西的语法开销。 编辑:这不是整个图片,只是表面。

我知道Lisp-5的支持者喜欢函数是数据的事实,而这是在语言核心中表达的。我喜欢我可以调用列表“列表”的事实。和汽车“汽车”不会混淆我的编译器,而且函数无论如何都是一种基本上特殊的数据。 编辑:这是我的主要观点:单独的命名空间根本不是疣。

我也很喜欢 Pascal Constanza所拥有的说这个。

我在Python(统一命名空间)和Ruby(方法与非方法的不同命名空间)中遇到了类似的区别。在这种情况下,我更喜欢Python的方法 - 例如,使用这种方法,如果我想列出一些事物,其中一些是函数,而另一些则不是,我不需要做任何与它们名称不同的事情。例如,取决于它们的“功能性”。类似的考虑适用于所有情况,其中函数对象被绑定而不是被调用(参数,并从高阶函数返回值等等)。

也可以调用非函数(如果它们的类定义 __ call __ ,在Python的情况下 - “运算符重载”的特殊情况),因此“上下文区别”可以被调用。也不一定清楚。

然而,我的“lisp-oid”经验主要是使用Scheme而不是Common Lisp,所以我可能会因为熟悉统一命名空间而潜意识地偏向于最终来自该体验。

Scheme中函数的名称只是一个函数作为其值的变量。我是否(定义x(y)(zy))(let((x(lambda(y)(zy)))),我正在定义一个我可以调用的函数。因此,就“Scheme”而言,“变量名很少想出现在那里”的想法是一种似是而非。

Scheme是一种特色功能语言,因此将函数视为数据是其原则之一。将函数作为自己的一种类型,与所有其他数据一样存储是一种继承理念的方式。

我看到的最大缺点,至少对于Common Lisp来说,是可理解性。我们都同意它对变量和函数使用不同的命名空间,但它有多少?在PAIP中,Norvig表明它具有“至少七个”的值。命名空间。

当一位由一位备受尊敬的程序员撰写的语言经典书籍之一甚至无法在出版的书中说出来时,我认为存在问题。我对多个名称空间没有任何问题,但我希望该语言至少足够简单,某人可以完全理解它的这一方面。

我很乐意为变量和函数使用相同的符号,但是在更加模糊的区域中,我会因恐惧而使用不同的名称(碰撞名称空间可能很难调试!),这真的应该从来不是这样。

两种方法都有好处。但是,我发现当它重要时,我更喜欢同时使用函数LIST和变量LIST,而不是错误拼写其中一个。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top