unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Need help with macro
@ 2018-12-13  0:30 Mike Gran
  2018-12-13  1:34 ` Mark H Weaver
  2018-12-13  1:38 ` Alex Vong
  0 siblings, 2 replies; 5+ messages in thread
From: Mike Gran @ 2018-12-13  0:30 UTC (permalink / raw)
  To: guile-user

Hey all,

I need help making a macro.

I have an existing procedure of the form

(call-method self method (...))

Note that SELF is a struct, METHOD is a string, and the ellipses can
be anything.

I would like to make a macro that transforms into the above, but, is
of the form

(send self (method ...))

where SELF is the same struct, METHOD is a literal symbol, and the
ellipses are unchanged.

For example, I would like to call

(send date (get-year))
(send date (set-year 2018))
(send date (set-dmy 1 1 2018))

and have it be

(call-method date "get-year" '())
(call-method date "set-year" (list 2018))
(call-method date "set-dmy" (list 1 1 2018))

I get hung up on figuring out how to handle the literal symbol and the
ellipses.

If you need context, see
https://wiki.gnome.org/Projects/GObjectIntrospection/HowToWriteALanguageBinding

Thanks in advance,

Mike Gran





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Need help with macro
  2018-12-13  0:30 Need help with macro Mike Gran
@ 2018-12-13  1:34 ` Mark H Weaver
  2018-12-13 18:14   ` Mike Gran
  2018-12-13  1:38 ` Alex Vong
  1 sibling, 1 reply; 5+ messages in thread
From: Mark H Weaver @ 2018-12-13  1:34 UTC (permalink / raw)
  To: Mike Gran; +Cc: guile-user

Hi Mike,

Mike Gran <spk121@yahoo.com> writes:

> Hey all,
>
> I need help making a macro.
>
> I have an existing procedure of the form
>
> (call-method self method (...))
>
> Note that SELF is a struct, METHOD is a string, and the ellipses can
> be anything.
>
> I would like to make a macro that transforms into the above, but, is
> of the form
>
> (send self (method ...))
>
> where SELF is the same struct, METHOD is a literal symbol, and the
> ellipses are unchanged.
>
> For example, I would like to call
>
> (send date (get-year))
> (send date (set-year 2018))
> (send date (set-dmy 1 1 2018))
>
> and have it be
>
> (call-method date "get-year" '())
> (call-method date "set-year" (list 2018))
> (call-method date "set-dmy" (list 1 1 2018))
>
> I get hung up on figuring out how to handle the literal symbol and the
> ellipses.

Here's a syntax-rules macro to do it:

  (define-syntax send
    (syntax-rules ()
      ((send self (method arg ...))
       (call-method self (symbol->string 'method) `(,arg ...)))))

However, in this implementation, the 'symbol->string' call is deferred
to run time.

Here's a syntax-case macro that does the conversion at compile time:

  (define-syntax send
    (lambda (stx)
      (syntax-case stx ()
        ((send self (method arg ...))
         (identifier? #'method)
         (with-syntax ((method-str (symbol->string
                                    (syntax->datum #'method))))
           #'(call-method self method-str `(,arg ...)))))))

This syntax-case macro also verifies at compile time that 'method' is a
bare identifier, via the guard (identifier? #'method).

Note that to generate the list of arguments, the simpler approach would
have been to write (list arg ...) instead of `(,arg ...).  I chose to
use quasiquote mainly to benefit from an optimization in the quasiquote
macro, namely that `() expands into '(), which is preferable to (list).

      Mark



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Need help with macro
  2018-12-13  0:30 Need help with macro Mike Gran
  2018-12-13  1:34 ` Mark H Weaver
@ 2018-12-13  1:38 ` Alex Vong
  2018-12-13 18:15   ` Mike Gran
  1 sibling, 1 reply; 5+ messages in thread
From: Alex Vong @ 2018-12-13  1:38 UTC (permalink / raw)
  To: Mike Gran; +Cc: guile-user

[-- Attachment #1: Type: text/plain, Size: 1414 bytes --]

Hello Mike,

Mike Gran <spk121@yahoo.com> writes:

> Hey all,
>
> I need help making a macro.
>
> I have an existing procedure of the form
>
> (call-method self method (...))
>
> Note that SELF is a struct, METHOD is a string, and the ellipses can
> be anything.
>
> I would like to make a macro that transforms into the above, but, is
> of the form
>
> (send self (method ...))
>
> where SELF is the same struct, METHOD is a literal symbol, and the
> ellipses are unchanged.
>
> For example, I would like to call
>
> (send date (get-year))
> (send date (set-year 2018))
> (send date (set-dmy 1 1 2018))
>
> and have it be
>
> (call-method date "get-year" '())
> (call-method date "set-year" (list 2018))
> (call-method date "set-dmy" (list 1 1 2018))
>
> I get hung up on figuring out how to handle the literal symbol and the
> ellipses.
>
> If you need context, see
> https://wiki.gnome.org/Projects/GObjectIntrospection/HowToWriteALanguageBinding
>
> Thanks in advance,
>
> Mike Gran

I think this would work:

  (define-syntax-rule (send self (method args ...))
    (call-method self
                 (symbol->string 'method)
                 (list args ...)))

For example,

  (send date (set-dmy 1 1 2018))

will be expanded to

  (call-method date
               (symbol->string 'set-dmy)
               (list 1 1 2018))

which is equivalent to

  (call-method date "set-dmy" (list 1 1 2018))

Cheers,
Alex

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Need help with macro
  2018-12-13  1:34 ` Mark H Weaver
@ 2018-12-13 18:14   ` Mike Gran
  0 siblings, 0 replies; 5+ messages in thread
From: Mike Gran @ 2018-12-13 18:14 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user

On Wed, Dec 12, 2018 at 08:34:13PM -0500, Mark H Weaver wrote:
> Here's a syntax-rules macro to do it:
> 
>   (define-syntax send
>     (syntax-rules ()
>       ((send self (method arg ...))
>        (call-method self (symbol->string 'method) `(,arg ...)))))
> 
> However, in this implementation, the 'symbol->string' call is deferred
> to run time.
> 
> Here's a syntax-case macro that does the conversion at compile time:
> 
>   (define-syntax send
>     (lambda (stx)
>       (syntax-case stx ()
>         ((send self (method arg ...))
>          (identifier? #'method)
>          (with-syntax ((method-str (symbol->string
>                                     (syntax->datum #'method))))
>            #'(call-method self method-str `(,arg ...)))))))

Great!  This is what I needed.  Thanks for help.

-Mike



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Need help with macro
  2018-12-13  1:38 ` Alex Vong
@ 2018-12-13 18:15   ` Mike Gran
  0 siblings, 0 replies; 5+ messages in thread
From: Mike Gran @ 2018-12-13 18:15 UTC (permalink / raw)
  To: Alex Vong; +Cc: guile-user

> 
> I think this would work:
> 
>   (define-syntax-rule (send self (method args ...))
>     (call-method self
>                  (symbol->string 'method)
>                  (list args ...)))
> 
> For example,
> 
>   (send date (set-dmy 1 1 2018))
> 
> will be expanded to
> 
>   (call-method date
>                (symbol->string 'set-dmy)
>                (list 1 1 2018))
> 
> which is equivalent to
> 
>   (call-method date "set-dmy" (list 1 1 2018))
> 

Thanks for your help!

-Mike Gran





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-12-13 18:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-13  0:30 Need help with macro Mike Gran
2018-12-13  1:34 ` Mark H Weaver
2018-12-13 18:14   ` Mike Gran
2018-12-13  1:38 ` Alex Vong
2018-12-13 18:15   ` Mike Gran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).