unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* syntax-local-binding
@ 2012-01-15 17:00 Andy Wingo
  2012-01-15 17:22 ` syntax-local-binding Andy Wingo
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-15 17:00 UTC (permalink / raw)
  To: guile-devel

Hi list,

Attached is a patch that implements a new accessor,
syntax-local-binding.  It's like syntax-local-value, but can also
determine if an identifier is a pattern var or a normal lexical.

  > (define-syntax local-binding
      (lambda (x)
        (syntax-case x ()
          ((_ id) (identifier? #'id)
           (call-with-values (lambda () (syntax-local-binding #'id))
             (lambda (x y)
               (with-syntax ((type (datum->syntax #'here x)))
                 #''type)))))))
  > (let-syntax ((x (lambda (x) 10))) (local-binding x))
  $3 = local-macro
  > (syntax-case #'(foo) () ((id) (local-binding id)))
  $4 = pattern-variable
  > (let ((x 10)) (local-binding x))
  $5 = lexical

It returns two values.  The first is a symbol, either `local-macro',
`lexical', or `pattern-variable'.  The second is specific to the type.
For local-macro it is the transformer binding.  For lexical it is the
gensym name of the lexical.  For pattern variables, it is something
opaque that identifies that pattern var.

Inspired by a patch by Stefan Israelsson Tampe.

I'm going to try to implement the-environment with this.  We'll see how
it goes!

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-15 17:00 syntax-local-binding Andy Wingo
@ 2012-01-15 17:22 ` Andy Wingo
  2012-01-19 11:41   ` syntax-local-binding Andy Wingo
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-15 17:22 UTC (permalink / raw)
  To: guile-devel

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

On Sun 15 Jan 2012 18:00, Andy Wingo <wingo@pobox.com> writes:

> Attached is a patch that implements a new accessor,
> syntax-local-binding.

Here 'tis!


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-add-syntax-local-binding.patch --]
[-- Type: text/x-diff, Size: 4309 bytes --]

From 09ba44abeb47cdf4ec61df6f7386217f0cbe30c7 Mon Sep 17 00:00:00 2001
From: Andy Wingo <wingo@pobox.com>
Date: Sun, 15 Jan 2012 17:51:02 +0100
Subject: [PATCH] add syntax-local-binding

* module/ice-9/boot-9.scm (syntax-local-binding): New binding.

* module/ice-9/psyntax.scm: Locally define a fluid that holds the
  "transformer environment".  with-transformer-environment calls a
  procedure with the transformer environment, or raises an error if
  called outside the extent of a transformer.  Bind
  transformer-environment in expand-macro.
  (syntax-local-binding): New procedure to return binding information of
  a lexially bound identifier (a lexical, local macro, or pattern
  variable).
---
 module/ice-9/boot-9.scm  |    1 +
 module/ice-9/psyntax.scm |   39 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index f661d08..9cdd8d1 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -389,6 +389,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-local-binding #f)
 
 ;; $sc-dispatch is an implementation detail of psyntax. It is used by
 ;; expanded macros, to dispatch an input against a set of patterns.
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index 1bf3c32..dcabafe 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -786,6 +786,14 @@
                       id))))))
          (else (syntax-violation 'id-var-name "invalid id" id)))))
 
+    (define transformer-environment
+      (make-fluid
+       (lambda (k)
+         (error "called outside the dynamic extent of a syntax transformer"))))
+
+    (define (with-transformer-environment k)
+      ((fluid-ref transformer-environment) k))
+
     ;; free-id=? must be passed fully wrapped ids since (free-id=? x y)
     ;; may be true even if (free-id=? (wrap x w) (wrap y w)) is not.
 
@@ -1321,8 +1329,10 @@
                    (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 ((transformer-environment
+                       (lambda (k) (k e r w s rib 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.
@@ -2435,6 +2445,31 @@
     (set! syntax-source
           (lambda (x) (source-annotation x)))
 
+    (set! syntax-local-binding
+          (lambda (id)
+            (arg-check nonsymbol-id? id 'syntax-local-value)
+            (with-transformer-environment
+             (lambda (e r w s rib mod)
+               (define (strip-anti-mark w)
+                 (let ((ms (wrap-marks w)) (s (wrap-subst w)))
+                   (if (and (pair? ms) (eq? (car ms) the-anti-mark))
+                       ;; output is from original text
+                       (make-wrap (cdr ms) (if rib (cons rib (cdr s)) (cdr s)))
+                       ;; output introduced by macro
+                       (error "what!!!"))))
+               (let ((label (id-var-name (syntax-object-expression id)
+                                         (strip-anti-mark (syntax-object-wrap id)))))
+                 (if (not (string? label))
+                     (error "identifier not lexically bound" id))
+                 (let ((b (assq-ref r label)))
+                   (if (not b)
+                       (error "displaced lexical" id))
+                   (case (binding-type b)
+                     ((lexical) (values 'lexical (binding-value b)))
+                     ((macro) (values 'local-macro (binding-value b)))
+                     ((syntax) (values 'pattern-variable (binding-value b)))
+                     (else (error "unpossible!" b)))))))))
+
     (set! generate-temporaries
           (lambda (ls)
             (arg-check list? ls 'generate-temporaries)
-- 
1.7.8.3


[-- Attachment #3: Type: text/plain, Size: 26 bytes --]


-- 
http://wingolog.org/

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

* Re: syntax-local-binding
  2012-01-15 17:22 ` syntax-local-binding Andy Wingo
@ 2012-01-19 11:41   ` Andy Wingo
  2012-01-20 20:26     ` syntax-local-binding Mark H Weaver
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-19 11:41 UTC (permalink / raw)
  To: guile-devel

Hello,

I have now pushed an implementation of syntax-local-binding to
stable-2.0, with the following documentation.  In the spirit of Eli's
note on Racket's syntax-local-value, it also works with identifiers that
are bound at the module level or the top level.  Comments and patches
welcome.

Cheers,

Andy

 -- Scheme Procedure: syntax-local-binding id
     Resolve the identifer ID, a syntax object, within the current
     lexical environment, and return two values, the binding type and a
     binding value.  The binding type is a symbol, which may be one of
     the following:

    `lexical'
          A lexically-bound variable.  The value is a unique token (in
          the sense of `eq?') identifying this binding.

    `macro'
          A syntax transformer, either local or global.  The value is
          the transformer procedure.

    `pattern-variable'
          A pattern variable, bound via syntax-case.  The value is an
          opaque object, internal to the expander.

    `displaced-lexical'
          A lexical variable that has gone out of scope.  This can
          happen if a badly-written procedural macro saves a syntax
          object, then attempts to introduce it in a context in which
          it is unbound.  The value is `#f'.

    `global'
          A global binding.  The value is a pair, whose head is the
          symbol, and whose tail is the name of the module in which to
          resolve the symbol.

    `other'
          Some other binding, like `lambda' or other core bindings.  The
          value is `#f'.

     This is a very low-level procedure, with limited uses.  One case in
     which it is useful is to build abstractions that associate
     auxiliary information with macros:

          (define aux-property (make-object-property))
          (define-syntax-rule (with-aux aux value)
            (let ((trans value))
              (set! (aux-property trans) aux)
              trans)))
          (define-syntax retrieve-aux
            (lambda (x)
              (syntax-case x ()
                ((x id)
                 (call-with-values (lambda () (syntax-local-binding #'id))
                   (lambda (type val)
                     (with-syntax ((aux (datum->syntax #'here
                                                       (and (eq? type 'macro)
                                                            (aux-property val)))))
                       #''aux)))))))
          (define-syntax foo
            (with-aux 'bar
              (syntax-rules () ((_) 'foo))))
          (foo)
          => foo
          (retrieve-aux foo)
          => bar

     `syntax-local-binding' must be called within the dynamic extent of
     a syntax transformer; to call it otherwise will signal an error.

-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-19 11:41   ` syntax-local-binding Andy Wingo
@ 2012-01-20 20:26     ` Mark H Weaver
  2012-01-20 21:23       ` syntax-local-binding Andy Wingo
  0 siblings, 1 reply; 27+ messages in thread
From: Mark H Weaver @ 2012-01-20 20:26 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> writes:
>     `lexical'
>           A lexically-bound variable.  The value is a unique token (in
>           the sense of `eq?') identifying this binding.
>
>     `macro'
>           A syntax transformer, either local or global.  The value is
>           the transformer procedure.

Ironically, `syntax-local-binding' renders the current simple
implementation strategy of `the-environment' inadequate, because
identifier-syntax is no longer sufficient to simulate a lexical.

More importantly, this exposing of internal binding representations will
interfere with our ability to change the representations later.

In particular, I was hoping to change the binding representation of
`syntax-rules' macros so that they are serializable.  In particular,
they would be represented by the `syntax-rules' form itself (the same
one that psyntax currently passes to `primitive-eval' to produce the
transformer procedure).  A weak-key hash table would cache the compiled
transformer procedures.

This would allow (the-environment) to capture locally-bound
`syntax-rules' macros.  Unfortunately, `syntax-local-binding', as
currently documented, now makes this impossible.

    Thanks,
      Mark



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

* Re: syntax-local-binding
  2012-01-20 20:26     ` syntax-local-binding Mark H Weaver
@ 2012-01-20 21:23       ` Andy Wingo
  2012-01-20 22:03         ` syntax-local-binding Mark H Weaver
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-20 21:23 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

On Fri 20 Jan 2012 21:26, Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> writes:
>>     `lexical'
>>           A lexically-bound variable.  The value is a unique token (in
>>           the sense of `eq?') identifying this binding.
>>
>>     `macro'
>>           A syntax transformer, either local or global.  The value is
>>           the transformer procedure.
>
> Ironically, `syntax-local-binding' renders the current simple
> implementation strategy of `the-environment' inadequate, because
> identifier-syntax is no longer sufficient to simulate a lexical.

Why do you say that?

> In particular, I was hoping to change the binding representation of
> `syntax-rules' macros so that they are serializable.  In particular,
> they would be represented by the `syntax-rules' form itself (the same
> one that psyntax currently passes to `primitive-eval' to produce the
> transformer procedure).  A weak-key hash table would cache the compiled
> transformer procedures.
>
> This would allow (the-environment) to capture locally-bound
> `syntax-rules' macros.  Unfortunately, `syntax-local-binding', as
> currently documented, now makes this impossible.

Why do you think that?  The procedures do carry metadata; I understood
that that was your strategy, to use the serialization of the
syntax-rules form in the procedure metadata.

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-20 21:23       ` syntax-local-binding Andy Wingo
@ 2012-01-20 22:03         ` Mark H Weaver
  2012-01-22  0:03           ` syntax-local-binding Ludovic Courtès
  2012-01-23 16:05           ` syntax-local-binding Andy Wingo
  0 siblings, 2 replies; 27+ messages in thread
From: Mark H Weaver @ 2012-01-20 22:03 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> writes:

> On Fri 20 Jan 2012 21:26, Mark H Weaver <mhw@netris.org> writes:
>
>> Andy Wingo <wingo@pobox.com> writes:
>>>     `lexical'
>>>           A lexically-bound variable.  The value is a unique token (in
>>>           the sense of `eq?') identifying this binding.
>>>
>>>     `macro'
>>>           A syntax transformer, either local or global.  The value is
>>>           the transformer procedure.
>>
>> Ironically, `syntax-local-binding' renders the current simple
>> implementation strategy of `the-environment' inadequate, because
>> identifier-syntax is no longer sufficient to simulate a lexical.
>
> Why do you say that?

Because it breaks your nice equivalence.  For example:

  (let ((x 1))
    (syntax-local-binding #'x))

is not equivalent to:

  (let ((x 1))
    (local-eval '(syntax-local-binding #'x) (the-environment)))

Put another way: if anyone uses `syntax-local-binding' to distinguish
lexical variables from macros in some clever macro of theirs, this means
that `local-eval' is now buggy with regard to their clever macro.

>> in particular, I was hoping to change the binding representation of
>> `syntax-rules' macros so that they are serializable.  In particular,
>> they would be represented by the `syntax-rules' form itself (the same
>> one that psyntax currently passes to `primitive-eval' to produce the
>> transformer procedure).  A weak-key hash table would cache the compiled
>> transformer procedures.
>>
>> This would allow (the-environment) to capture locally-bound
>> `syntax-rules' macros.  Unfortunately, `syntax-local-binding', as
>> currently documented, now makes this impossible.
>
> Why do you think that?  The procedures do carry metadata; I understood
> that that was your strategy, to use the serialization of the
> syntax-rules form in the procedure metadata.

Well, this was in the context of a new strategy where psyntax would
include a new core form called `call-with-current-local-expander' that
calls its parameter (a procedure or macro) with a procedure that accepts
an expression and returns an expanded form.  In this case, the most
straightforward implementation would simply serialize the (r w mod)
structures directly.

Toward that end, I was thinking it would be nice to keep those
structures serializable.  The only part that's not currently
serializable are the transformer procedures for local macros.
Thus the change in representation.

More specifically: instead of attaching procedure properties/metadata to
the transformer procedures as is currently done, that information would
be put directly into the binding.  An alist would probably make the most
sense.  The source code of the macro (whatever's currently passed to
`primitive-eval') would also be included.

This may or may not be a good idea, I dunno.  I haven't fully thought it
through.  However, that's not the point.  The point is that by exposing
these details in the API, you are constraining our ability to make
changes of this kind.  I think that's very unfortunate.

     Mark



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

* Re: syntax-local-binding
  2012-01-20 22:03         ` syntax-local-binding Mark H Weaver
@ 2012-01-22  0:03           ` Ludovic Courtès
  2012-01-23 16:05           ` syntax-local-binding Andy Wingo
  1 sibling, 0 replies; 27+ messages in thread
From: Ludovic Courtès @ 2012-01-22  0:03 UTC (permalink / raw)
  To: guile-devel

Hi,

Mark H Weaver <mhw@netris.org> skribis:

> Because it breaks your nice equivalence.  For example:
>
>   (let ((x 1))
>     (syntax-local-binding #'x))
>
> is not equivalent to:
>
>   (let ((x 1))
>     (local-eval '(syntax-local-binding #'x) (the-environment)))
>
> Put another way: if anyone uses `syntax-local-binding' to distinguish
> lexical variables from macros in some clever macro of theirs, this means
> that `local-eval' is now buggy with regard to their clever macro.

What about recommending against “clever macros” that use
‘syntax-local-binding’, or documenting the limitation in how
‘local-eval’ and ‘syntax-local-binding’ would interact?

After all, the point of ‘local-eval’ is to provide a compatibility later
with 1.8, and ‘syntax-local-binding’ didn’t exist there.

Thanks,
Ludo’.




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

* Re: syntax-local-binding
  2012-01-20 22:03         ` syntax-local-binding Mark H Weaver
  2012-01-22  0:03           ` syntax-local-binding Ludovic Courtès
@ 2012-01-23 16:05           ` Andy Wingo
  2012-01-23 21:03             ` syntax-local-binding Mark H Weaver
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-23 16:05 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

Heya Mark,

On Fri 20 Jan 2012 23:03, Mark H Weaver <mhw@netris.org> writes:

>   (let ((x 1))
>     (syntax-local-binding #'x))
>
> is not equivalent to:
>
>   (let ((x 1))
>     (local-eval '(syntax-local-binding #'x) (the-environment)))

Indeed; bummer!  I think, though, that this is simply a consequence of
giving more power to macro writers.

It is analogous in some ways to the changes that identifier-syntax
introduce into macro writing: with identifier-syntax, one can no longer
write a code walker with syntax-rules pattern matching, as single
identifiers may expand out to complicated expressions, possibly even
with side effects.

>> Why do you think that?  The procedures do carry metadata; I understood
>> that that was your strategy, to use the serialization of the
>> syntax-rules form in the procedure metadata.
>
> Well, this was in the context of a new strategy where psyntax would
> include a new core form called `call-with-current-local-expander' that
> calls its parameter (a procedure or macro) with a procedure that accepts
> an expression and returns an expanded form.  In this case, the most
> straightforward implementation would simply serialize the (r w mod)
> structures directly.
>
> Toward that end, I was thinking it would be nice to keep those
> structures serializable.  The only part that's not currently
> serializable are the transformer procedures for local macros.
> Thus the change in representation.

I have been staring at this empty page here for a little while, writing
and re-writing, but I can't get over a feeling that I really don't want
this kind of work in psyntax itself.  Who knows, maybe you have really
convincing arguments here, but this particular argument should not be
driving a decision about e.g. including syntax-local-binding or not.

That sounds negative, and in a way of course it is -- but still, I'd
much rather enable people to make powerful syntactic abstractions like
local-eval outside psyntax.  Syntax-parse, for example, if it ever
lands, will land in the form of a module

In this case there are lots of strategies you could use.  We could
change psyntax to embed the syntax objects in the procedure meta-data,
like I said.  Ice-9 local-eval could #:replace its own syntax-rules.  We
could (and probably should) do procedure serialization.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-23 16:05           ` syntax-local-binding Andy Wingo
@ 2012-01-23 21:03             ` Mark H Weaver
  2012-01-23 22:19               ` syntax-local-binding Andy Wingo
  0 siblings, 1 reply; 27+ messages in thread
From: Mark H Weaver @ 2012-01-23 21:03 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> writes:

> On Fri 20 Jan 2012 23:03, Mark H Weaver <mhw@netris.org> writes:
>
>>   (let ((x 1))
>>     (syntax-local-binding #'x))
>>
>> is not equivalent to:
>>
>>   (let ((x 1))
>>     (local-eval '(syntax-local-binding #'x) (the-environment)))
>
> Indeed; bummer!  I think, though, that this is simply a consequence of
> giving more power to macro writers.
>
> It is analogous in some ways to the changes that identifier-syntax
> introduce into macro writing: with identifier-syntax, one can no longer
> write a code walker with syntax-rules pattern matching, as single
> identifiers may expand out to complicated expressions, possibly even
> with side effects.

This is false.  Macros are always expanded _before_ any of their
arguments are expanded.  Therefore, a code walker sees the unexpanded
forms, including any "simulated variables" bound by identifier-syntax.

>>> Why do you think that?  The procedures do carry metadata; I understood
>>> that that was your strategy, to use the serialization of the
>>> syntax-rules form in the procedure metadata.
>>
>> Well, this was in the context of a new strategy where psyntax would
>> include a new core form called `call-with-current-local-expander' that
>> calls its parameter (a procedure or macro) with a procedure that accepts
>> an expression and returns an expanded form.  In this case, the most
>> straightforward implementation would simply serialize the (r w mod)
>> structures directly.
>>
>> Toward that end, I was thinking it would be nice to keep those
>> structures serializable.  The only part that's not currently
>> serializable are the transformer procedures for local macros.
>> Thus the change in representation.
>
> I have been staring at this empty page here for a little while, writing
> and re-writing, but I can't get over a feeling that I really don't want
> this kind of work in psyntax itself.

Your priorities are reversed from what they ought to be.

What you _should_ be worried about is making commitments in our API that
we must continue to support forever.  This is a _real_ problem, since it
constrains our ability to modify our implementation in the future.

Putting the `the-environment' in psyntax is, at worst, a stylistic
issue.  Whether it belongs there is a matter of taste, but however
strongly you may feel about that, it is a purely _internal_
implementation issue.  The really important thing is that it commits us
to _nothing_.  There's nothing stopping us from radically reimplementing
it later.  In particular, there's nothing stopping us from moving it out
of psyntax later.

Guile has been in existence for a couple of decades already, and I hope
that it will be actively used for many decades to come.  With that in
mind, please consider the long view.  One of the reasons Scheme has
lasted so long is because it tries exceptionally hard to hide internal
implementation details.  Implementations that expose too much internal
detail may derive a short-term benefit from doing so, but it comes at
the price of eventual calcification: there comes a time when
implementations that expose too much become unable to make significant
internal structural changes.

Please consider this.  I feel that your mind has become closed to my
arguments.

     Mark



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

* Re: syntax-local-binding
  2012-01-23 21:03             ` syntax-local-binding Mark H Weaver
@ 2012-01-23 22:19               ` Andy Wingo
  2012-01-24  2:11                 ` syntax-local-binding Mark H Weaver
  2012-01-24 10:30                 ` syntax-local-binding Peter TB Brett
  0 siblings, 2 replies; 27+ messages in thread
From: Andy Wingo @ 2012-01-23 22:19 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

Hi Mark,

On Mon 23 Jan 2012 22:03, Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>> with identifier-syntax, one can no longer write a code walker with
>> syntax-rules pattern matching, as single identifiers may expand out
>> to complicated expressions, possibly even with side effects.
>
> This is false.  Macros are always expanded _before_ any of their
> arguments are expanded.  Therefore, a code walker sees the unexpanded
> forms, including any "simulated variables" bound by identifier-syntax.

I'm not sure we're talking about the same thing here; do see Alex
Shinn's NAK on R6RS:  http://www.r6rs.org/ratification/results.html#X70

While I disagree with his assessment of the identifier-syntax tradeoff,
I think he correctly identifies it as a tradeoff.

>>>> Why do you think that?  The procedures do carry metadata; I understood
>>>> that that was your strategy, to use the serialization of the
>>>> syntax-rules form in the procedure metadata.
>>>
>>> Well, this was in the context of a new strategy where psyntax would
>>> include a new core form called `call-with-current-local-expander' that
>>> calls its parameter (a procedure or macro) with a procedure that accepts
>>> an expression and returns an expanded form.  In this case, the most
>>> straightforward implementation would simply serialize the (r w mod)
>>> structures directly.
>>>
>>> Toward that end, I was thinking it would be nice to keep those
>>> structures serializable.  The only part that's not currently
>>> serializable are the transformer procedures for local macros.
>>> Thus the change in representation.
>>
>> I have been staring at this empty page here for a little while, writing
>> and re-writing, but I can't get over a feeling that I really don't want
>> this kind of work in psyntax itself.
>
> Your priorities are reversed from what they ought to be.
>
> What you _should_ be worried about is making commitments in our API that
> we must continue to support forever.  This is a _real_ problem, since it
> constrains our ability to modify our implementation in the future.

I know I'm going to sound like Mr. Collins in Pride and Prejudice here,
but I flatter myself that I know a thing or two about managing change --
I mean, replacing the lazy-memoizing evaluator with the compiler,
retrofitting psyntax into Guile, the whole subr mess, etc.  There is
always room to improve, of course, as in all human endeavor, but for now
it does seem that Guile is getting more powerful _and_ more limpid over
time.

But frankly though, regarding change, while we do need the freedom to
modify some things, some other practical freedoms just don't make the
cost/benefit cut, for me.  For example, considering replacing psyntax,
which seems to be in the back of your mind here.  This conservatism is
preventing Guile from adding features.  And we do need features --
local-eval and syntax-parse among them.

> Putting the `the-environment' in psyntax is, at worst, a stylistic
> issue.  Whether it belongs there is a matter of taste, but however
> strongly you may feel about that, it is a purely _internal_
> implementation issue.  The really important thing is that it commits us
> to _nothing_.  There's nothing stopping us from radically reimplementing
> it later.  In particular, there's nothing stopping us from moving it out
> of psyntax later.

Apart from the fact with `the-environment' in psyntax, it's in the
default environment, of course; though with autoloads one can get around
that...

With `the-environment' in a module, in 2.0.4 we could have three
functions added to psyntax:  syntax-local-binding,
syntax-locally-bound-identifiers, and syntax-module.  The first and the
third have precedent in Racket (whose hackers have been able to do
significantly awesome stuff).  The second is strange, but seems OK.  I'm
OK with them.

But what if they're the wrong interface?

Well, then we use the normal deprecation mechanism to get rid of them,
eventually (in the 2.2 series, for example).  We learned something.
Users get warned off the code.  Life goes on.

> Guile has been in existence for a couple of decades already, and I hope
> that it will be actively used for many decades to come.

Hear, hear.

> With that in mind, please consider the long view.  One of the reasons
> Scheme has lasted so long is because it tries exceptionally hard to
> hide internal implementation details.  Implementations that expose too
> much internal detail may derive a short-term benefit from doing so,
> but it comes at the price of eventual calcification: there comes a
> time when implementations that expose too much become unable to make
> significant internal structural changes.
>
> Please consider this.  I feel that your mind has become closed to my
> arguments.

I really do value your work, and your words, Mark.  Besides that
personal appreciation, I think you're doing good work for Guile.

We happen to disagree here on a matter of implementation.  OK.  It's a
feature we have worked on sufficiently that it should probably make it
into 2.0.4.  OK.  One of us will be unhappy about whatever goes in, it
seems.  I appreciate the calcification argument, but I simply think that
it does not apply in this case.

The thing that we shouldn't forget, though, is that regardles of the
particular technique, if local-eval goes in, we'll have won already --
local-eval in a modern Scheme.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-23 22:19               ` syntax-local-binding Andy Wingo
@ 2012-01-24  2:11                 ` Mark H Weaver
  2012-01-24 11:42                   ` syntax-local-binding Andy Wingo
  2012-01-24 10:30                 ` syntax-local-binding Peter TB Brett
  1 sibling, 1 reply; 27+ messages in thread
From: Mark H Weaver @ 2012-01-24  2:11 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> writes:

>> Your priorities are reversed from what they ought to be.
>>
>> What you _should_ be worried about is making commitments in our API that
>> we must continue to support forever.  This is a _real_ problem, since it
>> constrains our ability to modify our implementation in the future.
>
> I know I'm going to sound like Mr. Collins in Pride and Prejudice here,
> but I flatter myself that I know a thing or two about managing change --
> I mean, replacing the lazy-memoizing evaluator with the compiler,
> retrofitting psyntax into Guile, the whole subr mess, etc.

These are certainly impressive accomplishments, and I salute you for
this excellent work! :)

However, these accomplishments do not demonstrate that you understand
the importance of hiding implementation details so that future Guile
hackers can make similar transformations a decade or two from now.

For example, you seem unabashedly content to lock us into using psyntax
forever, despite the fact that it has known deficiencies having to do
with its phase story, as well as limitations in its handling of hygiene
in complex macros.  (c.f. "Improved hygiene", SRFI 72).  I don't mean to
suggest that we should replace psyntax anytime soon, but we might want
to replace it in a decade or two.  Therefore, it concerns me when I see
internal psyntax representations exported in our API.

> But frankly though, regarding change, while we do need the freedom to
> modify some things, some other practical freedoms just don't make the
> cost/benefit cut, for me.

I agree that sometimes practical necessity outweighs the need to hide
implementation details.  However, in this case, the only "benefit" is to
satisfy your desire to keep `the-environment' out of psyntax.

> This conservatism is preventing Guile from adding features.  And we do
> need features -- local-eval and syntax-parse among them.

For the record, I absolutely want Stefan to have what he needs to
implement `syntax-parse'.  My understanding is that all he needs is a
way to associate properties with syntactic keywords.  Toward that end, I
proposed that we should add something analogous to procedure properties
for macros.  This can be done without exposing internal details as you
have done.

> But what if they're the wrong interface?
>
> Well, then we use the normal deprecation mechanism to get rid of them,
> eventually (in the 2.2 series, for example).  We learned something.
> Users get warned off the code.  Life goes on.

Yes, this is always an option, but it is a _painful_ option for all
involved.  If we can already foresee the need to deprecate an interface,
wouldn't it be better not to add it in the first place?

* * * * *

Anyway, I can plainly see that your mind is set on this, and that all of
the above words were a waste of effort, so I'm going to try to drop it.

I just have one final request: please at least change the lexical
environments in your `local-eval' implementation to use the future-proof
`evaluator procedure' representation, as I have done in mine.

FWIW, criticisms aside, I _do_ very much appreciate that you heard my
plea for local-eval in 2.0.4, and that you have put so much time into
this.  Thanks for that, and for all the wonderful things you have done
for Guile and GNU.

      Mark



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

* Re: syntax-local-binding
  2012-01-23 22:19               ` syntax-local-binding Andy Wingo
  2012-01-24  2:11                 ` syntax-local-binding Mark H Weaver
@ 2012-01-24 10:30                 ` Peter TB Brett
  2012-01-24 10:38                   ` syntax-local-binding David Kastrup
  2012-01-24 11:26                   ` syntax-local-binding Andy Wingo
  1 sibling, 2 replies; 27+ messages in thread
From: Peter TB Brett @ 2012-01-24 10:30 UTC (permalink / raw)
  To: guile-devel

Andy Wingo <wingo@pobox.com> writes:

> On Mon 23 Jan 2012 22:03, Mark H Weaver <mhw@netris.org> writes:
>> Your priorities are reversed from what they ought to be.
>>
>> What you _should_ be worried about is making commitments in our API that
>> we must continue to support forever.  This is a _real_ problem, since it
>> constrains our ability to modify our implementation in the future.
>
> I know I'm going to sound like Mr. Collins in Pride and Prejudice here,
> but I flatter myself that I know a thing or two about managing change --
> I mean, replacing the lazy-memoizing evaluator with the compiler,
> retrofitting psyntax into Guile, the whole subr mess, etc.  There is
> always room to improve, of course, as in all human endeavor, but for now
> it does seem that Guile is getting more powerful _and_ more limpid over
> time.
>
> But frankly though, regarding change, while we do need the freedom to
> modify some things, some other practical freedoms just don't make the
> cost/benefit cut, for me.  For example, considering replacing psyntax,
> which seems to be in the back of your mind here.  This conservatism is
> preventing Guile from adding features.  And we do need features --
> local-eval and syntax-parse among them.

I'm sorry to say it, Andy, but I'm pretty certain that Mark's correct in
this case.  When you're making additions to a body of code that's
expected to be very widely used in a very diverse variety of
applications (such as, for example, the Linux kernel, or glibc), one
must be *incredibly careful* not to expose implementation details,
because users *will* depend on them and complain bitterly when they are
changed or removed.  I don't feel that your approach to this issue is
consistent with your wishes to massively increase Guile usage during
2012.

It seems pretty clear to me that the only (debatable) downside to using
Mark's implementation is that some definitions end up in the "wrong"
module, while your implementation has several potentially *major*
problems (including the necessity of providing universally unique
gensyms) which Mark has managed to avoid.  I am at a loss to understand
why you are so vehemently opposed to using Mark's approach (even if only
in the short term while you two find a mutually-agreeable solution), and
I urge you to reconsider.

This is just my £0.02, and as "mere user" of Guile my opinion is
probably of little value in this discussion.  And as Mark pointed out,
you've clearly made your decision on this; I'm not holding much hope of
changing your mind.

Thanks for all your continuing work on Guile.

Regards,

                             Peter

-- 
Peter Brett <peter@peter-b.co.uk>
Remote Sensing Research Group
Surrey Space Centre




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

* Re: syntax-local-binding
  2012-01-24 10:30                 ` syntax-local-binding Peter TB Brett
@ 2012-01-24 10:38                   ` David Kastrup
  2012-01-24 11:26                   ` syntax-local-binding Andy Wingo
  1 sibling, 0 replies; 27+ messages in thread
From: David Kastrup @ 2012-01-24 10:38 UTC (permalink / raw)
  To: guile-devel

Peter TB Brett <peter@peter-b.co.uk> writes:

> It seems pretty clear to me that the only (debatable) downside to
> using Mark's implementation is that some definitions end up in the
> "wrong" module, while your implementation has several potentially
> *major* problems (including the necessity of providing universally
> unique gensyms) which Mark has managed to avoid.

Let me just repeat that I consider universally unique gensyms a recipe
for trouble.  Having a compiler _depend_ on creating unreproducible
output is going to be in the "not really fun" category for a _lot_ of
things.  I don't have much of a clue about the other differences.  But
this one _really_ comes at a dear price in its implications.

-- 
David Kastrup




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

* Re: syntax-local-binding
  2012-01-24 10:30                 ` syntax-local-binding Peter TB Brett
  2012-01-24 10:38                   ` syntax-local-binding David Kastrup
@ 2012-01-24 11:26                   ` Andy Wingo
  2012-01-24 13:25                     ` syntax-local-binding Mark H Weaver
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-24 11:26 UTC (permalink / raw)
  To: Peter TB Brett; +Cc: guile-devel

On Tue 24 Jan 2012 11:30, Peter TB Brett <peter@peter-b.co.uk> writes:

> It seems pretty clear to me that the only (debatable) downside to using
> Mark's implementation is that some definitions end up in the "wrong"
> module, while your implementation has several potentially *major*
> problems (including the necessity of providing universally unique
> gensyms)

Let's be clear here: the universally-unique gensym issue is something
that Guile *already* has, in version 2.0.0, 2.0.1, etc.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-24  2:11                 ` syntax-local-binding Mark H Weaver
@ 2012-01-24 11:42                   ` Andy Wingo
  2012-01-24 17:29                     ` syntax-local-binding Noah Lavine
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-24 11:42 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

Hi Mark,

On Tue 24 Jan 2012 03:11, Mark H Weaver <mhw@netris.org> writes:

> you seem unabashedly content to lock us into using psyntax forever,

This statement is an exaggeration.  While I am content with psyntax now,
all change is possible, with time.  While it's important to think of the
future (and the past), one must not forget about the present :)

> It concerns me when I see internal psyntax representations exported in
> our API.

None of the interfaces that I proposed leak internal psyntax
representations.

syntax-local-binding provides binding information for an identifier.
Racket provides similar procedures, and does not use psyntax.  Therefore
this information does not tie us to the psyntax implementation.

syntax-locally-bound-identifiers can be implemented in any expander.  It
provides syntax objects.  Syntax objects are not a psyntax
implementation detail.

syntax-module is a simple accessor.  Racket provides the same accessor.
Therefore it does not leak psyntax implementation details.

> If we can already foresee the need to deprecate an interface, wouldn't
> it be better not to add it in the first place?

I don't see the need to deprecate them now, not more than any other
identifier that we export.

> I just have one final request: please at least change the lexical
> environments in your `local-eval' implementation to use the future-proof
> `evaluator procedure' representation, as I have done in mine.

For the reasons I mentioned in my mail yesterday at 12:52 UTC, I really
don't see the point, as we have more effective means of dealing with
future change than introducing an abstraction there.  But if it will
make you happy, sure.  I'm quite tired of this topic ;-)

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-24 11:26                   ` syntax-local-binding Andy Wingo
@ 2012-01-24 13:25                     ` Mark H Weaver
  2012-01-24 20:28                       ` mark uniqueness (Was: Re: syntax-local-binding) Andy Wingo
  2012-01-24 21:22                       ` syntax-local-binding Andy Wingo
  0 siblings, 2 replies; 27+ messages in thread
From: Mark H Weaver @ 2012-01-24 13:25 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Peter TB Brett, guile-devel

Andy Wingo <wingo@pobox.com> writes:

> On Tue 24 Jan 2012 11:30, Peter TB Brett <peter@peter-b.co.uk> writes:
>
>> It seems pretty clear to me that the only (debatable) downside to using
>> Mark's implementation is that some definitions end up in the "wrong"
>> module, while your implementation has several potentially *major*
>> problems (including the necessity of providing universally unique
>> gensyms)
>
> Let's be clear here: the universally-unique gensym issue is something
> that Guile *already* has, in version 2.0.0, 2.0.1, etc.

I don't see why we need universally-unique gensyms unless your approach
to `local-eval' is used.  I've already explained why they are not needed
for macros compiled in another session.

>> It concerns me when I see internal psyntax representations exported in
>> our API.
>
> None of the interfaces that I proposed leak internal psyntax
> representations.

`syntax-local-binding' leaks the internal representations used for
bindings.  I gave an example where this would constrain our ability to
change the binding representation for syntactic keywords, and your
response was to point out that my particular example could be done in a
different way without changing the representation.  Your response
demonstrated the weakness of my particular example, while underscoring
my main point: that this constrains our internal representation choices.

>> I just have one final request: please at least change the lexical
>> environments in your `local-eval' implementation to use the future-proof
>> `evaluator procedure' representation, as I have done in mine.
>
> For the reasons I mentioned in my mail yesterday at 12:52 UTC, I really
> don't see the point, as we have more effective means of dealing with
> future change than introducing an abstraction there.

Your suggested "more effective means" is to introduce a new type
<lexical-environment-2> and continue supporting <lexical-environment>.
No thanks.

> But if it will make you happy, sure.  I'm quite tired of this topic
> ;-)

Yes, it would make me happy, thank you.  And believe me, I'm tired of
this topic too.  I thought I was mostly finished working on `local-eval'
three weeks ago, when I produced my simple patch, which I _still_ think
is superior to yours in the most important respect, namely in the
commitments that it forces us to make.

    Regards,
      Mark



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

* Re: syntax-local-binding
  2012-01-24 11:42                   ` syntax-local-binding Andy Wingo
@ 2012-01-24 17:29                     ` Noah Lavine
  0 siblings, 0 replies; 27+ messages in thread
From: Noah Lavine @ 2012-01-24 17:29 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Mark H Weaver, guile-devel

Hello,

>> If we can already foresee the need to deprecate an interface, wouldn't
>> it be better not to add it in the first place?
>
> I don't see the need to deprecate them now, not more than any other
> identifier that we export.

I think this may be the key to this argument. There are two separate
questions being debated as one question. Here they are:

1. Do we forsee a need to deprecate the syntax-local-binding
functionality in the future, for instance to move away from psyntax?
2. Is this version of syntax-local-binding the best interface to this
functionality?

They are related questions, but they are distinct because someone
could believe that it is good to expose this functionality but that
the current syntax-local-bindings is not the best interface for us.

I could be wrong, but I think that Andy answers "maybe, but not for a
long time" to 1, and therefore thinks it's fine to include
syntax-local-binding. Mark answers "maybe, but definitely needs more
thought before we make a commitment" to 2, and therefore does not want
to include syntax-local-binding. These are not contradictory
positions. (Some of their other positions are contradictory, though
:-) ). However, it does make me think that we should discuss the
interface to syntax-local-binding more before releasing it (but don't
take this too seriously, because I didn't follow the earlier threads
much).

Noah



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

* mark uniqueness (Was: Re: syntax-local-binding)
  2012-01-24 13:25                     ` syntax-local-binding Mark H Weaver
@ 2012-01-24 20:28                       ` Andy Wingo
  2012-01-25  0:26                         ` mark uniqueness Mark H Weaver
  2012-01-24 21:22                       ` syntax-local-binding Andy Wingo
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-24 20:28 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: Peter TB Brett, guile-devel

On Tue 24 Jan 2012 14:25, Mark H Weaver <mhw@netris.org> writes:

> I don't see why we need universally-unique gensyms
> I've already explained why they are not needed
> for macros compiled in another session.

Ah, I forgot to reply to that.  I found it:

On Mon 16 Jan 2012 14:28, Mark H Weaver <mhw@netris.org> writes:

> The reason it has not been a problem with macros is that, within a
> top-level macro (which are the only ones used across Guile sessions),
> the only syntax-objects that can be meaningfully _introduced_ into the
> expansion are top-level/module bindings.  But these bindings have no
> associated labels or gensyms, because they're not in the wrap.
>
> See how this is a problem now where it wasn't before?
> Or am I missing something?

Either you are missing something, or I am, or both of us -- that much is
clear ;-)

Psyntax associates marks with every identifier.  Two identifiers are
equal if they are symbolically equal, and they have the same marks.  It
would break hygiene if two identifiers that didn't come from the same
place accidentally had the same marks.

A fresh mark is placed on syntax returned from a macro expander, if the
syntax was not present in the input.  An easy way to do this would be
simply:

  (define-syntax-rule (fresh-identifier)
    #'x)
  (define my-id (fresh-identifier))

All you need to do is to introduce that binding into a macro, and you
might alias some other binding, because you have serialized the symbol
and marks into a compiled file.

This is admittedly far-fetched.  But it can happen, and at the
top-level.  For example, our old friend:

  (define-syntax-rule (define-const x val)
    (begin
      (define t val)
      (define-syntax x (identifier-syntax t))))

Here, `t' will have a fresh mark.

Now, if in one compilation unit, I do:

  (define-const x 10)

And in another, I do:

  (let ((t 20))
    x) => ?

You would expect the result to be 20.  But I think it could be 20, if
the marks on the two "t"s happened to collide.

Am I missing something? :-)

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-24 13:25                     ` syntax-local-binding Mark H Weaver
  2012-01-24 20:28                       ` mark uniqueness (Was: Re: syntax-local-binding) Andy Wingo
@ 2012-01-24 21:22                       ` Andy Wingo
  2012-01-25  2:30                         ` syntax-local-binding Mark H Weaver
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Wingo @ 2012-01-24 21:22 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: Peter TB Brett, guile-devel

Hello Mark :)

Thanks again for your deep thoughts.  This conversation is a bit
stressful for the both of us, but we wouldn't be having it if we didn't
both care about Guile.

In the spirit of diffusing tension here, feel free to imagine all of my
words as coming from Mr. Collins for the duration of this thread ;-)

On Tue 24 Jan 2012 14:25, Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>> None of the interfaces that I proposed leak internal psyntax
>> representations.
>
> `syntax-local-binding' leaks the internal representations used for
> bindings.

You mean, whether something is a lexical, or a macro, or a global, or
whatever; OK.  I think that "leak" is the wrong word here: leaks are
inadvertent, whereas providing this information is what this function
was designed to do; and furthermore it's not a detail of psyntax (cf
Racket which does not use psyntax).

Let me offer another example of its utility: writing a macro stepper.
Again, for an example I'll have to link to the PLT folks' great work:

  http://docs.racket-lang.org/macro-debugger/index.html

With syntax-local-binding, syntax-locally-bound-identifiers, and a
couple hooks that get fired when a macro is expanded and reconstructed,
you could implement a macro stepper for Guile.

And, once we provide those hooks, you can implement this in a module.

Pretty sweet, if you ask me!

Perhaps, though, at this point we're just going to have to agree to
disagree; surely we have plumbed the depths sufficiently.  It's not
satisfying, but I think we both made a great effort to communicate and
convince -- and in some cases, to work on each other's code.  We really
need to move on here.  I will re-post my patches taking into account
your comments regarding the form of the environments.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: mark uniqueness
  2012-01-24 20:28                       ` mark uniqueness (Was: Re: syntax-local-binding) Andy Wingo
@ 2012-01-25  0:26                         ` Mark H Weaver
  2012-01-25  9:02                           ` Andy Wingo
  0 siblings, 1 reply; 27+ messages in thread
From: Mark H Weaver @ 2012-01-25  0:26 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Peter TB Brett, guile-devel

Andy Wingo <wingo@pobox.com> writes:

>   (define-syntax-rule (define-const x val)
>     (begin
>       (define t val)
>       (define-syntax x (identifier-syntax t))))
>
> Here, `t' will have a fresh mark.
>
> Now, if in one compilation unit, I do:
>
>   (define-const x 10)
>
> And in another, I do:
>
>   (let ((t 20))
>     x) => ?
>
> You would expect the result to be 20.  But I think it could be 20, if
> the marks on the two "t"s happened to collide.

Ah yes, indeed you are right.  Thanks for this explanation.  I guess we
need universally-unique gensyms for marks at least, regardless of which
`local-eval' implementation we use.

    Thanks,
      Mark



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

* Re: syntax-local-binding
  2012-01-24 21:22                       ` syntax-local-binding Andy Wingo
@ 2012-01-25  2:30                         ` Mark H Weaver
  2012-01-25  7:49                           ` syntax-local-binding Stefan Israelsson Tampe
                                             ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Mark H Weaver @ 2012-01-25  2:30 UTC (permalink / raw)
  To: Andy Wingo; +Cc: Peter TB Brett, guile-devel

Andy Wingo <wingo@pobox.com> writes:
> In the spirit of diffusing tension here, feel free to imagine all of my
> words as coming from Mr. Collins for the duration of this thread ;-)

Hehe :)

> On Tue 24 Jan 2012 14:25, Mark H Weaver <mhw@netris.org> writes:
>
>> Andy Wingo <wingo@pobox.com> writes:
>>
>>> None of the interfaces that I proposed leak internal psyntax
>>> representations.
>>
>> `syntax-local-binding' leaks the internal representations used for
>> bindings.
>
> You mean, whether something is a lexical, or a macro, or a global, or
> whatever; OK.

That's actually not what I meant, although I'm not convinced that we
fully understand the implications of exposing even that much.  One thing
that is already clear is that `identifier-syntax' and `local-eval' were
previously capable of emulating variables perfectly before, whereas in
the presence of `syntax-local-binding' they no longer are.

This is a perfect example of how added flexibility in one aspect can
lead to _reduced_ flexibility in other aspects.  I think we need more
time to consider the implications of this.

However, the more serious problem, and the one I was actually talking
about, is the _second_ value returned by `syntax-local-binding', which
exposes the representations of bindings stored in the cdrs of the
psyntax `r' alist.

> Let me offer another example of its utility: writing a macro stepper.

It's not the least bit surprising that exposing internal implementation
details enables the creation of all kinds of nifty things as external
programs that would ordinarily need to be internal.  This is perfectly
obvious.

However, as you wisely said to me when I posted my first `local-eval'
evaluator-only implementation, this stuff has a cost, and it has to
justify itself.  I assumed you meant the maintenance cost of supporting
this advanced functionality indefinitely, and the constraints that it
places on the freedom of future implementors.  Was I right?

In retrospect, based on your recent behavior, I wonder if that's what
you meant or if you were talking about something completely different,
because you seem to have completely abandoned your original restraint,
and have now gone much farther than I would ever dare to go.  Indeed, as
you can see, I am very unhappy about how far you have gone with this.

> Perhaps, though, at this point we're just going to have to agree to
> disagree;

This is a euphemism for "sorry, but we're doing it my way".  Multiple
people here have expressed grave concerns about your approach, and not a
single person has publicly expressed their support for adding all of
these new interfaces you've designed.  Even Ludovic has remained silent.
And yet you apparently intend to rush all of this stuff into 2.0.4.
After all, nothing could be worse than having `the-environment' in
psyntax, even for single release.

Is this your idea of a consensus process, which you so often advocate?

     Mark



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

* Re: syntax-local-binding
  2012-01-25  2:30                         ` syntax-local-binding Mark H Weaver
@ 2012-01-25  7:49                           ` Stefan Israelsson Tampe
  2012-01-25 11:18                           ` syntax-local-binding Andy Wingo
  2012-01-25 13:18                           ` syntax-local-binding Ludovic Courtès
  2 siblings, 0 replies; 27+ messages in thread
From: Stefan Israelsson Tampe @ 2012-01-25  7:49 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: Andy Wingo, Peter TB Brett, guile-devel

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

Hi,

1. module level macro bindings are reachable already with the api. so
beeing able to reach locally
defined one as well can be seen as a way to make that feature complete.

2. (define-syntax name val) (let-syntax ((name val)) ...) etc should be
aboute
creating bindings and hence the binding value should be a feature of scheme
and not
something that depends on the macro expander.

3. weather a syntax object represent a lexical a macro etc. is also
something that has to do
about scheme and not the actual syntax expander.

In this light my view is that this information does not expose any details
about the internals. Without this
function however users may be tempted to manually look into a syntax object
and the resulting code will
brake if we change the internal representation of syntax information. In
short by publishing a rich set of accesssors users will be safe and less
things will brake if we do the change.

However It look to me that changing the syntax representation in racket
would be a monumental task because of the extreemly rich set of features
their macro framework has so it is very good to be
careful in entering features. But note, if these features are defined in a
small set of accessors that logicaly is about getting information that are
defined as scheme and not as something that is internal I would say that
the burden is to a large degree an illusion.

For example the use of syntax-local-binding in syntax-parse is to
(define-syntax class data) or (let-syntax ((class data)) ...) with class
beeing a syntax object pointing to information about a syntax class like a
string syntax class that enables matching of strings only. Now It would be
good and I really like to get help here, if there are any good suggestions
about what I can do to avoid using syntax-local-binding (I managed to
rmeove this dependency for other locis in the code). The point here is that
wingo need to find arguments of code using syntax-local-binding and argue
that it is the natural solution. And Mark need to suggest alternatives and
depending on elegance, performance, safety etc we could agree if a feature
is exoterix and perhaps not needed. For this I can help in suggesting
elements from the syntax-parse code base.

This is my 2c at least
/Stefan


On Wed, Jan 25, 2012 at 3:30 AM, Mark H Weaver <mhw@netris.org> wrote:

> Andy Wingo <wingo@pobox.com> writes:
> > In the spirit of diffusing tension here, feel free to imagine all of my
> > words as coming from Mr. Collins for the duration of this thread ;-)
>
> Hehe :)
>
> > On Tue 24 Jan 2012 14:25, Mark H Weaver <mhw@netris.org> writes:
> >
> >> Andy Wingo <wingo@pobox.com> writes:
> >>
> >>> None of the interfaces that I proposed leak internal psyntax
> >>> representations.
> >>
> >> `syntax-local-binding' leaks the internal representations used for
> >> bindings.
> >
> > You mean, whether something is a lexical, or a macro, or a global, or
> > whatever; OK.
>
> That's actually not what I meant, although I'm not convinced that we
> fully understand the implications of exposing even that much.  One thing
> that is already clear is that `identifier-syntax' and `local-eval' were
> previously capable of emulating variables perfectly before, whereas in
> the presence of `syntax-local-binding' they no longer are.
>
> This is a perfect example of how added flexibility in one aspect can
> lead to _reduced_ flexibility in other aspects.  I think we need more
> time to consider the implications of this.
>
> However, the more serious problem, and the one I was actually talking
> about, is the _second_ value returned by `syntax-local-binding', which
> exposes the representations of bindings stored in the cdrs of the
> psyntax `r' alist.
>
> > Let me offer another example of its utility: writing a macro stepper.
>
> It's not the least bit surprising that exposing internal implementation
> details enables the creation of all kinds of nifty things as external
> programs that would ordinarily need to be internal.  This is perfectly
> obvious.
>
> However, as you wisely said to me when I posted my first `local-eval'
> evaluator-only implementation, this stuff has a cost, and it has to
> justify itself.  I assumed you meant the maintenance cost of supporting
> this advanced functionality indefinitely, and the constraints that it
> places on the freedom of future implementors.  Was I right?
>
> In retrospect, based on your recent behavior, I wonder if that's what
> you meant or if you were talking about something completely different,
> because you seem to have completely abandoned your original restraint,
> and have now gone much farther than I would ever dare to go.  Indeed, as
> you can see, I am very unhappy about how far you have gone with this.
>
> > Perhaps, though, at this point we're just going to have to agree to
> > disagree;
>
> This is a euphemism for "sorry, but we're doing it my way".  Multiple
> people here have expressed grave concerns about your approach, and not a
> single person has publicly expressed their support for adding all of
> these new interfaces you've designed.  Even Ludovic has remained silent.
> And yet you apparently intend to rush all of this stuff into 2.0.4.
> After all, nothing could be worse than having `the-environment' in
> psyntax, even for single release.
>
> Is this your idea of a consensus process, which you so often advocate?
>
>     Mark
>
>

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

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

* Re: mark uniqueness
  2012-01-25  0:26                         ` mark uniqueness Mark H Weaver
@ 2012-01-25  9:02                           ` Andy Wingo
  0 siblings, 0 replies; 27+ messages in thread
From: Andy Wingo @ 2012-01-25  9:02 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: Peter TB Brett, guile-devel

On Wed 25 Jan 2012 01:26, Mark H Weaver <mhw@netris.org> writes:

> Andy Wingo <wingo@pobox.com> writes:
>
>>   (define-syntax-rule (define-const x val)
>>     (begin
>>       (define t val)
>>       (define-syntax x (identifier-syntax t))))
>>
>> Here, `t' will have a fresh mark.
>>
>> Now, if in one compilation unit, I do:
>>
>>   (define-const x 10)
>>
>> And in another, I do:
>>
>>   (let ((t 20))
>>     x) => ?
>>
>> You would expect the result to be 20.  But I think it could be 20, if
>> the marks on the two "t"s happened to collide.

FWIW I think this example wasn't quite right; you'd need to have the
case where both "t"s that are visible have marks.  Like in compilation
unit B:

  (let ()
    (define-const y 20)
    x) => ?

Cheers,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-25  2:30                         ` syntax-local-binding Mark H Weaver
  2012-01-25  7:49                           ` syntax-local-binding Stefan Israelsson Tampe
@ 2012-01-25 11:18                           ` Andy Wingo
  2012-01-25 13:18                           ` syntax-local-binding Ludovic Courtès
  2 siblings, 0 replies; 27+ messages in thread
From: Andy Wingo @ 2012-01-25 11:18 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: Peter TB Brett, guile-devel

Hello Mark,

On Wed 25 Jan 2012 03:30, Mark H Weaver <mhw@netris.org> writes:

>> Perhaps, though, at this point we're just going to have to agree to
>> disagree;
>
> This is a euphemism for "sorry, but we're doing it my way".

Just a few days ago, you said:

On Sun 22 Jan 2012 13:23, Mark H Weaver <mhw@netris.org> writes:

> If Andy finishes his version of `local-eval', that's all well and good,
> and I'm happy to use his version.

You got a fairly explicit NAK from me on the-environment in psyntax:
beginning with suggestions for a different approach, continuing where I
implemented those suggestions, and finally just a few days ago.  (I.e.,
I do not consent to the-environment in psyntax, given the existence of
other possibilities.)

But, you are interested in local-eval in 2.0.4, and you consented to
this approach.

Please.  Let us focus on solutions.

Regards,

Andy
-- 
http://wingolog.org/



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

* Re: syntax-local-binding
  2012-01-25  2:30                         ` syntax-local-binding Mark H Weaver
  2012-01-25  7:49                           ` syntax-local-binding Stefan Israelsson Tampe
  2012-01-25 11:18                           ` syntax-local-binding Andy Wingo
@ 2012-01-25 13:18                           ` Ludovic Courtès
  2012-01-25 18:08                             ` syntax-local-binding Mark H Weaver
  2012-01-26 11:21                             ` syntax-local-binding Andy Wingo
  2 siblings, 2 replies; 27+ messages in thread
From: Ludovic Courtès @ 2012-01-25 13:18 UTC (permalink / raw)
  To: guile-devel

Hello Happy Guilers!  :-)

Sorry for remaining silent in this heated thread (I spent my spare time
on other practical issues for 2.0.4, and felt I lacked the competence.)

My overall feeling is that providing a 1.8-compatible ‘local-eval’ in
2.0 is great, but that it’s essentially one bug to be fixed among many
others.

Thus, I appreciate all the work Andy and you have put into it, and I’m
glad it will be helpful to Guile users such as Lilypond.  However, I
think, that we should keep in mind that Guile is not just about
‘local-eval’, and that there are other great things to work on together.

As for the technical aspects:

Mark H Weaver <mhw@netris.org> skribis:

> Andy Wingo <wingo@pobox.com> writes:
>> On Tue 24 Jan 2012 14:25, Mark H Weaver <mhw@netris.org> writes:
>>
>>> Andy Wingo <wingo@pobox.com> writes:
>>>
>>>> None of the interfaces that I proposed leak internal psyntax
>>>> representations.
>>>
>>> `syntax-local-binding' leaks the internal representations used for
>>> bindings.
>>
>> You mean, whether something is a lexical, or a macro, or a global, or
>> whatever; OK.
>
> That's actually not what I meant, although I'm not convinced that we
> fully understand the implications of exposing even that much.  One thing
> that is already clear is that `identifier-syntax' and `local-eval' were
> previously capable of emulating variables perfectly before, whereas in
> the presence of `syntax-local-binding' they no longer are.
>
> This is a perfect example of how added flexibility in one aspect can
> lead to _reduced_ flexibility in other aspects.  I think we need more
> time to consider the implications of this.

I agree.  Yet, it’s the kind of API that is useful internally for
different purposes beyond ‘local-eval’, as this discussion showed,
right?

So, IIUC, the tension is:

  1. Such as API is desirable for Guile-internal consumption.

  2. Exposing it to users may restrict our ability to change the
     implementation in the future, just like ‘the-environment’ did.

I haven’t fully thought about it, but one possible trade-off would be to
mark ‘syntax-local-binding’ & co. as internal, somehow arrange to make
them visible only from some (system ...) module, and document them in
the “Implementation” chapter.

WDYT?

Thanks,
Ludo’.




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

* Re: syntax-local-binding
  2012-01-25 13:18                           ` syntax-local-binding Ludovic Courtès
@ 2012-01-25 18:08                             ` Mark H Weaver
  2012-01-26 11:21                             ` syntax-local-binding Andy Wingo
  1 sibling, 0 replies; 27+ messages in thread
From: Mark H Weaver @ 2012-01-25 18:08 UTC (permalink / raw)
  To: guile-devel

I have nothing new to say here, so I'll spare you all my increasingly
frustrated repetitions.  I need to walk away for a while.  Do what you
feel is best.  Good luck.

      Mark



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

* Re: syntax-local-binding
  2012-01-25 13:18                           ` syntax-local-binding Ludovic Courtès
  2012-01-25 18:08                             ` syntax-local-binding Mark H Weaver
@ 2012-01-26 11:21                             ` Andy Wingo
  1 sibling, 0 replies; 27+ messages in thread
From: Andy Wingo @ 2012-01-26 11:21 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Thanks for the feedback, Ludovic.

On Wed 25 Jan 2012 14:18, ludo@gnu.org (Ludovic Courtès) writes:

>   1. Such as API is desirable for Guile-internal consumption.
>
>   2. Exposing it to users may restrict our ability to change the
>      implementation in the future, just like ‘the-environment’ did.
>
> I haven’t fully thought about it, but one possible trade-off would be to
> mark ‘syntax-local-binding’ & co. as internal, somehow arrange to make
> them visible only from some (system ...) module, and document them in
> the “Implementation” chapter.

I have moved the new accessors to (system syntax), and marked them as
experimental in the documentation.

Cheers,

Andy
-- 
http://wingolog.org/



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

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

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-15 17:00 syntax-local-binding Andy Wingo
2012-01-15 17:22 ` syntax-local-binding Andy Wingo
2012-01-19 11:41   ` syntax-local-binding Andy Wingo
2012-01-20 20:26     ` syntax-local-binding Mark H Weaver
2012-01-20 21:23       ` syntax-local-binding Andy Wingo
2012-01-20 22:03         ` syntax-local-binding Mark H Weaver
2012-01-22  0:03           ` syntax-local-binding Ludovic Courtès
2012-01-23 16:05           ` syntax-local-binding Andy Wingo
2012-01-23 21:03             ` syntax-local-binding Mark H Weaver
2012-01-23 22:19               ` syntax-local-binding Andy Wingo
2012-01-24  2:11                 ` syntax-local-binding Mark H Weaver
2012-01-24 11:42                   ` syntax-local-binding Andy Wingo
2012-01-24 17:29                     ` syntax-local-binding Noah Lavine
2012-01-24 10:30                 ` syntax-local-binding Peter TB Brett
2012-01-24 10:38                   ` syntax-local-binding David Kastrup
2012-01-24 11:26                   ` syntax-local-binding Andy Wingo
2012-01-24 13:25                     ` syntax-local-binding Mark H Weaver
2012-01-24 20:28                       ` mark uniqueness (Was: Re: syntax-local-binding) Andy Wingo
2012-01-25  0:26                         ` mark uniqueness Mark H Weaver
2012-01-25  9:02                           ` Andy Wingo
2012-01-24 21:22                       ` syntax-local-binding Andy Wingo
2012-01-25  2:30                         ` syntax-local-binding Mark H Weaver
2012-01-25  7:49                           ` syntax-local-binding Stefan Israelsson Tampe
2012-01-25 11:18                           ` syntax-local-binding Andy Wingo
2012-01-25 13:18                           ` syntax-local-binding Ludovic Courtès
2012-01-25 18:08                             ` syntax-local-binding Mark H Weaver
2012-01-26 11:21                             ` syntax-local-binding Andy Wingo

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