宏的許多例子似乎都是關於隱藏lambda,例如在CL中打開文件。我正在尋找一些更宏觀的宏,特別是在PLT計劃中。我想知道何時考慮使用宏與使用函數。你用Scheme Scheme宏做了些什麼?
回答
我只用了很小的事情計劃宏(define-syntax
),如更好的lambda語法:
(define-syntax [: x]
(syntax-case x()
([src-: e es ...]
(syntax-case (datum->syntax-object #'src-: '_)()
(_ #'(lambda (_) (e es ...)))))))
,它可以讓你寫
[:/_ 2] ; <-- much better than (lambda (x) (/ x 2))
丹·弗裏德曼有使用宏OO的一個令人費解的實現:http://www.cs.indiana.edu/~dfried/ooo.pdf
但說實話,我所定義的所有有用的宏d從Paul Graham's On Lisp被盜,通常易於用defmacro
(PLT計劃中的define-macro
)編寫。例如,aif
與define-syntax
相當醜陋。
(define-syntax (aif x)
(syntax-case x()
[(src-aif test then else)
(syntax-case (datum->syntax-object (syntax src-aif) '_)()
[_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))
define-syntax
是,這只是簡單的使用非常簡單的宏,在那裏你很高興無法捕捉變量的奇數;和非常複雜的宏DSL,你很高興無法捕捉變量容易。在第一種情況下,您希望編寫代碼而不考慮它,而在第二種情況下,您已經充分考慮了DSL,您希望將其中的一部分寫入syntax-rules
/syntax-case
語言中,該語言不是Scheme以便避免神祕的錯誤。
但我沒有在Scheme中使用過多的宏。習語方案非常實用,很多時候你只想編寫一個功能程序,然後隱藏一些lambda表達式。我開始了功能訓練,現在認爲如果你對lambda有一個懶惰的語言或者一個好的語法,即使這不是必須的,所以宏在純粹的功能性風格中並不是那麼有用。
所以我建議Practical Common Lisp和On Lisp。如果你想使用PLT方案,我認爲他們的defmacro
宏中的大部分都可以與define-macro
一起使用。或者只是使用Common Lisp。
如果使用語法參數,`aif`變得更清晰(定義hygenic!):`(define-syntax-parameter it #f)(define-syntax aif語法分析器[(_ test then else)#'(let([result test])(syntax-parameterize([it(make-rename-transformer result)])(if result then else)))])) – Jack 2014-10-07 19:22:37
我會開始回答最後一個問題。何時使用宏而不是函數。宏做功能不能做的事情,功能做宏不能做的事情,所以很難混合它們,但是讓我們深入一下。
當您希望參數評估時使用函數,而當您希望參數未評估時使用宏。這不是很有用,是嗎?當你想以不同的方式寫東西時,當你看到一個模式並且你想要抽象時,你使用宏。例如:我定義了三個稱爲foo-create,foo-process和foo-destroy的函數,用於foo的不同值以及類似的機構,其中唯一的變化是foo。有一個模式,但是對於一個函數來說是一個太高的級別,所以你創建一個宏。
以我卑微的經驗,Scheme中的宏和其他Lisp一樣多,像Common Lisp或Clojure。我認爲這證明衛生宏可能不是一個好主意,在這裏我不同意Paul Graham的看法。這不是因爲有時候你想要變得骯髒(不衛生),而是因爲衛生的宏變得複雜或錯綜複雜。
「因爲衛生的宏觀變得複雜或錯綜複雜」 - 我不認爲這是因爲衛生本身;這很可能是因爲Scheme衛生宏是「高級」,必須用除Scheme之外的語言編寫(就我而言,這比計劃本身更不方便) 這就是爲什麼我喜歡Common Lisp和在Scheme中仍然使用define-macro,儘管R5RS具有這種誇張的語法規則的東西......:-) – Jay 2010-06-27 23:38:51
Peter Seibel編寫的Practical Common Lisp對宏有很好的介紹。關於Lisp,Paul Graham,可能是更復雜的例子的一個很好的來源。另外,請查看Common Lisp中的內置宏。
Scheme宏!=常用Lisp宏 – 2008-10-29 18:41:29
一種更先進的宏的示例不是僞裝的λ形式是常見Lisp的宏與時隙,這使得對象插槽存取樣子普通可變訪問:
(with-slots (state door) car
(when (eq state :stopped)
(setq state :driving-around)
(setq door :closed)))
注意,這與將插槽值綁定到局部變量並訪問它們不同,因爲帶插槽允許您通過SETQ更改插槽並立即查看外部更改。
setq的使用確實被棄用,以支持setf。如果像這樣的例子使用setf,那麼對於新的(通用)lispers來說就不那麼容易混淆了。 – simon 2008-10-29 22:06:43
宏需要爲了實現新的控制結構和新的綁定結構。
因此在http://planet.plt-scheme.org尋找這些種類的構造。 在PLaneT上你都瀏覽文檔和代碼。新的控制結構
例子:
http://planet.plt-scheme.org/package-source/soegaard/control.plt/2/0/planet-docs/manual/index.html
要找到新的結合形式的例子,查找以「與 - 」開頭的宏。 另一個有用的例子是在math.plt中也從PLaneT中找到的。
; Within a (with-modulus n form1 ...) the return values of
; the arithmetival operations +, -, * and^are automatically
; reduced modulo n. Furthermore (mod x)=(modulo x n) and
; (inv x)=(inverse x n).
; Example: (with-modulus 3 (^ 2 4)) ==> 1
(define-syntax (with-modulus stx)
(syntax-case stx()
[(with-modulus e form ...)
(with-syntax ([+ (datum->syntax-object (syntax with-modulus) '+)]
[- (datum->syntax-object (syntax with-modulus) '-)]
[* (datum->syntax-object (syntax with-modulus) '*)]
[^ (datum->syntax-object (syntax with-modulus) '^)]
[mod (datum->syntax-object (syntax with-modulus) 'mod)]
[inv (datum->syntax-object (syntax with-modulus) 'inv)])
(syntax (let* ([n e]
[mod (lambda (x) (modulo x n))]
[inv (lambda (x) (inverse x n))]
[+ (compose mod +)]
[- (compose mod -)]
[* (compose mod *)]
[square (lambda (x) (* x x))]
[^ (rec^(lambda (a b)
(cond
[(= b 0) 1]
[(even? b) (square (^ a (/ b 2)))]
[else (* a (^ a (sub1 b)))])))])
form ...)))]))
Automata via Macros本文提供了一個函數編程的珍珠,通過Scheme中的宏實現有限狀態機。
該書The Reasoned Schemer以本書中使用的邏輯編程語言miniKanren的完全基於宏的實現結束。 This paper介紹miniKanren及其實施比本書更正式和簡潔。
通過宏鏈接自動機是純金。我有一個巨大的哈哈!時刻閱讀它。從我+1。 – 2011-07-19 04:47:04
我在程序不足時使用它們。
我有一個curry
宏,當我用我的手掌做了很多計劃。這非常方便。
Scheme宏允許您添加原始語言作者未包含的特徵;這是宏觀背後的全部理念。
這是一個小例子:PLT Scheme提供了一種用於編寫幻燈片演示的語言。我使用宏將幻燈片編號與幻燈片相關聯,以便我可以更輕鬆地管理它們。
我寫了一個提供中綴語法的宏。沒什麼太花哨的;沒有優先權。雖然我通常使用前綴語法,但我更喜歡<和>的中綴。
- 1. 這個Scheme代碼是做什麼的?
- 2. 我在做什麼錯在Scheme?
- 3. 以下函數在Scheme編程語言中做了什麼
- 4. 在Scheme中編寫了哪些軟件?
- 5. Scheme Lambda?它是什麼?
- 6. Scheme宏中的語法引用
- 7. 使用宏的Scheme中的Currying函數
- 8. 學習如何實現Scheme宏有什麼好的資源?
- 9. 你用Object.clone()做了什麼?
- 10. 你如何在OS X中使用Scheme?
- 11. 這些宏做什麼(LLVM)?
- 12. 閱讀宏:你用它們做什麼?
- 13. 如何在guile scheme中擴展宏?
- 14. 爲什麼這個Scheme不能編譯?
- 15. 爲什麼在Scheme中不評估?
- 16. Lisp/Scheme中的'(撇號)是什麼?
- 17. Scheme中的「Stack」。什麼使它特別?
- 18. 在Scheme中,「set!」是什麼意思?
- 19. Scheme中的變異是什麼?
- 20. 什麼是Scheme中的原子?
- 21. 如何調用Chicken Scheme宏中的「when」宏?
- 22. REST url scheme
- 23. JsFiddle-like color scheme
- 24. Yammer URL scheme android
- 25. sqlalchemy oracle scheme
- 26. 錯誤:for:undefined(Scheme)
- 27. Andmap \ ormap - chez scheme
- 28. Posn in scheme/DrRacket
- 29. Apple Music URL Scheme
- 30. Scheme Let語句
PLT計劃現在稱爲球拍。 見http://www.racket-lang.org/ – Stephen 2010-07-05 15:59:58