[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] A problem with let-syntax?
From: |
Tomasz Primke |
Subject: |
[Chicken-users] A problem with let-syntax? |
Date: |
Tue, 27 Oct 2009 15:06:15 +0100 |
I'm working on macros which should define many procedures. My first
try was to write a macro, that after such a call:
(defproc myproc a b c)
would define the following procedures:
myproc-a
myproc-b
myproc-c
The returned values don't matter; it's just an exercise.
Here's my code:
(define-syntax defproc-aux
(syntax-rules ()
( (_ name msg)
(define (name) (print msg)) )))
(define-syntax defproc
(lambda (exp ren comp)
; The base procedure name string.
(let* ( (base (cadr exp))
(baseStr (symbol->string base))
(params (cddr exp)) )
; Extract all the methods and prepare macro forms.
(let loop ( (params params) (acc '()) )
(if (null? params)
`(begin ,@acc)
(let* ( (methSymb (car params))
(methStr (symbol->string methSymb))
(methNameStr (string-append baseStr "-" methStr))
(methName (string->symbol methNameStr))
(newAcc (cons `(defproc-aux ,methName ,methStr) acc)) )
(loop (cdr params) newAcc)))))))
I started with defproc-aux defined outside the defproc macro, with
define-syntax. This macro worked as expected:
#;> (expand '(defproc myproc a b c))
(begin (defproc-aux myproc-c "c") (defproc-aux myproc-b "b")
(defproc-aux myproc-a "a"))
#;> (defproc myproc a b c)
#;> myproc-a
#<procedure (myproc-a)>
#;> myproc-b
#<procedure (myproc-b)>
#;> myproc-c
#<procedure (myproc-c)>
So, I thought that I had learnt how to write such macros and tried to
write something very similar:
(define-syntax defproc2
(lambda (exp ren comp)
; The auxiliary macro.
(let-syntax ( (defproc-aux2 (syntax-rules ()
( (_ name msg)
(define (name) (print msg)) ))) )
; The base procedure name string.
(let* ( (base (cadr exp))
(baseStr (symbol->string base))
(params (cddr exp)) )
; Extract all the methods and prepare macro forms.
(let loop ( (params params) (acc '()) )
(if (null? params)
`(begin ,@acc)
(let* ( (methSymb (car params))
(methStr (symbol->string methSymb))
(methNameStr (string-append baseStr "-" methStr))
(methName (string->symbol methNameStr))
(newAcc (cons `(defproc-aux2 ,methName ,methStr) acc)) )
(loop (cdr params) newAcc))))))))
The reason was simple: I wanted to make it clear, that this auxiliary
macro is needed only in defproc2. Unfortunatelly, it doesn't work at
all:
#;> (expand '(defproc2 myproc a b c))
(begin (defproc-aux2 myproc-c "c") (defproc-aux2 myproc-b "b")
(defproc-aux2 myproc-a "a"))
#;16> (defproc2 myproc a b c)
Error: unbound variable: defproc-aux2
Call history:
<eval> (##sys#cons (quote553 begin) (##sys#append acc
(quote553 ())))
<eval> (##sys#append acc (quote553 ()))
<syntax> (begin (defproc-aux2 myproc-c "c")
(defproc-aux2 myproc-b
"b") (defproc-aux2 myproc-a "a"))
<syntax> (defproc-aux2 myproc-c "c")
<syntax> (defproc-aux2 myproc-b "b")
<syntax> (##core#begin (defproc-aux2 myproc-a "a"))
<syntax> (defproc-aux2 myproc-a "a")
<eval> (defproc-aux2 myproc-c "c") <--
Well, I'm new to Chicken (and to Scheme, although I have some basic
experience already). If I understand these messages, the defproc-aux2
isn't bounded to the macro defined by the let-syntax form.
The question is why?
According to all my knowledge based on R5RS docs and TSPL (3rd and 4th
editions) the let-syntax form should work just as the defproc-aux2 was
defined with define-syntax (in this let-syntax form's scope).
I'm using the Chicken version 4.2.0.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Chicken-users] A problem with let-syntax?,
Tomasz Primke <=