guile-user
[Top][All Lists]
Advanced

[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.

Attachment: OpenPGP_0x49E3EE22191725EE.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


reply via email to

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