2016-08-22 1 views
0

나는 '다른'문이 주어지지 않는 '때'기능을 적용하는 매크로를 가지고 노력하고 작동하지 않습니다 :왜이 매크로를 사용하는 다른 '경우', 라켓

그러나
(define-syntax-rule (myif condition body (body2 #f)) 
    (if (not body2) 
     (when condition body) 
     (if condition 
      body 
      body2))) 

(define x 15) 
(myif (> x 10) (println x)) 

, 이 작동하지 않습니다. 오류는 다음과 같습니다.

myif: use does not match pattern: 
    (myif condition body (body2 #f)) in: (myif (> x 10) (println x)) 

답변

3

define-syntax-rules 선택적 인수가있는 프로 시저와 같은 인수를 사용하지 않습니다.

(define-syntax-rule (myif condition body (body2 #f)) 
    ...) 

는 것과 같습니다 유효한 사용 (myif predicate consequence (alternative #f))

(define-syntax myif 
    (syntax-rules() 
    [(myif condition body (body2 #f)) ...])) 

와로가집니다 : 당신이 실행해야 코드를하려고하는 것 같다

(if (not (alternative #f)) 
    (when predicate consequence) 
    (if predicate consequence (alternative #f))) 

이것은 시간의 컴파일이 아니라 확장의 일부가 아니므로 이것은 술어 이전에 대안을 평가할 것이기 때문입니다. 그래서 함수가를 imlpementing과 같은 일을

(define-syntax myif 
    (syntax-rules() 
    [(_ predicate consequence alternative) (if predicate consequence alternative)] 
    [(_ predicate consequence) (when predicate consequence)]) 

편집

: 즉, 간단한 구문을 사용하지 않는 두 가지 패턴을 갖는 그러나 당신은 당신이 원하는 것을 할 수 syntax-rules 작동하지 않습니다 매크로 대신. 여기에는 스릴이없고, 생각할 수있는 특별한 기능 구현이 없습니다. NB : 저는 이것들과 같은 매크로에 관해서는 단순한 초보자입니다.

(define-syntax (myif stx) 
    (let ((lst (syntax->list stx))) 
    (if (= (length lst) 3) 
     #`(when #,@(cdr lst)) 
     #`(if #,@(cdr lst))))) 

lst의 일부가 어디에서 왔는지의 정보를 구문 객체가 공지있다. `#, #,, and #,@`, ,,@의 구문입니다.

+0

어떻게 매크로로 만들지 않고 함수로 만들 수 있습니까? – rnso

+0

@mso'if'는 절망적 인 언어에서는 결코 함수로 만들 수 없지만, 구문 규칙을 mathing하는 대신에 구문을 생성하는 함수를 사용할 수도 있습니다. 예제를 추가했습니다. – Sylwester

+0

필자는 myif 'function'또는 'procedure'(매크로 또는 구문이 아님)를 가졌다. (define myif condition body (body2 #f)) .........). 가능한가? – rnso

관련 문제