不得不说,学了sicp后对编程有了很多理解,也越来越喜欢Scheme,不过我觉得Clojure中的一些工具宏挺好用,但到了Scheme我不会重写一遍 (Scheme中的宏sicp里没有讲) 现在我想在Scheme中实现->>和->,不怎么熟悉Scheme中的宏,请教各位,谢谢
论坛有关于 threading 宏的讨论: 分享:让 Common Lisp 代码更简洁可读性高一些~
Racket 里有一个 threading 的实现:https://github.com/lexi-lambda/threading,不过可能实现得有点复杂了。
(define (~>> arg list-of-funcs)
((fold-left compose (lambda (x) x) list-of-funcs) arg))
不过我实在看不懂这里为什么有两层括号,有Scheme宏的教程链接能给我发一个吗
因为这不是宏,是函数
(define-syntax ~>
(syntax-rules ()
((_ value)
value)
((_ value (subr args ...) others-clauses ...)
(~> (subr value args ...) others-clauses ...))
((_ value subr other-clauses ...)
(~> (subr value) other-clauses ...))))
(~> 1 (+ 2) (- 1) (* 3))
;; (* (- (+ 1 2) 1) 3)
;; => 6
(define (add1 rhs) (+ 1 rhs))
(~> 1 add1 (+ 2) (* 3))
;; (* (+ (add1 1) 2) 3)
;; => 12
(~> 1 (* 3) add1 (+ 2))
;; (+ (add1 (* 1 3)) 2)
;; => 6
楼上给的lexi-lambda的实现用的syntax-parse只有Racket有
谢谢大佬
顺便问下thread-last怎么实现
照葫芦画瓢,改插入value的位置
还是写一下吧,Scheme的宏实在看不懂
(define-syntax ~>>
(syntax-rules ()
((_ value)
value)
((_ value (subr args ...) other-clauses ...)
(~>> (subr args ... value) other-clauses ...))
((_ value subr other-clauses ...)
(~>> (subr value) other-clauses ...))))
应该是这样,谢谢大佬指点
哪有两层括号。。。
最后的那个)
对应的是define
foldl / fold-left 之前有两个左括号啊
哪有两层,这里黄色标出的部分是一个函数。
绿色 vs 黄色不是两层嘛,我的理解里楼主是想说这个
Lisp里两个括号、甚至N个括号在左边或者在右边,都是再正常不过了。
不太常见的情况是,直接两层括号,比如:
((foo bar))
即使是这样也是有可能的,(foo bar)
返回一个无参lambda
实现Anaphoric threading
(define-syntax athread
(lambda (x)
(syntax-case x ()
((_ expr)
#'expr)
((_ expr other-clauses ...)
(with-syntax ((it (datum->syntax x 'it)))
#'(let ((it expr))
(athread other-clauses ...)))))))
(athread 3 (+ 1 it)) ;; => 4
Racket 7.5 Guile 2.2.0通过,Chez 9.5.2不通过,俺暂且蒙在鼓里。
Chez 的报错信息很明显了: Exception in datum->syntax: #<syntax (athread ...)> is not an identifier
把 (datum->syntax x 'it)
里的 x 换成一个 identifier 就好了,比如可以
...
(syntax-case stx ()
...
[(athreading expr more ...)
(with-syntax ([it (datum->syntax #'athreading 'it)])
#'(let ([it expr]) (athreading more ...))])
...
另附 r6rs 里 datum->syntax
的文档:r6rs-lib
另外,即使之前 (datum->syntax x 'it)
的解法可以跑通 (athread 3 (+ 1 it))
的例子,但只要子句多一点就会发现问题:
> (athread 3 (+ 1 it) (- it 4))
-1
正常情况它应该得到 0 的结果。