I'm in the process of trying to update some old guile 1.8 code to guile 3.x. I'm struggling to find a good replacement for a particular construct.
Here's an example that represents the old 1.8 code:
(define h (make-hash-table 31))
(define (def-node name-args types)
(let ((name (car name-args))
(args (cdr name-args)))
(hashq-set! h name
(list name args types))))
(define define-node
(defmacro:syntax-transformer
(lambda arg-list
(apply def-node arg-list)
#f)))
(define (make-nodes)
(let ((def define-node))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))
(make-nodes)
(display (hashq-ref h 'a))
(newline)
(display (hashq-ref h 'd))
(newline)
My hope is to update define-node
and/or def-node
while leaving make-nodes
unchanged. So far I've rewritten define-node
like this:
(define-syntax define-node
(lambda (x)
(syntax-case x ()
[(_ name-args arg-types)
#'(def-node 'name-args 'arg-types)])))
This seems to be a reasonable replacement for define-node
, but it doesn't work with the current make-nodes
, the let
in make-nodes
is not valid. I have to replace make-nodes
with this:
(define (make-nodes)
(define-node (a b . c) (BT . CT))
(define-node (d e . f) (ET . FT)))
Which is OK, but I wonder if it's possible to find a solution where I don't have to modify make-nodes
?
You'll need to change make-nodes
. If you think about an expression like
(let ((def define-node))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))
Which is the same as
((λ (def)
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT)))
define-node)
Then the evaluation of (def (a b . c) (BT . CT))
involves first evaluating the arguments ... which will fail.
It's not clear to me how this ever could have worked with a sane version of let
.
So you'd need to use something like let-syntax
to make a local macro. I don't know if Guile has that, but if not it should.
The following will work, I think, in an R5RS Scheme, if you add make-hasheqv
and hash-set!
I tested this using Racket in fact, but using the R5RS
module language with a suitable #%require
to get the hashy bits:
(define h (make-hasheqv))
(define (def-node name-args types)
(let ((name (car name-args))
(args (cdr name-args)))
(hash-set! h name
(list name args types))))
(define (make-nodes)
(let-syntax ((def (syntax-rules ()
((_ name-args types)
(def-node 'name-args 'types)))))
(def (a b . c) (BT . CT))
(def (d e . f) (ET . FT))))