chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] Re: Explicit Renaming Macros Help/Tutorial?


From: Jack Trades
Subject: [Chicken-users] Re: Explicit Renaming Macros Help/Tutorial?
Date: Tue, 9 Jun 2009 14:15:18 -0400

Thanks again for your help, I think I finally understand er-macros, at least a little.

A couple more questions.  I was playing with a macro that extends the syntax of if.  This macro works fine on its own and also if I import the module with no prefix.  However I get an error if I try to import the module with a prefix. The offending code is below.

(module test (ef)
(import scheme)

(define-syntax (ef x r c)
  (let ((%if (r 'if))
        (%cond (r 'cond)))
  `'(,@(let loop ((args x) (cons-form '()))
      (cond ((null? args)
              (reverse cons-form))
            ((equal? (car args) 'ef)
              (cond ((= (length x) 3)
                      (let ((test (cadr x)) (true (caddr x))) (cons %if (list test true))))
                    ((= (length x) 4)
                      (let ((t (cadr x)) (tt (caddr x)) (ft (cadddr x))) (cons %if (list t tt ft))))
                    (else
                      (cons %cond (loop (cdddr args) (cons (list (cadr args) (caddr args)) cons-form))))))
            ((equal? (car args) 'elif)
              (loop (cdddr args) (cons (list (cadr args) (caddr args)) cons-form)))
            ((equal? (car args) 'else)
              (loop (cddr args) (cons (list 'else (cadr args)) cons-form))))))))
)

;; This works
(import test)
(ef (< 1 0) #t #f)
===> (if (< 1 0) #t #f)

;; This produces an error.
(import (prefix test t-))
(t-ef (< 1 0) #t #f)
===> Error: (append) during expansion of (t-ef ...) - bad argument type - not a proper list: #<unspecified>

        Call history:

        <eval>          ((##core#letrec ((loop (##core#loop-lambda (args cons-form) (cond ((null? args) (reverse cons-form))...
        <eval>          (null? args)
        <eval>          (equal? (car args) (quote ef))
        <eval>          (car args)
        <eval>          (equal? (car args) (quote elif))
        <eval>          (car args)
        <eval>          (equal? (car args) (quote else))
        <eval>          (car args)      <--


Also, is there any way I can name this macro 'if'.  It accepts the same syntax as the standard 'if' but it also extends it.  I've tried every permutation of quoting that I can conceive of but I keep getting errors if I name it 'if', even though it produces the correct forms.

(define-syntax (if x r c)
  (let ((%if (r 'if))
        (%cond (r 'cond)))
  `'(,@(let loop ((args x) (cons-form '()))
      (cond ((null? args)
              (reverse cons-form))
            ((equal? (car args) 'if)
              (cond ((= (length x) 3)
                      (let ((test (cadr x)) (true (caddr x))) (cons %if (list test true))))
                    ((= (length x) 4)
                      (let ((t (cadr x)) (tt (caddr x)) (ft (cadddr x))) (cons %if (list t tt ft))))
                    (else
                      (cons %cond (loop (cdddr args) (cons (list (cadr args) (caddr args)) cons-form))))))
            ((equal? (car args) 'elif)
              (loop (cdddr args) (cons (list (cadr args) (caddr args)) cons-form)))
            ((equal? (car args) 'else)
              (loop (cddr args) (cons (list 'else (cadr args)) cons-form))))))))

(if (< 1 0) 1 2)
===> (if (< 1 0) 1 2)

(if (< 1 0) 1 else 2)
===> (cond ((< 1 0) 1) (else 2))

But when I unquote it...

(if (< 1 0) 1 2)
===> Error: (append) during expansion of (if98 ...) - bad argument type - not a proper list: #<unspecified>

(if (< 1 0) 1 else 2)
===> Error: (append) during expansion of (if106 ...) - bad argument type - not a proper list: #<unspecified>

The 'ef' macro accepts the following syntaxes
(ef (< 1 0) #t)                      ===> (if (< 1 0) #t)
(ef (< 1 0) #t #f)                   ===> (if (< 1 0) #t #f)
(ef (< 1 0) 1 else 2)                ===> (cond ((< 1 0) 1) (else 2))
(ef (< 1 0) 1 elif (< 2 0) 2)        ===> (cond ((< 1 0) 1) ((< 2 0) 2))
(ef (< 1 0) 1 elif (< 2 0) 2 else 3) ===> (cond ((< 1 0) 1) ((< 2 0) 2) (else 3))

Jack Trades

reply via email to

[Prev in Thread] Current Thread [Next in Thread]