2008-12-04 20 views
5

Czy makro być napisane na schemacie (z define-syntax, na przykład), które odbędzie wyrażenia tak:Schemat Makro do wyrażenia lęgowych

(op a b c d e f g h i j) 

i dają wyrażeń takich jak to jako wyjście?

(op (op (op (op (op (op (op (op (op a b) c) d) e) f) g) h) i) j) 

Oczywiście dla dowolnych długości. Nie mogę myśleć o sposób, aby to zrobić, biorąc pod uwagę niektóre szablon tak:

(define-syntax op 
    (syntax-rules() 
    [(_) 'base-case] 
    [(v1 v2 ...) 'nested-case??])) 
+0

Jestem ciekawy. Czy to tylko kwestia teoretycznych zainteresowań, czy masz ciekawy przypadek użycia? Ogólnie rzecz biorąc, taki rodzaj owijania zostałby osiągnięty przez funkcję foldLeft. – namin

+0

hmm, dobry punkt. najczęściej o to pytałem, ponieważ nie myślałem o twojej drodze = P. nie zdawałem sobie sprawy, że to jest dokładnie to, co robi foldl. – Claudiu

Odpowiedz

6
(define bop list) 

(define-syntax op 
    (syntax-rules() 
    ((op a b) (bop a b)) 
    ((op a b c ...) (op (bop a b) c ...)))) 

Na przykład (op 1 2 3 4) rozszerza się (bop (bop (bop 1 2) 3) 4) i ocenia się (((1 2) 3) 4).

+1

Dlaczego używasz bop w literalnych identyfikatorach, jeśli nie pasujesz do niego? – leppie

+0

Dobra uwaga. Naprawiony. – namin

+1

Schematy makr są naprawdę sprytne z ich ... prawda? – Claudiu

0

Aby pokazać, jak odpowiedź odrabia:

(op 1 2 3 4) 

To op z 4 sprawozdania, tak 2nd sprawa zostanie wybrany z a = 1, b = 2, c = 3, ... = 4:

(op (bop 1 2) 3 4) 

To jest op z 3 instrukcjami, więc drugi raz ponownie. A = (BOP 1 2), b = 3, c = 4:

(op (bop (bop 1 2) 3) 4) 

Teraz jest BOP 2 stwierdzeniach, więc = (BOP (BOP 1, 2) 3), B = 4, i zrobione.

1

Funkcja, którą chcesz zastosować do argumentów, powinna sama być argumentem dla makra. Poza tym moje rozwiązanie było takie samo.

#!r6rs 

(import (rnrs base)) 

(define-syntax claudiu 
    (syntax-rules() 
    ((claudiu fun first second) 
    (fun first second)) 
    ((claudiu fun first second rest ...) 
    (claudiu fun (claudiu fun first second) rest ...))))