unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* syntax-local-value patch for discussion
@ 2011-12-05 18:12 Stefan Israelsson Tampe
  2011-12-08 21:58 ` Ian Price
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2011-12-05 18:12 UTC (permalink / raw)
  To: guile-devel


[-- Attachment #1.1: Type: text/plain, Size: 1983 bytes --]

So I tried to get hold of the macro binding. So with the following patch
wich should be enogh
for me to make progress porting rackets syntax parse to guile.

Would be very glad if we could find a interface to expose this information
that is sane
and rigid manner. So we should discuss this feature.

Anyway about the patch.
I added a fluid that is setted with a closure that captures enough syntax
information
so that we can lookup the macro value local or global. It basically uses
the same method
as psyntax macroexpander.

Now we can write,
(define-syntax info
  (lambda (x)
    (syntax-case x ()
      ((_ x)
        (pk (syntax-binding-info (syntax->datum #'x)))
        #'#f))))

and calling this in an example lead to
(let-syntax ((a (lambda (x) #'#f)))
      (info a))

;;; ((macro . #<procedure 1a68480 at ice-9/eval.scm:396:13 (a)>))

or

 (let ((a 1)) (info a))
    ((lexical . #{a 310}#))

So with this I can attach meta information to macros local or not by using
a weak hash.

Anyway a hack but it shows what is needed.

Happy Hacking :-)

---------- Forwarded message ----------
From: Stefan Israelsson Tampe <stefan.itampe@gmail.com>
Date: Sun, Dec 4, 2011 at 8:22 PM
Subject: syntax-local-value
To: guile-devel <guile-devel@gnu.org>


In looking at racket syntax-parse there seems to be some advanced macrology
that is not included in guile.

The light now is on the possibility to attach data to macros. I figure that
I could
reproduce this by using a weak hash-table but miss the functionality of

syntax-local-value

e.g.
http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-value%29%29<http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._%7E23%7E25kernel%29._syntax-local-value%29%29>

Basically the possibility to get the macro-object associated to a symbol in
an environment if I have understyand this.

So is there a guile feature that matches this at a reasonable level?

Regards
Stefan

[-- Attachment #1.2: Type: text/html, Size: 2493 bytes --]

[-- Attachment #2: boot-9-local-binding.diff --]
[-- Type: text/x-patch, Size: 515 bytes --]

diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index 5ac01b8..619d761 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -386,6 +386,7 @@ If there is no handler at all, Guile prints an error and then exits."
 (define generate-temporaries #f)
 (define bound-identifier=? #f)
 (define free-identifier=? #f)
+(define syntax-binding-info #f)
 
 ;; $sc-dispatch is an implementation detail of psyntax. It is used by
 ;; expanded macros, to dispatch an input against a set of patterns.

[-- Attachment #3: psyntax-local-binding.diff --]
[-- Type: text/x-patch, Size: 1720 bytes --]

diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index e522f54..70463a5 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -155,6 +155,10 @@
 (eval-when (compile)
   (set-current-module (resolve-module '(guile))))
 
+(define *macro-lookup* (make-fluid))
+(fluid-set! *macro-lookup* 
+            (lambda x (error "not in a macro evaluation context")))
+
 (let ()
   (define-syntax define-expansion-constructors
     (lambda (x)
@@ -1304,8 +1308,12 @@
                    (syntax-violation #f "encountered raw symbol in macro output"
                                      (source-wrap e w (wrap-subst w) mod) x))
                   (else (decorate-source x s)))))
-        (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
-                              (new-mark))))
+        (with-fluids ((*macro-lookup*
+                       (lambda (e) (lookup (id-var-name e w)
+                                           r mod))))
+                                           
+          (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
+                                (new-mark)))))
 
     (define expand-body
       ;; In processing the forms of the body, we create a new, empty wrap.
@@ -2398,10 +2406,14 @@
           (lambda* (x #:optional (m 'e) (esew '(eval)))
             (expand-top-sequence (list x) null-env top-wrap #f m esew
                                  (cons 'hygiene (module-name (current-module))))))
+    (set! syntax-binding-info
+          (lambda (x)
+            ((fluid-ref *macro-lookup*) x)))
 
     (set! identifier?
           (lambda (x)
             (nonsymbol-id? x)))
+    
 
     (set! datum->syntax
           (lambda (id datum)

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

* Re: syntax-local-value patch for discussion
  2011-12-05 18:12 syntax-local-value patch for discussion Stefan Israelsson Tampe
@ 2011-12-08 21:58 ` Ian Price
  2011-12-09 11:49   ` Stefan Israelsson Tampe
  2012-01-07  0:05 ` Andy Wingo
  2012-01-08 19:15 ` Mark H Weaver
  2 siblings, 1 reply; 13+ messages in thread
From: Ian Price @ 2011-12-08 21:58 UTC (permalink / raw)
  To: Stefan Israelsson Tampe; +Cc: guile-devel

Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:

> So I tried to get hold of the macro binding. So with the following patch wich should be enogh
> for me to make progress porting rackets syntax parse to guile.
>
> Would be very glad if we could find a interface to expose this information that is sane
> and rigid manner. So we should discuss this feature.
As it stands, I agree it is pretty simplistic, but I'm not sure what to
propose :) What is the intended use cases for this? A compile-time
values mechanism?

> Anyway about the patch.
> I added a fluid that is setted with a closure that captures enough syntax information
> so that we can lookup the macro value local or global. It basically uses the same method
> as psyntax macroexpander.
The patch looks fine to me, although I admit I have little experience
with psyntax.

>
> Now we can write,
> (define-syntax info
>   (lambda (x)
>     (syntax-case x ()
>       ((_ x)
>         (pk (syntax-binding-info (syntax->datum #'x)))
>         #'#f))))
FWIW, I wouldn't expect to have to pass a raw datum to any procedure
with a syntax prefix. If we keep this procedure, I think the
syntax->datum should be hid, or the procedure renamed.

> So with this I can attach meta information to macros local or not by
> using a weak hash.
I have 'define-type' & 'type-case' macros, basically copied from
racket's plai language[0][1] , that suffers from a complete lack of
error handling in the case where the type-id is not, in fact, a
type-id. If I were to use this mechanism, I would create a weak hash of
datatype-ids, adding them to the hash with 'define-type', and checking
if they are in the hash in my 'type-case' macro. Would that be right?

0. http://docs.racket-lang.org/plai/plai-scheme.html
1. I can post these if people want them
-- 
Ian Price

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



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

* Re: syntax-local-value patch for discussion
  2011-12-08 21:58 ` Ian Price
@ 2011-12-09 11:49   ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2011-12-09 11:49 UTC (permalink / raw)
  To: Ian Price; +Cc: guile-devel

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

Hi,

On Thu, Dec 8, 2011 at 10:58 PM, Ian Price <ianprice90@googlemail.com>wrote:

> Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:
>
> > So I tried to get hold of the macro binding. So with the following patch
> wich should be enogh
> > for me to make progress porting rackets syntax parse to guile.
> >
> > Would be very glad if we could find a interface to expose this
> information that is sane
> > and rigid manner. So we should discuss this feature.
> As it stands, I agree it is pretty simplistic, but I'm not sure what to
> propose :) What is the intended use cases for this? A compile-time
> values mechanism?
>

In syntax-parse they associate atribute data to an attribute variable that
also is a macro.
So later on when the symbol is used the compiler want to get hold of the
attribute data.
So there is a need to get hold on the lambda that is associated with the
symbol and then lookup
the data via a weak hash table.


> > Anyway about the patch.
> > I added a fluid that is setted with a closure that captures enough
> syntax information
> > so that we can lookup the macro value local or global. It basically uses
> the same method
> > as psyntax macroexpander.
> The patch looks fine to me, although I admit I have little experience
> with psyntax.
>

Ok,


> >
> > Now we can write,
> > (define-syntax info
> >   (lambda (x)
> >     (syntax-case x ()
> >       ((_ x)
> >         (pk (syntax-binding-info (syntax->datum #'x)))
> >         #'#f))))
> FWIW, I wouldn't expect to have to pass a raw datum to any procedure
> with a syntax prefix. If we keep this procedure, I think the
> syntax->datum should be hid, or the procedure renamed.
>

An idea is to  change the name to symbol-local-data. Another idea is to
return
the lookup function directly (I think that this might be needed as well to
make sure
that the same symbol has the same interpretation in two contexts)
So for this function we could use the name  local-symbol-lookup-function
and then builed any secondary interfaces on that inside a proper module.


> > So with this I can attach meta information to macros local or not by
> > using a weak hash.
> I have 'define-type' & 'type-case' macros, basically copied from
> racket's plai language[0][1] , that suffers from a complete lack of
> error handling in the case where the type-id is not, in fact, a
> type-id. If I were to use this mechanism, I would create a weak hash of
> datatype-ids, adding them to the hash with 'define-type', and checking
> if they are in the hash in my 'type-case' macro. Would that be right?
>

Yes you can use this mechanism to do what you wan't. There might be better
ways though.
Anyway
1. In a separate module make the type-id:s and let them be macros with the
lambda put as a key
in a weak key hash table
2. in using the type-id in the expansion of a type-case you can now lookup
the symbol's context and deduce the  macro binding, get the lambda and
check if it is in the weak key hash table. and as you say be able to do the
sanity check.

Another method would be to have the type-id:s syntactic context is a module
toplevel variable,
and from the syntax object deduce if it is a toplevel variable and if so
check if the id is in the hash table.
Maybe there is tools alredy made that does this in a simple straightforward
way?

If you would define a type-id locally then the only way to later check for
valid type-id is to do
(let-syntax ((type-id (register-and-return (lambda (x) (error "this is a
type-id not a syntactic element")))
     the-code-that-uses-type-id ...)
where you would use my suggestion.

the machanism I propose

> 0. http://docs.racket-lang.org/plai/plai-scheme.html
> 1. I can post these if people want them
> --
> Ian Price
>
> "Programming is like pinball. The reward for doing it well is
> the opportunity to do it again" - from "The Wizardy Compiled"
>

Cool, these libraries can be useful,
/Stefan

[-- Attachment #2: Type: text/html, Size: 5469 bytes --]

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

* Re: syntax-local-value patch for discussion
  2011-12-05 18:12 syntax-local-value patch for discussion Stefan Israelsson Tampe
  2011-12-08 21:58 ` Ian Price
@ 2012-01-07  0:05 ` Andy Wingo
  2012-01-08 17:47   ` Stefan Israelsson Tampe
  2012-01-08 19:15 ` Mark H Weaver
  2 siblings, 1 reply; 13+ messages in thread
From: Andy Wingo @ 2012-01-07  0:05 UTC (permalink / raw)
  To: Stefan Israelsson Tampe; +Cc: guile-devel

On Mon 05 Dec 2011 19:12, Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:

> (define-syntax info
>   (lambda (x)
>     (syntax-case x ()
>       ((_ x)
>         (pk (syntax-binding-info (syntax->datum #'x)))
>         #'#f))))

I agree with Ian that we should be operating on syntax objects here, not
on datums.  Also, what should the type of the return value be?  Racket
implies that it should be a procedure, no?

> and calling this in an example lead to
> (let-syntax ((a (lambda (x) #'#f)))
>       (info a))

Does it work on toplevel macros as well?

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-value patch for discussion
  2012-01-07  0:05 ` Andy Wingo
@ 2012-01-08 17:47   ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-08 17:47 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

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

On Sat, Jan 7, 2012 at 1:05 AM, Andy Wingo <wingo@pobox.com> wrote:

> On Mon 05 Dec 2011 19:12, Stefan Israelsson Tampe <stefan.itampe@gmail.com>
> writes:
>
> > (define-syntax info
> >   (lambda (x)
> >     (syntax-case x ()
> >       ((_ x)
> >         (pk (syntax-binding-info (syntax->datum #'x)))
> >         #'#f))))
>
> I agree with Ian that we should be operating on syntax objects here, not
> on datums.  Also, what should the type of the return value be?  Racket
> implies that it should be a procedure, no?
>

syntax-binding-info just returns the binding information used at a lookup
in psyntax for an identifier
but it would be better if it returns a lookup procedure that applied to a
syntax object gives the lookuped
information assuming that psyntax is not mutating. using this primitive we
can design a syntax-local-value
according to racket

e.g.
(syntax-local-value id-stx [failure-thunk intdef-ctx]) -> any
  id-stx        : syntax?
  failure-thunk : (or/c (-> any) #f)                          = #f
  intdef-ctx    : (or/c internal-definition-context? #f) = #f

This should return the value of the macro binding that can be anything and
if it's not a macro
eval failure thunk or return #f if not supplied. Also intef-ctx could in
our case be then lookup-function
returned by a call to syntax-binding-info in order to mimic the racket
logic. To note is that in syntax-parse
syntax classes are defined as a macro with a struct value instead of a
transformer. Also to not is that in racket they have special renamer macros
that interacts with this function in such a way that the syntax-local-value
of a renamer macro is following the renamer and calls this function again
on the renamer value
automagically. It should be noted that renamer macros is needed to make
syntax-parse clean in that you long descriptive names for the syntax
classes and it is assumed that you rename them when using the actual syntax
parse.



> > and calling this in an example lead to
> > (let-syntax ((a (lambda (x) #'#f)))
> >       (info a))
>
> Does it work on toplevel macros as well?
>
>
Yes!

/Stefan

[-- Attachment #2: Type: text/html, Size: 2784 bytes --]

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

* Re: syntax-local-value patch for discussion
  2011-12-05 18:12 syntax-local-value patch for discussion Stefan Israelsson Tampe
  2011-12-08 21:58 ` Ian Price
  2012-01-07  0:05 ` Andy Wingo
@ 2012-01-08 19:15 ` Mark H Weaver
  2012-01-08 21:28   ` Stefan Israelsson Tampe
  2012-01-14 16:42   ` Stefan Israelsson Tampe
  2 siblings, 2 replies; 13+ messages in thread
From: Mark H Weaver @ 2012-01-08 19:15 UTC (permalink / raw)
  To: Stefan Israelsson Tampe; +Cc: guile-devel

Hi Stefan,

Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:
> diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
> index e522f54..70463a5 100644
> --- a/module/ice-9/psyntax.scm
> +++ b/module/ice-9/psyntax.scm
> @@ -155,6 +155,10 @@
>  (eval-when (compile)
>    (set-current-module (resolve-module '(guile))))
>  
> +(define *macro-lookup* (make-fluid))
> +(fluid-set! *macro-lookup* 
> +            (lambda x (error "not in a macro evaluation context")))
> +
>  (let ()
>    (define-syntax define-expansion-constructors
>      (lambda (x)
> @@ -1304,8 +1308,12 @@
>                     (syntax-violation #f "encountered raw symbol in macro output"
>                                       (source-wrap e w (wrap-subst w) mod) x))
>                    (else (decorate-source x s)))))
> -        (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> -                              (new-mark))))
> +        (with-fluids ((*macro-lookup*
> +                       (lambda (e) (lookup (id-var-name e w)
> +                                           r mod))))
> +                                           
> +          (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> +                                (new-mark)))))
>  
>      (define expand-body
>        ;; In processing the forms of the body, we create a new, empty wrap.

This doesn't look quite right to me.

At this one point only, where a macro is expanded, you capture the
lexical environment (r w mod) in your fluid.  This is the lexical
environment that you use to lookup plain symbols later passed to
`syntax-binding-info'.

Will this approach will be robust in the general case?  For example,
what happens if you use a macro in one module to generate a macro in
another module that uses syntax-binding-info on a syntax object that
came from yet another module?

A few suggestions:

First, as others have pointed out, you should be passing syntax-objects
to `syntax-binding-info' instead of plain symbols.  This one change
alone will make this code far robust, because syntax-objects include
their own wrap and module.

Second, in your call to `lookup', you should pass the module that came
from the syntax-object, instead of the module captured from the most
recent macro expansion.  Please take a look at how psyntax's internal
procedure `syntax-type' looks up syntax-objects (compared with how it
looks up plain symbols).  I think you should emulate that logic.

Third, are you sure that the `r' captured from the most recent macro
expansion will be recent enough in all cases to include the binding
that's being queried?  `r' is extended in quite a few places in psyntax,
for various different binding constructs.

      Best,
       Mark



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

* Re: syntax-local-value patch for discussion
  2012-01-08 19:15 ` Mark H Weaver
@ 2012-01-08 21:28   ` Stefan Israelsson Tampe
  2012-01-14 16:42   ` Stefan Israelsson Tampe
  1 sibling, 0 replies; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-08 21:28 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

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

Thanks for taking time to help with this!

On Sun, Jan 8, 2012 at 8:15 PM, Mark H Weaver <mhw@netris.org> wrote:

> Hi Stefan,
>
> Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:
> > diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
> > index e522f54..70463a5 100644
> > --- a/module/ice-9/psyntax.scm
> > +++ b/module/ice-9/psyntax.scm
> > @@ -155,6 +155,10 @@
> >  (eval-when (compile)
> >    (set-current-module (resolve-module '(guile))))
> >
> > +(define *macro-lookup* (make-fluid))
> > +(fluid-set! *macro-lookup*
> > +            (lambda x (error "not in a macro evaluation context")))
> > +
> >  (let ()
> >    (define-syntax define-expansion-constructors
> >      (lambda (x)
> > @@ -1304,8 +1308,12 @@
> >                     (syntax-violation #f "encountered raw symbol in
> macro output"
> >                                       (source-wrap e w (wrap-subst w)
> mod) x))
> >                    (else (decorate-source x s)))))
> > -        (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> > -                              (new-mark))))
> > +        (with-fluids ((*macro-lookup*
> > +                       (lambda (e) (lookup (id-var-name e w)
> > +                                           r mod))))
> > +
> > +          (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> > +                                (new-mark)))))
> >
> >      (define expand-body
> >        ;; In processing the forms of the body, we create a new, empty
> wrap.
>
> This doesn't look quite right to me.
>
> At this one point only, where a macro is expanded, you capture the
> lexical environment (r w mod) in your fluid.  This is the lexical
> environment that you use to lookup plain symbols later passed to
> `syntax-binding-info'.
>

I first tought that the semantic meant that to get the macro binding for a
symbol in the stored lexical
environment. and acording to the racket doc, in a supplied context or the
context of the expansion (hence
the use of the fluid) But reading your mail the context mentioned in the
doc is probably related to
syntax-parameters. Hence I will try to folllow your suggestions to refine
the approach.

/Stefan

[-- Attachment #2: Type: text/html, Size: 2786 bytes --]

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

* Re: syntax-local-value patch for discussion
  2012-01-08 19:15 ` Mark H Weaver
  2012-01-08 21:28   ` Stefan Israelsson Tampe
@ 2012-01-14 16:42   ` Stefan Israelsson Tampe
  2012-01-19  9:50     ` Stefan Israelsson Tampe
  1 sibling, 1 reply; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-14 16:42 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

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

Ok, I have tried follow your suggestion,
here is what I could make,

        (with-fluids ((*macro-lookup*
                       (lambda (e)
                         (cond
                          ((number? e)
                           (pk w))

                          ((symbol? e)
                           (lookup (id-var-name e w)
                                   r mod))

                          ((syntax-object? e)
                           (lookup (id-var-name
                                    (syntax-object-expression e)
                                    (syntax-object-wrap e))
                                   r
                                   (or
                                    (syntax-object-module e)
                                    mod)))
                          (else #f)))))

just look at the syntax-object? part for now. You will see that I only use
syntax-object-wrap and not the joining with w which fails when I try to do
that using e.g.
 ((syntax-object? e)
          (syntax-type (syntax-object-expression e)
                       r
                       (join-wraps w (syntax-object-wrap e))
                       (or (source-annotation e) s) rib
                       (or (syntax-object-module e) mod) for-car?))

which is the syntax? part of the syntax-type function. Hence I tried
(join-wraps w (syntax-object-wrap e))

but that does not work.

comments?

/Stefan

On Sun, Jan 8, 2012 at 8:15 PM, Mark H Weaver <mhw@netris.org> wrote:

> Hi Stefan,
>
> Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:
> > diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
> > index e522f54..70463a5 100644
> > --- a/module/ice-9/psyntax.scm
> > +++ b/module/ice-9/psyntax.scm
> > @@ -155,6 +155,10 @@
> >  (eval-when (compile)
> >    (set-current-module (resolve-module '(guile))))
> >
> > +(define *macro-lookup* (make-fluid))
> > +(fluid-set! *macro-lookup*
> > +            (lambda x (error "not in a macro evaluation context")))
> > +
> >  (let ()
> >    (define-syntax define-expansion-constructors
> >      (lambda (x)
> > @@ -1304,8 +1308,12 @@
> >                     (syntax-violation #f "encountered raw symbol in
> macro output"
> >                                       (source-wrap e w (wrap-subst w)
> mod) x))
> >                    (else (decorate-source x s)))))
> > -        (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> > -                              (new-mark))))
> > +        (with-fluids ((*macro-lookup*
> > +                       (lambda (e) (lookup (id-var-name e w)
> > +                                           r mod))))
> > +
> > +          (rebuild-macro-output (p (source-wrap e (anti-mark w) s mod))
> > +                                (new-mark)))))
> >
> >      (define expand-body
> >        ;; In processing the forms of the body, we create a new, empty
> wrap.
>
> This doesn't look quite right to me.
>
> At this one point only, where a macro is expanded, you capture the
> lexical environment (r w mod) in your fluid.  This is the lexical
> environment that you use to lookup plain symbols later passed to
> `syntax-binding-info'.
>
> Will this approach will be robust in the general case?  For example,
> what happens if you use a macro in one module to generate a macro in
> another module that uses syntax-binding-info on a syntax object that
> came from yet another module?
>
> A few suggestions:
>
> First, as others have pointed out, you should be passing syntax-objects
> to `syntax-binding-info' instead of plain symbols.  This one change
> alone will make this code far robust, because syntax-objects include
> their own wrap and module.
>
> Second, in your call to `lookup', you should pass the module that came
> from the syntax-object, instead of the module captured from the most
> recent macro expansion.  Please take a look at how psyntax's internal
> procedure `syntax-type' looks up syntax-objects (compared with how it
> looks up plain symbols).  I think you should emulate that logic.
>
> Third, are you sure that the `r' captured from the most recent macro
> expansion will be recent enough in all cases to include the binding
> that's being queried?  `r' is extended in quite a few places in psyntax,
> for various different binding constructs.
>
>      Best,
>       Mark
>

[-- Attachment #2: Type: text/html, Size: 5144 bytes --]

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

* Re: syntax-local-value patch for discussion
  2012-01-14 16:42   ` Stefan Israelsson Tampe
@ 2012-01-19  9:50     ` Stefan Israelsson Tampe
  2012-01-23 10:53       ` Andy Wingo
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-19  9:50 UTC (permalink / raw)
  To: guile-devel

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

Hi,

Working on porting syntax-parse is a learning experience and I know
understand how it uses
syntax-local-value as a way to lookup a syntax object by joining the wraps
together with the
total wrap at the macro call.

The question is if this really are the total wrap e.g. contains the history
of all the previous variable
and macro and syntax definitions. Is this so or are it a partial part of
the history?

Anyway syntax-parse works by defining pattern variables the hard core way
and I have now changed that
to a more standard way of implementation leading to skipping
syntax-local-value (variables are stored in
a struct and they does then not contain the correct wrap) but instead
examine the syntax variables used
and transport the wraps of the containing syntax variable of the struct.
For this I have a messy and sloppy
algorithm just to make it work - but I would like to have a syntax-join
function that takes two syntax objects
and join them correctly and robustly in the pressense of eventual marks or
not.

Anyway this now works,

(define-syntax-class t (pattern (x:id y)))
(define-syntax a (lambda (x) (syntax-parse x ((_ z:t ...) #'(+ z.y ...)))))
(a (x1 1) (x2 2) (x3 3))
$1 = 6

/Stefan

[-- Attachment #2: Type: text/html, Size: 1293 bytes --]

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

* Re: syntax-local-value patch for discussion
  2012-01-19  9:50     ` Stefan Israelsson Tampe
@ 2012-01-23 10:53       ` Andy Wingo
  2012-01-23 16:06         ` Stefan Israelsson Tampe
  0 siblings, 1 reply; 13+ messages in thread
From: Andy Wingo @ 2012-01-23 10:53 UTC (permalink / raw)
  To: Stefan Israelsson Tampe; +Cc: guile-devel

Hi Stefan,

On Thu 19 Jan 2012 10:50, Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:

> Working on porting syntax-parse is a learning experience and I know
> understand how it uses syntax-local-value as a way to lookup a syntax
> object by joining the wraps together with the total wrap at the macro
> call.

syntax-local-binding just uses the wrap from the id that you give it,
without joining it to the macro expansion environment's wrap.

> I would like to have a syntax-join function that takes two syntax
> objects and join them correctly and robustly in the pressense of
> eventual marks or not.

Why would you want to do something like this?

You might try writing the documentation of the function first; it would
clarify the conversation.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-value patch for discussion
  2012-01-23 10:53       ` Andy Wingo
@ 2012-01-23 16:06         ` Stefan Israelsson Tampe
  2012-01-26 11:31           ` Andy Wingo
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-23 16:06 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

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

Ok, here is a discussoin using code in syntax-parse.

Let's start with the defintion of a syntax-class, str in the macro package
syntax-parse:
(define-syntax-class str #:attributes () #:opaque #:commit
  #:description "string"
  (pattern (~and x (~fail #:unless (string? (syntax-e #'x))))))

So the and patterns first match x and then on the same element match a ~fail
that fails if the supplied code (string? (syntax-e #'x)) is false.

The headake for me is that #'(string? (syntax-e #'x)) is stored in a struct
and hence
does not get wrapped correctly e.g. after the packaging of this code in a
struct, say S
we will then issue something like the following code in the expansion of
the first match

#'(with-syntax ((x  stx))  (parse stx S))

and when parse is ready to unpack S we could have

S = #(syntax-object #<struct-s> wrap-part hygiene)

Now I basically solve this problem by constructing
a = (vector 'syntax-object (vector-ref (struct-s-code (syntax->datum S)) 1)
(un-mark wrap-part) hygiene)
crossing the fingers that the "code" will be nonatomic and then the
expander will use it like,

(with-syntax ((code a)) #'( .... code))

This is the story. I do not want to rest here because this solution is not
resistant to bitrot and depends on internals that I do not want to touch.
The solution would be to have an interface in guile that allows to write,

(with-syntax ((code (syntax-embedd (struct-s-code (syntax->datum S)) S)))
(.... code ...))

e.g.

(syntax-embedd exp env-stx) = embedds exp in the syntax env-stx

I'm much more fine with dropping env-stx and replace that with the
equivalent syntax environment at the macro call

I Hope that things are less foggy now!

Regards
Stefan




On Mon, Jan 23, 2012 at 11:53 AM, Andy Wingo <wingo@pobox.com> wrote:

> Hi Stefan,
>
> On Thu 19 Jan 2012 10:50, Stefan Israelsson Tampe <stefan.itampe@gmail.com>
> writes:
>
> > Working on porting syntax-parse is a learning experience and I know
> > understand how it uses syntax-local-value as a way to lookup a syntax
> > object by joining the wraps together with the total wrap at the macro
> > call.
>
> syntax-local-binding just uses the wrap from the id that you give it,
> without joining it to the macro expansion environment's wrap.
>
> > I would like to have a syntax-join function that takes two syntax
> > objects and join them correctly and robustly in the pressense of
> > eventual marks or not.
>
> Why would you want to do something like this?
>
> You might try writing the documentation of the function first; it would
> clarify the conversation.
>
> Regards,
>
> Andy
> --
> http://wingolog.org/
>

[-- Attachment #2: Type: text/html, Size: 3360 bytes --]

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

* Re: syntax-local-value patch for discussion
  2012-01-23 16:06         ` Stefan Israelsson Tampe
@ 2012-01-26 11:31           ` Andy Wingo
  2012-01-26 15:49             ` Stefan Israelsson Tampe
  0 siblings, 1 reply; 13+ messages in thread
From: Andy Wingo @ 2012-01-26 11:31 UTC (permalink / raw)
  To: Stefan Israelsson Tampe; +Cc: guile-devel

Hi Stefan,

On Mon 23 Jan 2012 17:06, Stefan Israelsson Tampe <stefan.itampe@gmail.com> writes:

> and when parse is ready to unpack S we could have
>
> S = #(syntax-object #<struct-s> wrap-part hygiene)
>
> Now I basically solve this problem by constructing

Why do syntax->datum and datum->syntax not work for you to pack and
unpack these structs in syntax objects?

> a = (vector 'syntax-object (vector-ref (struct-s-code (syntax->datum S)) 1) (un-mark wrap-part) hygiene)

Gross :)

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-value patch for discussion
  2012-01-26 11:31           ` Andy Wingo
@ 2012-01-26 15:49             ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-26 15:49 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

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

Remember it's not symbols but code objects that this refers to so I need to
use the syntactic information and only augment the objects that can be
joined
and leave the other syntactic objects like symbols from another module and
so
on.

I will try to leave the struct representation and use only lists. This will
perhaps fix the problems
I have.

/Stefan

On Thu, Jan 26, 2012 at 12:31 PM, Andy Wingo <wingo@pobox.com> wrote:

> Hi Stefan,
>
> On Mon 23 Jan 2012 17:06, Stefan Israelsson Tampe <stefan.itampe@gmail.com>
> writes:
>
> > and when parse is ready to unpack S we could have
> >
> > S = #(syntax-object #<struct-s> wrap-part hygiene)
> >
> > Now I basically solve this problem by constructing
>
> Why do syntax->datum and datum->syntax not work for you to pack and
> unpack these structs in syntax objects?
>
> > a = (vector 'syntax-object (vector-ref (struct-s-code (syntax->datum S))
> 1) (un-mark wrap-part) hygiene)
>
> Gross :)
>
> Andy
> --
> http://wingolog.org/
>

[-- Attachment #2: Type: text/html, Size: 1542 bytes --]

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

end of thread, other threads:[~2012-01-26 15:49 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-05 18:12 syntax-local-value patch for discussion Stefan Israelsson Tampe
2011-12-08 21:58 ` Ian Price
2011-12-09 11:49   ` Stefan Israelsson Tampe
2012-01-07  0:05 ` Andy Wingo
2012-01-08 17:47   ` Stefan Israelsson Tampe
2012-01-08 19:15 ` Mark H Weaver
2012-01-08 21:28   ` Stefan Israelsson Tampe
2012-01-14 16:42   ` Stefan Israelsson Tampe
2012-01-19  9:50     ` Stefan Israelsson Tampe
2012-01-23 10:53       ` Andy Wingo
2012-01-23 16:06         ` Stefan Israelsson Tampe
2012-01-26 11:31           ` Andy Wingo
2012-01-26 15:49             ` Stefan Israelsson Tampe

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