2014-01-20 3 views
3

어떻게 라켓에 변수에 값을 할당합니까? 나는이 목록이있는 경우

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

어떻게 내가 좋아하는 수학을 위해 그것을 사용하는 2 x와 4 y 및 z 3 지정합니까?

3 + x 

또는

y + z 

감사

+0

첫 번째 부분은 정말로 인용 부호가있는 목록을 제안하지만 두 번째 부분은 s-exps에 대해 많이 모르기 때문에 훨씬 간단한 대답. 후자가 사실이라면, 당신이 원하는 것은 오스카가'let '에 대한 대답의 첫 부분이며, 두 번째 부분을 보지 말아야합니다. – Metaxal

답변

4

당신은 계획에서 지역 변수를 선언 let를 사용할 수 있습니다. 예를 들어, 목록에 지정된 값으로 바인딩을 만들려면 다음

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

=> 6 

은 이제 <body> 부분에 선언 된 변수를 포함하는 표현식을 평가할 수 있습니다. (가) 위의 그 바인딩 평가하는 바인딩의 목록과 식을 수신 my-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 

및 반환 : 당신은 예를 사용하여 매크로, 바인딩의 목록에서 let를 만들 수 있습니다 평가 결과

+0

아침 일찍 커피 머그잔이 빠졌고'eval' 사용을 피하는 방법을 생각할 수 없으므로 제안은 환영합니다 :) –

+0

그냥이 구문 규칙을 사용할 수 있습니다 :'' [(_ (quote lst) exp) ....]''quote'는 리터럴이지만, 물론 이것은 다소 부정 행위입니다;) ('my-let'은 목록이 첫 번째 일 경우에도 작동하지 않지만 변수에 할당되고'my-let'에게 주어집니다.) – Metaxal

+1

@Metaxal'exp '가 따옴표로 묶인 표현식이라면'lst'와'exp'를 변수로 전달할 수 있도록 약간의 코드를 수정했습니다 –

1

A, 간단하고 직접적인 방법은 휴대용 assq을 사용 (예, GETVAL의) 접근을 정의하는 것이다 :

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

또는 변형을 포함한다. 다음과 같이 사용하십시오 :

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

(+ (getval 'y) (getval 'z)) 
=> 6 
관련 문제