2016-08-09 22 views
0

有沒有方法可以在Chicken方案中確定運行時當前是否定義了變量?如何確定雞計劃中是否存在變量?

(let ((var 1)) 
(print (is-defined? var)) ; #t 

(print (is-defined? var)) ; #f 

編輯:XY問題。

我在寫一個生成代碼的宏。這個生成的代碼必須以相互遞歸的方式調用宏 - 讓宏自己調用它本身不起作用。當遞歸調用宏時,我需要它的行爲與初始調用時不同。我會使用嵌套函數,但是......這是一個宏。

粗糙例如:

(defmacro m (nested) 
(if nested 
    BACKQUOTE(print "is nested") 
    BACKQUOTE(m #t) 

(是的,我知道方案不defmacro使用,但我從Common Lisp的未來我也似乎不能把反引號在這裏沒有這一切會。 )

我不希望宏的INITIAL調用採用額外的參數,只有遞歸調用時纔有意義。我想通過其他方式知道它。

我可以獲取生成的代碼來調用嵌套在第一個宏中並且不存在於呼叫站點的宏嗎?例如,生成調用(,other-macro)而不是(macro)的代碼?

但是這不應該工作,因爲宏是不是一流的物體,像功能...

+0

這你應該知道在編譯時間/寫入時間。 XY?計劃如何處理它? – Sylwester

+0

我已經爲我的問題添加了詳細信息。 –

回答

0

有沒有辦法做到這一點一般,因爲方案是詞法範圍。如果引用一個未定義的變量是一個錯誤,詢問是否定義了一個變量沒有多大意義。

對於頂級/全局變量,您可以使用symbol-utils egg,但它可能不會像您期望的那樣工作,因爲模塊內的全局變量也被重寫爲其他內容。

也許如果你可以說你是真的試圖做,我可以幫助你一個替代解決方案。

+0

我想寫一個'destructuring-bind'宏,它支持關鍵字和可選參數。爲此,我需要遞歸生成代碼。遞歸調用需要知道它們是否處於關鍵字模式。我不能使用嵌套方法,因爲它是一個宏,並且必須遞歸地生成再次調用宏的代碼。宏接受模式參數是沒有意義的,因爲在第一個例子中我必須用一個空參數來調用它。我需要的是一個可能存在也可能不存在的詞彙綁定,並作出相應的反應。 –

1

當你編寫遞歸宏時,我得到的印象是你有一個宏擴展(m a b ...)變成(m-helper a (b ...))可能會變成(let (a ...) (m b ...))。由於您將代碼轉換爲恰好包含宏的代碼,因此這是而不是直接遞歸。

隨着destructuring-bind你真的只需要跟蹤兩個變量。一爲car和一個爲cdr,並與一個隱含的重命名宏的東西不是從表單來重命名,因此衛生型:

(define-syntax destructuring-bind 
    (ir-macro-transformer 
    (lambda (form inject compare?) 
    (define (parse-structure structure expression optional? body) 
     ;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals 
     ) 

    (match form 
     [(structure expression) . body ] 
     `(let ((tmp ,expression)) 
      ,(parse-structure structure 'tmp #f body)))))) 

要檢查是否從輸入的東西是你使用附帶的compare?程序相同的符號。例如。 (compare? expression '&optional)

+0

這是真的,宏可以採取可選參數。另外,用'let-syntax'你可以創建一個本地可見的宏。您可以從低級宏調用幫助程序:宏沒有理由只調用其他宏。只要記住用'use-for-syntax'加載它們的庫或者用'begin-for-syntax'形式自己定義它們。爲了獲得靈感,請看看[matchable](http://wiki.call-cc.org/eggref/4/matchable)蛋的實現,它與此非常接近。還有[綁定](http://wiki.call-cc.org/eggref/4/bindings)蛋。 – sjamaan

相關問題