Variables Common Lisp和Scheme中函数和变量的单独名称空间

Variables Common Lisp和Scheme中函数和变量的单独名称空间,variables,scheme,lisp,common-lisp,lisp-2,Variables,Scheme,Lisp,Common Lisp,Lisp 2,Scheme对所有变量使用一个名称空间,而不管它们是绑定到函数还是其他类型的值。Common Lisp将两者分开,这样标识符“hello”可以在一个上下文中引用函数,在另一个上下文中引用字符串 (注1:此问题需要上述示例;请随意编辑并添加一个,或通过电子邮件将其发送给原作者,我会这样做。) 但是,在某些上下文中,例如将函数作为参数传递给其他函数,程序员必须使用#'明确区分他指定的是函数变量,而不是非函数变量,如: (sort (list '(9 A) '(3 B) '(4 C)) #'<

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

(注1:此问题需要上述示例;请随意编辑并添加一个,或通过电子邮件将其发送给原作者,我会这样做。)

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

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first) 这可以通过一些额外的语法来解决,尤其是
NamedFieldPuns
扩展:

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

那么,对于这个问题,除了一致性之外,对于通用Lisp与Scheme,以及对于所有值的单个名称空间与对于函数和非函数值的单独名称空间相比,一般而言,它们的优缺点是什么?

我在Python(统一名称空间)与Ruby中遇到了类似的区别(方法的名称空间与非方法的名称空间不同)。在这种情况下,我更喜欢Python的方法——例如,使用这种方法,如果我想列出一些东西,其中一些是函数,而另一些不是函数,我不必根据它们的“函数性”对它们的名称做任何不同的处理类似的考虑也适用于所有函数对象被绑定而不是被调用的情况(高阶函数的参数和返回值等)

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


然而,我的“lisp oid”经验主要是使用Scheme而不是普通的lisp,因此我可能会下意识地对统一名称空间产生偏见,而统一名称空间最终来自于我的经验。

这两种不同的方法有两个名称:lisp-1和lisp-2。lisp-1对于变量和函数都有一个名称空间(在Scheme中)而Lisp-2对变量和函数有单独的名称空间(在Common Lisp中)。我提到这一点是因为您可能不知道术语,因为您在问题中没有提到它

维基百科:

函数的单独名称空间是否是一种优势是Lisp社区争论的一个来源。它通常被称为Lisp-1与Lisp-2之争。Lisp-1指Scheme的模型,Lisp-2指Common Lisp的模型。这些名称是由Richard p.Gabriel和Kent Pitman在1988年的一篇论文中创造的,该论文对这两种方法


Gabriel和Pitman题为《解决这个问题》的论文。

Scheme中函数的名称只是一个变量,函数的值就是这个变量。无论我是
(定义x(y)(zy))
还是
(let((x(lambda(y)(zy)))
,我都在定义一个我可以调用的函数。因此就Scheme而言,“变量名很少会出现在那个里”有点似是而非

Scheme是一种典型的函数式语言,因此将函数视为数据是它的宗旨之一。让函数成为自己的一种类型,并像所有其他数据一样存储,是贯彻这一思想的一种方式。

实际上,正如中所述,争论是关于Lisp-5和Lisp-6的,因为在论文中提到了类型名、标记名、块名和声明名。编辑:正如Rainer在评论中指出的那样,这似乎是错误的:Scheme实际上似乎是一个Lisp-1。不过,以下内容基本上不受此错误的影响

从上下文来看,符号是表示要执行的内容还是要引用的内容总是很清楚的。将函数和变量放入同一名称空间主要是一种限制:程序员不能对某个事物和某个动作使用相同的名称。Lisp-5从中得到的只是refe的一些语法开销避免从与当前上下文暗示不同的名称空间中删除某些内容。编辑:这不是全部,只是表面

我知道Lisp-5的支持者喜欢函数是数据这一事实,这是用语言核心表达的。我喜欢我可以将列表称为“列表”,将汽车称为“汽车”在不混淆我的编译器的情况下,函数从根本上说是一种特殊的数据。编辑:这是我的主要观点:单独的名称空间根本不是一个缺点


我也很喜欢这一点。

这两种方法都有好处。但是,我发现,在重要的时候,我更喜欢同时使用函数列表和变量列表,而不是错误地拼写其中一个。

我看到的最大缺点,至少对于通用Lisp来说,是可理解性。我们都同意它使用不同的名称包在PAIP中,Norvig展示了它“至少有七个”名称空间

当该语言的一本经典著作,由一位备受尊敬的程序员编写,甚至不能在一本已出版的书中肯定地说,我认为这是一个问题。我没有多个名称空间的问题,但我希望该语言至少足够简单,有人能够完全理解它的这一方面


我对变量和函数使用相同的符号感到很舒服,但在更模糊的领域,出于恐惧,我会使用不同的名称(名称空间冲突可能真的很难调试!),这真的不应该发生。

在Ruby中,你可以对方法做或多或少相同的事情:
f=obj.method(:foo)
将为您提供一个
方法
对象,这是一个完全正常的对象。您可以使用
f.call(…)
isOrigin2 Point{x,y} = (x == 0) && (y == 0)