unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [patch] variable datums with syncase transformer
@ 2007-12-14  8:06 Stephen Compall
  2008-03-05 14:59 ` Ludovic Courtès
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Stephen Compall @ 2007-12-14  8:06 UTC (permalink / raw)
  To: guile-devel


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

Issue most easily explained with a simple reproduction:

guile> (use-syntax (ice-9 syncase))
guile> (@ (guile) car)
ERROR: invalid syntax #<variable b7c50a40 value: #<primitive-procedure car>>

The reasoning of the fix is best described in the long comment in the
patch below.  If you would rather that I modify psyntax.ss to use a new
procedure name rather than `self-evaluating?' please let me know.  Patch
does not include log entries, listed immediately below instead:

ice-9/ChangeLog:

2007-12-14  Stephen Compall  <s11@member.fsf.org>

	* syncase.scm: Support datums where (variable? DATUM) => #t
	when syncase transformer is installed.

test-suite/ChangeLog:

2007-12-14  Stephen Compall  <s11@member.fsf.org>

	* tests/syncase.test: Test that @-forms can be expanded by
	the syncase transformer.


Index: ice-9/syncase.scm
===================================================================
RCS file: /sources/guile/guile/guile-core/ice-9/syncase.scm,v
retrieving revision 1.35
diff -u -d -u -r1.35 syncase.scm
--- ice-9/syncase.scm	16 Apr 2006 23:43:48 -0000	1.35
+++ ice-9/syncase.scm	14 Dec 2007 07:55:49 -0000
@@ -194,6 +194,18 @@
               "syncase's gensym expected 0 or 1 arguments, got "
               (length rest)))))))))
 
+;; The question syncase is asking when it asks `self-evaluating?' is
+;; not really whether a given datum is self-evaluating, but whether it
+;; should pass the datum through as-is to the evaluator.  With that in
+;; mind, we wrap core `self-evaluating?' here so that syncase will
+;; pass-through variables, meaning (variable? datum) => #t, to the
+;; evaluator.  Without this, the system transformer will see a
+;; variable datum as invalid syntax, which it is not to the core
+;; transformer.
+(define (self-evaluating? datum)
+  (or ((@ (guile) self-evaluating?) datum)
+      (variable? datum)))
+
 ;;; Load the preprocessed code
 
 (let ((old-debug #f)
Index: test-suite/tests/syncase.test
===================================================================
RCS file: /sources/guile/guile/guile-core/test-suite/tests/syncase.test,v
retrieving revision 1.5
diff -u -d -u -r1.5 syncase.test
--- test-suite/tests/syncase.test	16 Apr 2006 23:27:14 -0000	1.5
+++ test-suite/tests/syncase.test	14 Dec 2007 07:55:49 -0000
@@ -34,3 +34,15 @@
 
 (pass-if "basic syncase macro"
   (= (plus 1 2 3) (+ 1 2 3)))
+
+(pass-if "variable?s recognized as datums"
+  (false-if-exception
+   (begin (eq? car (eval '(@ (guile) car) (current-module)))
+	  #t)))
+
+(define-syntax export-safe-plus
+  (syntax-rules ()
+    ((_ x ...) ((@ (guile) +) x ...))))
+
+(pass-if "variable?s passed through to evaluator"
+  (= (export-safe-plus 1 2 3) (+ 1 2 3)))


-- 
Our last-ditch plan is to change the forums into a podcast, then send
RSS feeds into the blogosphere so our users can further debate the
legality of mashups amongst this month's 20 'sexiest' gadgets.
        --Richard "Lowtax" Kyanka

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel

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

* Re: [patch] variable datums with syncase transformer
  2007-12-14  8:06 [patch] variable datums with syncase transformer Stephen Compall
@ 2008-03-05 14:59 ` Ludovic Courtès
  2008-03-05 15:36   ` Stephen Compall
  2008-03-05 16:34 ` Ludovic Courtès
  2008-03-06 23:28 ` Neil Jerram
  2 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2008-03-05 14:59 UTC (permalink / raw)
  To: guile-devel

Hi,

I just rediscovered this message, sorry for the long delay.

Stephen Compall <s11@member.fsf.org> writes:

> Issue most easily explained with a simple reproduction:
>
> guile> (use-syntax (ice-9 syncase))
> guile> (@ (guile) car)
> ERROR: invalid syntax #<variable b7c50a40 value: #<primitive-procedure car>>

OTOH, you can (should?) use `use-modules':

  guile> (use-modules (ice-9 syncase))
  guile> (define-syntax foo (syntax-rules () ((_ x ...) (x ...))))
  guile> foo
  #<macro! sc-macro>
  guile> (foo + 2 3)
  5
  guile> (@ (guile) car)
  #<primitive-procedure car>

I don't even understand what the difference is between using
`use-modules' and `use-syntax' for `(ice-9 syncase)'.  There's this
`expansion-eval-closure' fluid that's being used, but it doesn't seem to
change the module where top-level bindings are resolved, as one might
think:

  guile> (define-module (x) :use-syntax (ice-9 syncase))
  #<directory (x) b7a7d110>
  guile> (define (+ . args) 'plus)
  guile> (define-syntax foo (syntax-rules () ((_ x ...) (+ x ...))))
  guile> (export-syntax foo)
  guile> (foo 1 2 3)
  plus
  guile> (set-current-module (resolve-module '(guile-user)))
  #<directory (x) b7a7d110>
  guile> (use-modules (x))
  guile> (foo 1 2 3)
  6   ;; <--- `+' is resolved in `(guile-user)', not in `(x)'

This per-module syntax transformer, `use-syntax' and friends all look
pretty pointless to me.

Thanks,
Ludovic.





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

* Re: [patch] variable datums with syncase transformer
  2008-03-05 14:59 ` Ludovic Courtès
@ 2008-03-05 15:36   ` Stephen Compall
  0 siblings, 0 replies; 8+ messages in thread
From: Stephen Compall @ 2008-03-05 15:36 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:
> OTOH, you can (should?) use `use-modules':
> <snip>
> 
> I don't even understand what the difference is between using
> `use-modules' and `use-syntax' for `(ice-9 syncase)'.

guile> (use-modules (ice-9 syncase))
guile> (define-syntax x-of-y
         (lambda (stx)
           (syntax-case stx ()
             (_ (syntax (hashq-ref y 'x))))))
guile> x-of-y
#<macro! sc-macro>

;;restart
guile> ;;same as above, using use-syntax instead
guile> x-of-y

Backtrace:
In unknown file:
   ?: 0* [hashq-ref ...

<unnamed port>: While evaluating arguments to hashq-ref in expression (hashq-ref y (quote x)):
<unnamed port>: Unbound variable: y

-- 
But you know how reluctant paranormal phenomena are to reveal
themselves when skeptics are present. --Robert Sheaffer, SkI 9/2003




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

* Re: [patch] variable datums with syncase transformer
  2007-12-14  8:06 [patch] variable datums with syncase transformer Stephen Compall
  2008-03-05 14:59 ` Ludovic Courtès
@ 2008-03-05 16:34 ` Ludovic Courtès
  2008-03-05 20:55   ` Neil Jerram
  2008-03-06 23:28 ` Neil Jerram
  2 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2008-03-05 16:34 UTC (permalink / raw)
  To: guile-devel


Stephen Compall <s11@member.fsf.org> writes:

> ludo@gnu.org (Ludovic Courtès) writes:
>> OTOH, you can (should?) use `use-modules':
>> <snip>
>> 
>> I don't even understand what the difference is between using
>> `use-modules' and `use-syntax' for `(ice-9 syncase)'.
>
> guile> (use-modules (ice-9 syncase))
> guile> (define-syntax x-of-y
>          (lambda (stx)
>            (syntax-case stx ()
>              (_ (syntax (hashq-ref y 'x))))))
> guile> x-of-y
> #<macro! sc-macro>
>
> ;;restart
> guile> ;;same as above, using use-syntax instead
> guile> x-of-y
>
> Backtrace:
> In unknown file:
>    ?: 0* [hashq-ref ...

Oh, forgive my ignorance, I didn't know `syntax-case' allowed non-list
patterns.  It makes me like syntax transformers a bit more.  ;-)

Getting back to your initial problem...

> guile> (use-syntax (ice-9 syncase))
> guile> (@ (guile) car)
> ERROR: invalid syntax #<variable b7c50a40 value: #<primitive-procedure car>>

Note that `@' and `@@' rely on an interesting property of the evaluator:
you type `(@ (guile) car)', `@' returns a *variable*, but what you get
is a *procedure*, because in the meantime, the evaluator automagically
performed a `variable-ref'.  This is not very elegant in my opinion.

With that in mind, I propose instead the following patch, which also
fixes your problem AFAICS:

--- /home/ludo/src/guile/1.8/guile-core/ice-9/boot-9.scm.~1.356.2.10.~	2007-09-01 19:11:00.000000000 +0200
+++ /home/ludo/src/guile/1.8/guile-core/ice-9/boot-9.scm	2008-03-05 17:25:15.000000000 +0100
@@ -2988,7 +2988,7 @@
   (let ((var (module-variable (resolve-interface mod-name) var-name)))
     (if (not var)
 	(error "no such public variable" (list '@ mod-name var-name)))
-    var))
+    (variable-ref var)))
 
 ;; The '@@' macro is like '@' but it can also access bindings that
 ;; have not been explicitely exported.
@@ -2997,7 +2997,7 @@
   (let ((var (module-variable (resolve-module mod-name) var-name)))
     (if (not var)
 	(error "no such variable" (list '@@ mod-name var-name)))
-    var))
+    (variable-ref var)))
 
Would it be OK for you?

Thanks,
Ludovic.





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

* Re: [patch] variable datums with syncase transformer
  2008-03-05 16:34 ` Ludovic Courtès
@ 2008-03-05 20:55   ` Neil Jerram
  2008-03-05 22:16     ` Stephen Compall
  2008-03-05 23:21     ` Ludovic Courtès
  0 siblings, 2 replies; 8+ messages in thread
From: Neil Jerram @ 2008-03-05 20:55 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Note that `@' and `@@' rely on an interesting property of the evaluator:
> you type `(@ (guile) car)', `@' returns a *variable*, but what you get
> is a *procedure*, because in the meantime, the evaluator automagically
> performed a `variable-ref'.  This is not very elegant in my opinion.

However, I think it means that if the variable is then changed, the
code that included the (@ ...) expression will get the new value next
time it is executed.

This means that `(@ module identifier)' acts like a plain old
`identifier', in the sense that it gives you a location - whose value
may change over time - rather than the fixed value of the identifier
at the time the code was first executed.

I think that's a feature, and it's probable that someone somewhere is
relying on it.

> With that in mind, I propose instead the following patch, which also
> fixes your problem AFAICS:
>
> --- /home/ludo/src/guile/1.8/guile-core/ice-9/boot-9.scm.~1.356.2.10.~	2007-09-01 19:11:00.000000000 +0200
> +++ /home/ludo/src/guile/1.8/guile-core/ice-9/boot-9.scm	2008-03-05 17:25:15.000000000 +0100
> @@ -2988,7 +2988,7 @@
>    (let ((var (module-variable (resolve-interface mod-name) var-name)))
>      (if (not var)
>  	(error "no such public variable" (list '@ mod-name var-name)))
> -    var))
> +    (variable-ref var)))
>  
>  ;; The '@@' macro is like '@' but it can also access bindings that
>  ;; have not been explicitely exported.
> @@ -2997,7 +2997,7 @@
>    (let ((var (module-variable (resolve-module mod-name) var-name)))
>      (if (not var)
>  	(error "no such variable" (list '@@ mod-name var-name)))
> -    var))
> +    (variable-ref var)))

If I've understood it correctly, I think this patch would change
existing behaviour, by returning a fixed value rather than a location.

Could we not look at fixing (ice-9 syncase) instead, so that it
understands variables?

Regards,
        Neil





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

* Re: [patch] variable datums with syncase transformer
  2008-03-05 20:55   ` Neil Jerram
@ 2008-03-05 22:16     ` Stephen Compall
  2008-03-05 23:21     ` Ludovic Courtès
  1 sibling, 0 replies; 8+ messages in thread
From: Stephen Compall @ 2008-03-05 22:16 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel

Neil Jerram <neil@ossau.uklinux.net> writes:
> Could we not look at fixing (ice-9 syncase) instead, so that it
> understands variables?

That is what my patch does.  It does not work for set!, but doesn't
break anything that wasn't broken.

-- 
But you know how reluctant paranormal phenomena are to reveal
themselves when skeptics are present. --Robert Sheaffer, SkI 9/2003




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

* Re: [patch] variable datums with syncase transformer
  2008-03-05 20:55   ` Neil Jerram
  2008-03-05 22:16     ` Stephen Compall
@ 2008-03-05 23:21     ` Ludovic Courtès
  1 sibling, 0 replies; 8+ messages in thread
From: Ludovic Courtès @ 2008-03-05 23:21 UTC (permalink / raw)
  To: guile-devel

szgyg <szgyg@freemail.hu> writes:

> (set! (@ (guile) car) cdr)

Neil Jerram <neil@ossau.uklinux.net> writes:

> If I've understood it correctly, I think this patch would change
> existing behaviour, by returning a fixed value rather than a location.

Um, you're both right!

> Could we not look at fixing (ice-9 syncase) instead, so that it
> understands variables?

Yes.  I finally grasp the rationale behind Stephen's patch, and I think
I'm convinced that we should apply it.  But since I've been so misguided
in this discussion, someone else should confirm that it's a good idea.
:-)

Thanks,
Ludovic.





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

* Re: [patch] variable datums with syncase transformer
  2007-12-14  8:06 [patch] variable datums with syncase transformer Stephen Compall
  2008-03-05 14:59 ` Ludovic Courtès
  2008-03-05 16:34 ` Ludovic Courtès
@ 2008-03-06 23:28 ` Neil Jerram
  2 siblings, 0 replies; 8+ messages in thread
From: Neil Jerram @ 2008-03-06 23:28 UTC (permalink / raw)
  To: Stephen Compall; +Cc: Ludovic Courtès, guile-devel

Hi Stephen,

Following Ludovic's request for me to review this...

Stephen Compall <s11@member.fsf.org> writes:

> +;; The question syncase is asking when it asks `self-evaluating?' is
> +;; not really whether a given datum is self-evaluating, but whether it
> +;; should pass the datum through as-is to the evaluator.  With that in
> +;; mind, we wrap core `self-evaluating?' here so that syncase will
> +;; pass-through variables, meaning (variable? datum) => #t, to the
> +;; evaluator.  Without this, the system transformer will see a
> +;; variable datum as invalid syntax, which it is not to the core
> +;; transformer.
> +(define (self-evaluating? datum)
> +  (or ((@ (guile) self-evaluating?) datum)
> +      (variable? datum)))
> +

Given that self-evaluating? has no other purpose, I think it would be
preferable just to add "case scm_tc7_variable:" to the C code, along
with your excellent comment above.

I know that would technically be an incompatible change, but given
that I never heard mention of self-evaluating? before, I think we can
risk it.

(And someone can always write

 (define (compatible-self-evaluating? obj)
   (and (self-evaluating? obj)
        (not (variable? obj))))

if they need to.)

>  ;;; Load the preprocessed code
>  
>  (let ((old-debug #f)
> Index: test-suite/tests/syncase.test
> ===================================================================
> RCS file: /sources/guile/guile/guile-core/test-suite/tests/syncase.test,v
> retrieving revision 1.5
> diff -u -d -u -r1.5 syncase.test
> --- test-suite/tests/syncase.test	16 Apr 2006 23:27:14 -0000	1.5
> +++ test-suite/tests/syncase.test	14 Dec 2007 07:55:49 -0000
> @@ -34,3 +34,15 @@
>  
>  (pass-if "basic syncase macro"
>    (= (plus 1 2 3) (+ 1 2 3)))
> +
> +(pass-if "variable?s recognized as datums"
> +  (false-if-exception
> +   (begin (eq? car (eval '(@ (guile) car) (current-module)))
> +	  #t)))
> +
> +(define-syntax export-safe-plus
> +  (syntax-rules ()
> +    ((_ x ...) ((@ (guile) +) x ...))))
> +
> +(pass-if "variable?s passed through to evaluator"
> +  (= (export-safe-plus 1 2 3) (+ 1 2 3)))

These tests are fine (of course!).

Regards,
    Neil





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

end of thread, other threads:[~2008-03-06 23:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-14  8:06 [patch] variable datums with syncase transformer Stephen Compall
2008-03-05 14:59 ` Ludovic Courtès
2008-03-05 15:36   ` Stephen Compall
2008-03-05 16:34 ` Ludovic Courtès
2008-03-05 20:55   ` Neil Jerram
2008-03-05 22:16     ` Stephen Compall
2008-03-05 23:21     ` Ludovic Courtès
2008-03-06 23:28 ` Neil Jerram

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