这回是你云了吧
Elisp为了模拟这个诡异的行为还费了不少心思
这回是你云了吧
Elisp为了模拟这个诡异的行为还费了不少心思
我说了外面有 defun 了么?
我只说了 flet labels 定义的局部函数,用不用 funcall,加不加 #’ 都能调用。
Emacs 要特殊处理不过是因为 emacs lisp 里 #’ 和 quote 在多数情况下作用几乎是等价的。而 Common Lisp 里的作用是返回函数指针罢了
你那里举的例子就很有迷惑性好吧。
用elisp是因为他用macro实现的,看起来比较具象化。
另外用funcall的话不用sharpquote还就不能调用。如果没有defun那个fun
(flet ((fun () 1)) (funcall 'fun))
会报错
帮你举了,quote和sharpquote在flet系(flet*, labels)里语义还是有丁点不同的。
那得怎么举?
所以为啥funcall函数对象和符号还有区别?
因为变量和函数在两个命名空间… 然后,defvar一个变量,然后你可以把匿名函数丢给它,但变量名不在函数那块儿,(function xx)取不到值,也无法(xx )直接调用,得(funcall xx)。这在把函数当参数传的时候经常用。
labels的作用,在scheme里基本可以靠let实现的(当然scheme 局部define就好了,还少一个缩进代码更整齐),cl因为函数要单独放#'能取到,所以let和labels flet都有。
Description:
funcall applies function to args . If function is a symbol , it is coerced to a function as if by finding its functional value in the global environment .
本来在 MacLisp 和 Emacs Lisp 类似,是没有 #’ 的,Lisp Machine 上实现成有区别了,于是 CL 标准就定义成这样了。Lisp Machine 这样做的理由是 #’ 可以编译时确定,’ 是运行时的,为了效率只看 global binding。
所以你不知道 Scheme 的 letrec 是干啥的?
嘛,本来想说“要不我改掉labels” 或者 “let系嘛,哈哈哈哈flet系好了”。 不过letrec不用也罢。
(let ((balala 'i-am-null))
(let ((oh-my-balala (lambda (n)
(if (= n 0)
"Zzzzz...."
(balala (- n 1))))))
(set! balala oh-my-balala)
(balala 10)))
不想用 letrec
用 define
不就行了
(define (test)
(define (fib x)
(case x
[0 1]
[1 1]
[else (+ (fib (1- x)) (fib (- x 2)))]))
fib)
(test)
;; #<procedure fib>
fib
;; Exception: variable fib is not bound
这就赖皮了,说好let。
scheme就这儿好,东西少包也少,太大的的事儿干不了,拿来实现各种实用函数,简单明了。
搞不好再过十几年,剩下的lisp只有scheme…
现实中的fib绝对不会是那样的定义
只能说是个玩具
有缓存结果的方法吗? 虽说和letrec没关系,我觉得还是普及一下比较好!
你不普及 我不勉强 大家可以看 RealWorldOcaml 里的例子
可以用fib stream(惰性求值),写出来和naive的长得差不多。
尾递归呀 不格式化了哈好麻烦
(define (fib n)
(define (iter a b counter)
(if (= counter 0)
b
(iter (+ a b)
a
(- counter 1))))
(iter 1 0 n))
那 fib 250 之后 再求 fib 251 他是不是秒回呢?
naive 是什么样子的呢?
naive 就是我写的那个
fib stream 用 Haskell 写就是
fib = map fib' [0..] !!
where fib' 0 = 1
fib' 1 = 1
fib' n = fib (n-1) + fib (n-2)
Haskell 多了层 CAF 就会自动 mem 了。虽然咋看起来很方便,不过偶尔也会导致内存泄漏罢了。
我不写尾递归是因为 Axiom/FriCAS 不需要任何 hint 就能自动把 naive 版本转化成 loop。而且 mem 也是自动做的。你们用笨蛋编译器管我什么事咯。
不看好,因为 Scheme 的特性导致不会有什么 Scheme 写的项目能长久留存。而且我看这社区的尿性再过几年 Scheme 就把自己开除 Lisp 了。Scheme 和 Prolog, SML, Haskell 一样,都是一开始用 Lisp 实现的语言,你看这三个现在哪有标榜自己是 Lisp 的?
顺带,letrec
是 primitive,mutation 反而是可以避免的万恶之源。
好吧 出现了个新的问题
有谁能讨论 Haskell 吗?
看完紫书就可以看 functional pearls 了,讨论无意义,就是为了自己爽罢了。自从我发现语出惊人之流自己也不能免俗,(比如 PG 发明了 Blub Paradox 吹 macro,结果自己还是不免对 OOP 有偏见,再比如某yin)我就不怎么管自己说了什么了。