[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: boiler plate class generation, writing fresh variables with macros
From: |
Maxime Devos |
Subject: |
Re: boiler plate class generation, writing fresh variables with macros |
Date: |
Fri, 22 Jul 2022 11:58:00 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 |
On 22-07-2022 11:43, Blake Shaw wrote:
But if I try to use `slot-machine` inside a class definition i'm out of
luck:
(define-class <dummy> ()
(slot-machine 'inner 'color "green"))
=> While compiling expression:
Syntax error:
socket:7257:0: source expression failed to match any pattern in form
(define-class-pre-definition ((quote inner) (quote color) "green"))
This is actually a recurring theme with my experience with Guile, working
on a project, needing to generate boilerplate, and then being unable to
find a result, so I figured its time I reach out to figure out what I'm
doing wrong in this situation.
Syntax transformations in Scheme work from the outside to the inside,
not the other way around, so you can't do things like this (define-class
doesn't know what to do with this 'slot-machine' thing, it will reject
it for not being a valid slot definition). However, you can define a
syntax that generates the surrounding define-class and interprets things
to insert the result of slot-matchine into a proper define-class form.
Something like (untested):
(define-syntax easy-define-class
(lambda (s)
(syntax-case s ()
((_ <class-name> <parents> slot ...)
#`(define-class <class-name> <parents> #,(fixup #'slot) ...)))))
(define slot-machine "todo: use define-syntax + identifier-syntax +
syntax-error etc.")
(define (fixup slot)
(syntax-case slot (slot-machine)
((slot-machine category quality value)
(let ((sym ...)
...)
#`(#:getter #,get-sym [etcetera])))
(boring #'boring))) ; old-style slot definitions
(easy-define-class <dummy> () (slot-machine ...))
Important: fixup is _not_ a macro, just a helper procedure of the
easy-define-class macro that happens to transform syntax! As such, it
needs to use 'define', not 'define-syntax'. Also, you probably can't do
symbol-append like you are doing currently as Guile's hygiene code won't
know the context of the generated symbol, so you'll need some
datum->syntax + syntax->datum + symbol-append for your technically
unhygienic 'fixup' (though a very mild form of inhygiene!).
Greetings,
Maxime.
OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key
OpenPGP_signature
Description: OpenPGP digital signature