2014-01-20 33 views
3

如果我有這個名單如何將值分配給球拍中的變量?

'((x 3) (y 4) (z 2)) 

我怎麼分配3 x和y 4和z 2用它做數學是怎樣的?

3 + x 

y + z 

感謝

+0

你問題的第一部分,建議你真的要加引號的符號列表,但第二部分建議你不知道很多關於S-EXPS,因此,你可能會後,更簡單的答案。如果後者是真的,你想要的是奧斯卡關於「讓」的答案的第一部分,而不要看第二部分。 – Metaxal

回答

4

您可以使用let方案聲明局部變量。例如,在列表中創建與給定值綁定:

(let ((x 3) (y 4) (z 2)) 
    (+ y z)) ; body 

=> 6 

現在,您可以評估涉及的<body>部分聲明的變量的表達式。你甚至可以從綁定列表創建let,例如使用宏:

(define-namespace-anchor a) 
(define ns (namespace-anchor->namespace a)) 

(define-syntax my-let 
    (syntax-rules() 
    [(_ lst exp) 
    (eval `(let ,lst ,exp) ns)])) 

(my-let '((x 3) (y 4) (z 2)) ; bindings as an association list 
     '(+ y z))   ; expression to be evaluated 

=> 6 

上面創建一個名爲my-let接收到這些綁定進行評估綁定的列表和一個表達式的宏,並返回評估結果。

+0

這是清晨,我的咖啡杯丟失了,我想不出一種避免使用'eval'的方法,所以我們建議大家歡迎:) –

+0

只是爲了它,你可以有這樣的語法規則:'' [(_(quote lst)exp)....]'其中'quote'是一個字面意思,但當然這有點作弊;) (儘管如果列表是第一個分配給一個變量並賦予'my-let') – Metaxal

+1

@Metaxal我修改了一下我的代碼,以便'lst'和'exp'現在可以作爲變量傳遞,只要'exp'是一個帶引號的表達式 –

1

一個簡單的,直接的和便攜的方式是定義一個訪問器(在這個例子中,GETVAL)使用assq

(define vars '((x 3) (y 4) (z 2))) 
(define (getval sym) (cadr (assq sym vars))) 

或其任何變化。然後使用方法如下:

(+ 3 (getval 'x)) 
=> 6 

(+ (getval 'y) (getval 'z)) 
=> 6