Library bug: refering to function in a macro?

Jan 17, 2010 at 12:44 AM
Edited Jan 17, 2010 at 12:45 AM

Im not sure if this is a bug or if its somehow specified in r6rs. Basically i have the following library. Basically what is happening is , when i try to load the library, it says

Unhandled exception during evaluation:
&who: group
&message: "identifier out of context"
  form: group
  subform: #f
  file-name: "C:\\Program Files\\IronScheme\\lib\\utils\\general.sls"
  character: "(58,6) - (58,11)"
&trace: #<syntax group ((58,6) - (58,11) of C:\Program Files\IronScheme\lib\utils\general.sls)>

I imagine this is because group is a function and setq! is a macro. But shouldn't a macro be able to refer  to a function in the same library? Is this a bug?

(library (utils general) (export mvbind t? split-at group setq! def-syntax)

(define-syntax def-syntax
   (syntax-rules ()
     ((_ name body ...)
      (define-syntax name (lambda (obj) (syntax-case obj () body ...))))
     ((_ (name special) body ...)
      (define-syntax name (lambda (obj) (syntax-case obj special body ...))))))

(def-syntax mvbind
  ((_ ret func body ...)
   #'(call-with-values (lambda () func) (lambda ret body ...))))
(define (t? obj) (not (null? obj)))

(define (split-at lst place)
   ((null? lst) (values lst lst))
   ((< place 1) (error  (list lst place)
            "Invalid index in split-at: less than or = zero"))
    (let f ((first (list (car lst)))
        (second (cdr lst))
        (i 1))
      (if (or (null? second) (= i place))
      (values first second)
      (f (append first (list (car second)))
         (cdr second) (+ i 1)))))))

(define (group collection  by)
  (let f ((coll '()) (lst collection))
       (if (t? lst)
       (mvbind (first second) (split-at lst by)
           (f (append coll (list first)) second))

(def-syntax setq!
  ((_ var/vals ...)
   (with-syntax ([((var val) ...)
          (group #'(var/vals ...) 2)])
        #'(begin (set! var val) ...))))


Jan 17, 2010 at 4:43 AM
Suroy wrote:

Im not sure if this is a bug or if its somehow specified in r6rs.

Not a bug  :)  It is the way syntax-case (and library 'phasing') works.

You are trying to use a 'local' procedure during expansion time.

To make this work, you need to define a 'helper' library and import that.

Move GROUP, SPLIT-AT and T? to that library, and export what you need.

Just looking quickly, to export all from one library, you will need 2 additional libraries (one exporting DEF-SYNTAX, and the other the procedures).

It gets a bit long in the tooth though.

If you just want to use these procs at one place, then it would be better to define them there. Example

(define-syntax foo
  (lambda (x)
    (define split-at ...)
    (define group ...)
    (syntax-case x () ...)))

Jan 18, 2010 at 2:46 AM

Got it. Thanks again!