Very helpful, thank you. You're right that the #:methods spec was messing
up the original macro, too. Though it had some other problems after I got
beyond that hurdle.

Every time I think I am starting to understand macros I find out I don't.

Deren

On Tue, Aug 18, 2015 at 12:43 AM, Alexander D. Knauth <alexan...@knauth.org>
wrote:

> I'm not sure why that doesn't work, but I redid it with my
> define-struct-fields macro factored out and this worked:
>
> I'm not sure but I suspect the real difference comes from passing
> gen:printable to the pstruct macro though, because that's what causes this
> to fail.
> I also had to add the optional argument to the definition of gen-print in
> the (pstruct test ...) definition.
> The rest was just refactoring as I was trying to see how to simplify it so
> that I could see what was broken and what wasn't.
>
> #lang racket/base
> (require racket/generic
>          syntax/parse/define
>          "define-struct-fields.rkt"
>          (for-syntax racket/base syntax/parse racket/syntax))
>
> (define-generics printable
>   (gen-print printable [port])
>   (gen-port-print port printable)
>   (gen-print* printable [port] #:width width #:height [height])
>   #:defaults ([string?
>                (define/generic super-print gen-print)
>                (define (gen-print s [port (current-output-port)])
>                  (fprintf port "String: ~a" s))
>                (define (gen-port-print port s)
>                  (super-print s port))
>                (define (gen-print* s [port (current-output-port)]
>                                    #:width w #:height [h 0])
>                  (fprintf port "String (~ax~a): ~a" w h s))]))
>
> (define-simple-macro (pstruct struct-name (accessors ...) #:methods gen
> [body ...])
>   #:with sv (datum->syntax #'struct-name 'struct-values)
>   #:with ooo (quote-syntax ...)
>   (struct struct-name (accessors ...)
>     #:methods gen
>     [(define-syntax-rule (sv (fld ooo) v)
>        (define-struct-fields struct-name (fld ooo) v))
>      body ...]))
>
> (pstruct test (a b c)
>   #:methods gen:printable
>   [(define (gen-print ps [out (current-output-port)])
>      (struct-values (a) ps)
>      (print a out))])
> (gen-print (test 1 2 3))
>
> On Aug 18, 2015, at 12:20 AM, Deren Dohoda <deren.doh...@gmail.com> wrote:
>
> Thanks for your help Alexander. I did have this much working alright in a
> different manner. What I guess I wanted was that this syntax was introduced
> per struct so that the same syntax worked for all interface-structs. That
> is, if I
> (interface-struct test (a b c)
>   [(define (some-interface-function ...))
>     ...]) =>
> (struct test (a b c)
>   #:methods gen:???
>   [(define-struct-fields (field:id ...) ...)
>    (define (some-interface-function ...) ...) ...])
>
> Essentially all it had to do was grab the struct name automatically, just
> one more level of indirection. It seemed straightforward but in my example
> code the methods defined for the generic interface were not seen.
>
> Deren
>
> On Tue, Aug 18, 2015 at 12:07 AM, Alexander D. Knauth <
> alexan...@knauth.org> wrote:
>
>> Are you looking for a macro like this:
>> #lang racket
>> (require syntax/parse/define (for-syntax racket/syntax))
>> (define-simple-macro (define-struct-fields struct:id (field:id ...)
>> v:expr)
>>   #:with s (generate-temporary #'struct)
>>   #:with [struct-field ...]
>>   (for/list ([field (in-list (syntax->list #'(field ...)))])
>>     (format-id #'struct "~a-~a" #'struct field))
>>   (begin
>>     (define s v)
>>     (define field (struct-field s))
>>     ...))
>> ;; testing it out
>> (struct test (a b c))
>> (define x (test 1 2 3))
>> (define-struct-fields test (a b) x)
>> a
>> b
>>
>> Or do you want it even more automatic than that?
>>
>> On Aug 17, 2015, at 11:29 PM, Deren Dohoda <deren.doh...@gmail.com>
>> wrote:
>>
>> Suppose I have a struct which implements a generic interface. I'll copy
>> and paste the interface from the guide for the example. What I'd like to do
>> is have automatically-introduced syntax which allows you to skip a lot of
>> the struct-accessor forms. So for instance, for a struct like
>> (struct test (a b c))
>>
>> I'd like, in a method, to be able to say
>> (define (some-method genericable)
>>   (define-accessors (a b)))
>> Which is essentially a (define-values ...) expression, taking care of the
>> messy work of typing out all the accessor methods like (test-a genericable).
>>
>> I have this example, which doesn't raise any syntax errors, and looks
>> exactly like I'd expect from the macro stepper's output, yet fails when run:
>>
>> #lang racket/base
>> (require (for-syntax racket/base)
>>          racket/generic)
>>
>> (define-generics printable
>>     (gen-print printable [port])
>>     (gen-port-print port printable)
>>     (gen-print* printable [port] #:width width #:height [height])
>>     #:defaults ([string?
>>                  (define/generic super-print gen-print)
>>                  (define (gen-print s [port (current-output-port)])
>>                    (fprintf port "String: ~a" s))
>>                  (define (gen-port-print port s)
>>                    (super-print s port))
>>                  (define (gen-print* s [port (current-output-port)]
>>                                      #:width w #:height [h 0])
>>                    (fprintf port "String (~ax~a): ~a" w h s))]))
>>
>> (define-syntax (pstruct stx)
>>   (syntax-case stx ()
>>     ((_ struct-name (accessors ...) [body ...])
>>      (with-syntax ((sv (datum->syntax stx 'struct-values)))
>>      #'(struct struct-name (accessors ...)
>>          #:methods gen:printable
>>          [(define-syntax (sv stx)
>>             (syntax-case stx ()
>>               ((_ (acc (... ...)))
>>                (let ((accs (for/list ((id (syntax->datum #'(acc (...
>> ...)))))
>>                              (string->symbol (format "~a-~a" 'struct-name
>> id)))))
>>                  (with-syntax ((s (datum->syntax stx 'ps))
>>                                (as (datum->syntax stx accs)))
>>                    #'(define-values (acc (... ...)) (apply values (map
>> (λ(proc) (proc s)) as))))))))
>>           body ...])))))
>>
>> (pstruct test (a b c)
>>   [(define (gen-print ps)
>>      (struct-values (a))
>>      a)])
>>
>> Welcome to DrRacket, version 6.2 [3m].
>> Language: racket/base [custom]; memory limit: 1024 MB.
>> > (gen-print (test 1 2 3))
>> . . gen-print: not implemented for #<test>
>>
>> How am I going wrong here?
>>
>> Thanks,
>> Deren
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to