2014-10-28 82 views
1

我一直在使用R5RS的一些代碼來處理一個賦值,使用宏將某些表達式擴展爲表達式的核心形式。這些都是通過提供的eval把/應用循環後創建一個函數來使用宏返回一個核心表達式

(define expand (lambda (exp) 

(letrec-syntax 
    ((let (syntax-rules() 
     ((_ ((var init) ...) body ...) 
     (`((lambda (var ...) body ...) init ...)))))) 
    (exp)) ; sequence to expand 
)) 
(expand (let ((x 2) (y 1)) (+ x y))) 

當我運行的代碼,這樣我回來;The object 3 is not applicable.但因此它看起來像它的實際評估EXP,但我需要拿回呃...字符串表示。

如果我將希望展開的表達式嵌入到letrec-syntax body中,我可以找回我真正想要的東西。像這樣:

(define expand (lambda (exp) 

(letrec-syntax 
    ((let (syntax-rules() 
     ((_ ((var init) ...) body ...) 
     (`((lambda (var ...) body ...) init ...)))))) 
    (let ((x 2) (y 1)) (+ x y))) ; sequence to expand 
)) 

我回來...... ;The object ((lambda (x y) (+ x y)) 2 1) is not applicable,它看起來像什麼,我要發送回被解釋。

所以我的問題是我怎麼能重寫這個採取任何exp給予像第一個例子展開,但返回其擴展形式像第二個例子?

我認爲這個問題與lambda在關於letrec-syntax的錯誤範圍中定義的exp有關。我對Scheme很陌生,我覺得我在這裏錯過了一個簡單的解決方案。到目前爲止,我的最佳線索涉及使用語法或某種有關衛生的方法,但我覺得我一直在追逐我的尾巴,試圖研究這些話題,但我不確定它們是否是正確的方向。

感謝您的任何幫助。 :)

+0

哪個方案實現您使用? – uselpa 2014-10-28 21:31:47

+0

基於來自[此處]的R5RS的MIT/GNU Scheme(https://www.gnu.org/software/mit-scheme/) – 2014-10-28 21:40:47

回答

0

這工作:

(define-syntax expand 
    (syntax-rules (let) 
    ((_ (let ((var init) ...) body ...)) 
    '((lambda (var ...) body ...) init ...)))) 

然後

> (expand (let ((x 2) (y 1)) (+ x y))) 
((lambda (x y) (+ x y)) 2 1) 
+0

@uselpha MIT/GNU Scheme似乎不喜歡syntax-object-> datum #'部分,如果我刪除它,如果我在之後調用擴展,它會給我返回的表達式,但是當擴展稍後調用時,會得到一個格式錯誤的特殊形式錯誤(定義解釋 (lambda(exp) (exec擴展exp)'())))' – 2014-10-28 22:20:19

+0

好吧,剛安裝MIT-Scheme。請參閱我的更新。 – uselpa 2014-10-28 22:37:33

+0

你能解釋一下語法規則中的值(let)值是什麼嗎?我在網上看到的每個地方都使用'(syntax-rules() ((_)...)' – 2014-10-28 22:38:04

相關問題