2014-01-20 30 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