问个入门问题,关于rest参数
(defun fun1 (a &rest b)
...)
(defun fun2 (c &rest d)
...)
fun2 内部调用fun1的话,rest参数如何展开?
(defun fun2 (c &rest d)
(fun1 c d) ;; <= 直接这么调用不对吧?
(fun1 c ...d) ;; ?? <= 也不通
...)
问个入门问题,关于rest参数
(defun fun1 (a &rest b)
...)
(defun fun2 (c &rest d)
...)
fun2 内部调用fun1的话,rest参数如何展开?
(defun fun2 (c &rest d)
(fun1 c d) ;; <= 直接这么调用不对吧?
(fun1 c ...d) ;; ?? <= 也不通
...)
(defun fun2 (c &rest d)
(apply 'fun1 c d))
好的,谢谢!一看就明白,但还不能熟练运用,和scheme不太一样。
我寻思 Emacs Lisp 也有 ,@
啊。
(eval `(fun1 c ,@d))
我现在处在学习中,还不能融会贯通,scheme我也只是做过练习。所以,对于lisp系语言,我还是新手。
有空的时候,就花点时间练习一下。目前在看awesome-pair的代码,并对齐进行重构,再改进一下。等重构完了,再追加新功能。每天没法花太多时间在lisp上,只能慢慢整。有几个我想要的功能,它没提供,所以,就从它入手。
我寻思我用的chez-scheme也有apply
啊
大家不觉得scheme写起来,同样功能,代码量比cl多吗?
因为CL有一揽子特性。而且scheme的函数名普遍比较详细,不像cl那样基本就是魔法字符
比如说string->symbol
vs. intern
RSR7现在没动静了吧?反正,大部分人是写elisp,规模不大。一般应用,还是golang,rust实用些。
啥,Scheme 也有 &rest
啊
(define (fun1 a . b) ...)
为啥要用 eval
这两个完全不是一回事好吗,string->symbol
对标的是 make-symbol
,intern
比这两个多了 make symbol intern(al) to obarray ,某些 Scheme 实现也有 intern
procedure,当然 Scheme 在标准设计上故意不让用户像 Lisp 那样直接用 String 存取 environment。同理因此 Scheme 不用 eval 也做不到 (funcall 'foo)
早就写完了,R8RS 都在出了。
不太懂Scheme标准设计,只能从实现上猜测用途。所以我看guile和chez都把string->symbol
实现成类似intern
的方式,就想当然了。(guile的uninterned symbol用make-symbol
,chez倒是只有gensym
)
Scheme 只规定了 eq?
的很少的语义,没有规定 eq?
一定就是指针比较,也没规定什么是 intern 以至于 Chez 有个很诡异的特性。
> (set! sym (gensym))
> sym
#{g2 xz2wmui56faib0eyhaxb0-2}
> (eq? sym '#{g2 xz2wmui56faib0eyhaxb0-2})
#t
> (gensym? '#{foo 123})
#t
也就是说 gensym 的结果是 interned。或者说,其实直接把 eq?
实现成比较字面量而不是指针都不会有问题。
更绝的是 Chez 还能“更改事实”
> (gensym)
#{g0 ydx6vbp8s4eovam4munk2-0}
> '#{g1 ydx6vbp8s4eovam4munk2-1}
#{g1 ydx6vbp8s4eovam4munk2-1}
> (eq? '#{g1 ydx6vbp8s4eovam4munk2-1} '#{g1 ydx6vbp8s4eovam4munk2-1})
#t
> (set! foo '#{g1 ydx6vbp8s4eovam4munk2-1})
> (eq? foo '#{g1 ydx6vbp8s4eovam4munk2-1})
#t
> (set! bar (gensym))
> bar
#{g1 ydx6vbp8s4eovam4munk2-1}
> (eq? bar foo)
#f
> (eq? bar '#{g1 ydx6vbp8s4eovam4munk2-1})
#t
> (eq? foo
'#{g1 ydx6vbp8s4eovam4munk2-1})
#f
> foo
#{g1 ydx6vbp8s4eovam4munk2-1}
在 CL 中,标准严格定义了 gensym 和 intern 的概念。
(eq '#:foo '#:foo) ;; => nil
&rest args
就是一个 List
不一定,你也没说 fun1
的参数必须和 fun2
一致。
(defun foo (&rest r)
r)
((lambda (&rest r) (foo r)) 1 2 3)
;; => ((1 2 3))
((lambda (&rest r) (apply #'foo r)) 1 2 3)
;; => (1 2 3)
(eval ((lambda (&rest r) (cons 'foo r)) 1 2 3))
;; => (1 2 3)
我说要把参数“展开”了,从语法的角度,(fun1 c d)
我知道是正确的。不过“展开”这个术语是否准确,就不清楚了。
从应用开发的角度,极少有人用cl或scheme开发。scheme做这个标准,是为了以后进军传统的开发市场?
大家学它们主要做什么?我现在也就写写elisp。
反正可以吧,多传个environment就是Scheme代码了。
和应用开发基本没关系,Scheme 本来就是用来研究 actor model 和 lambda calculus 的语言,现在也用来研究 meta programming 和编译器。
真要说应用的话,Scheme 是用来做胶水语言和脚本语言的。类似于 Python 的位置。
听说做的比较好的是chez,但它目前只支持到r6rs。
又处在什么位置呢?
开源以后没人管了。
Chez 就是设计用来做胶水语言的。