一直没有搞懂,common lisp为什么用把函数和变量放在不同的命名空间?

以前不知道在哪看到说funcall比直接调用略快?也没在意,写习惯了. 最近在写一些racket文档,突然想起这个问题.

当初common lisp为什么把function和变量放在不同的命名空间? 想了些理由,感觉都不成立.难道又是为了吸纳某些方言的历史包袱?

(funcall (intern "dosomething"))

(eval `(,(intern "dosomething")))

纯粹是选择问题,算哪门子历史包袱,你觉得racket那种名字叫list的局部变量不能叫list只能写成lst就开心了?

为什么不能叫 list,只能写 lst?

还有,如果真的 first-class function,为什么不能和其他 variable 一致?

因为list函数被list局部变量覆盖了呀。first class不是这个意思。first class说的是这个东西(函数)可以作为变量传递。

可以算黑点吧(毕竟 lisp 应该是自由的)

既然 first-class 了,为什么还要在 namespace 区分呢?我一直没明白这点(另外可以参考 Indiana style)

不太清楚这跟自由有啥关系,如cireu所说,这就是个选择问题。强行说的话,多个命名空间显然比单个更自由。我认为单个还是多个命名空间和first class与否没有关系。我没找到indiana style的相关信息,指的是什么?

你说对了,为了和 lisp machine lisp 和 MacLisp 兼容。至于 MacLisp 为什么分开,是因为 lisp 一开始就没设计 first class function,只能通过函数名来调用函数。

当然有关系,first-class function 就是可以和其他类型的值一样使用的。那为什么要和其他变量写法不同?

Indian style 是一种写 Scheme 的风格,定义函数时候不会用 define 的糖,而是这样:

(define foo
  (lambda (x)
    blahblah))

这样显然更能体现 functions as first-class value。 不敢相信在一种把变量和函数去分开的语言里使用这样一种编写风格。

写法不同是指什么?有例子吗

语法糖的话,我觉得就是语法糖而已…你最多可以说表现了语言哲学

谁说的?JMC 从没说过,RMS 应该也没公开说过这种,更何况他从来没管过 Common Lisp,那会已经投身 GNU 事业了。G. Steele Junior 更不可能说这种话。

我认为给编程语言搞这种意识形态的都是屑用户。

不存在呀,cl也没人会写个这样的东西吧…

(defun abc (list) (list list))

丑爆.

刚发完就在想哈,两个名称空间相当于两个表,function只在自己的命名空间找当然比较快.

问题是语法就有点丑了,普通符号和函数名称不在同一个地方,函数内部传的参只能被funcall,返回一个labels或者flet定义的函数还是只能被funcall,且都不用#’;内部还好,返回到外部的话,依然funcall且不加#’,外部定义的就得#’.

虽然说理解起来很简单,但总觉得没有多大必要吧,毕竟如果写教程,就这事儿你也得写个几百字,而且新手一来我勒个去全是坑,就听着slime Duang Duang Duang跳了:rofl:.

你是云用户?

(flet ((foo () nil)) (foo)) ; => nil
(flet ((foo () nil)) (funcall 'foo)) ; => nil
(flet ((foo () nil)) (funcall #'foo)) ; => nil

请问你见到个函数定义

(defun foo (a b c) ...)

没有/不看文档你怎么判断它接受什么类型的参数?

这是我觉得 Scheme 做的比较有问题的地方,参数名不好随便取,用单个字母又不能做到文档作用,还没有 docstring。

同样是函数式,SML, Haskell,可以用类型来做文档,而不用花心思起参数名。它们就只有一个命名空间了?并不,它们有 函数/变量、类型、数据构建 三个 命名空间

1 个赞

原来如此.感谢. 之前觉得lisp写起来很舒服呀,想安利给某些人结果啪啪啪打脸说玩不转.整理下才发现好像对新手来说坑还蛮多的.

Common Lisp 就算不要求去看语言标准,至少也得看个 ANSI Common Lisp 这书吧。最主要的是自己还没有会用就随便安利别人实在不是好习惯,我感觉包括我自己很多人都做过这种事。

1 个赞

不是这种,昨天看到同事按scheme思路写的东西,大概是在看sicp里面的dispatch:

(defun foo () (flet ((bar () 'bbb)) #'bar)

(defvar abc (foo))

然后来问为什么(abc) , (funcall #‘abc) , (funcall #’(foo)) 都报错,以及(defun ijk (foo))为什么也不行…

然后才突然想问这个问题,仔细想想两个命名空间好像没多大必要.

(fset 'abc (foo)) ;; 或
(setf (symbol-function abc) (foo))

不就行了

太对了!

Lisp 就等于「创始人」的 Lisp。他们说的才是 Lisp 的特质,普通用户的感受都是屑哦。(我认为 Lisp 里 id 的选择应该是没有干扰的,就怎么就跳跃到意识形态了??)

哦,好像 John McCarthy 当年做的 LISP,还有他心中的 LISP 和今天差别巨大。管他呢,历史悠久,大佬正名就完事了

名字还是尽量有意义吧,abc只能在淘宝接一次性的活:joy:(逃

我已经把 Scheme Clojure 之类的开除 LISP 籍了,你们不要用 LISP 方言这种词招摇撞骗了,Common Lisp 以后不用再重新发明 LISP 了。再发明 LISP 或者声称自己用的语言是 LISP 的都是屑