unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Aliasing an identifier
@ 2018-11-15 16:55 Marc Nieper-Wißkirchen
  2018-11-17 15:17 ` Marc Nieper-Wißkirchen
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Nieper-Wißkirchen @ 2018-11-15 16:55 UTC (permalink / raw)
  To: guile-devel

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

I would like to alias an identifier in Guile. By this, I mean the
following: Given a bound identifier `x', I want to lexically introduce
another identifier `y' with the same binding as `x' so that `x' and `y'
become `free-identifier=?'.

The following is one use case: I have written a macro `custom-quasiquote`,
which has a similar syntax and does similar things as `quasiquote' does.
Because I would like to use the special reader syntax for `quasiquote', I
would do:

(letrec-syntax ((quasiquote <custom-quasiquote-transformer>))
  <body>)

In the <body>, whenever I write ``<template>', my
<custom-quasiquote-transformer> is being applied to <template>.

There may be parts in the <body> where I would like to use Scheme's
quasiquotation. One try is to surround these parts with:

(let-syntax ((quasiquote (identifier-syntax scheme-quasiquote)))
  <expression>)

Here, `scheme-quasiquote' is bound to `quasiquote' as exported by
`(guile)'. However, this solution is not correct as the `quasiquote' local
to <expression> is not `free-identifier=?' to `scheme-quasiquote'. Thus
quasiquotations containing quasiquotes (that should become auxiliary
syntax) won't work right.

What I really need is to make the inner `quasiquote' a true alias of
`scheme-quasiquote' (or rather to restore the binding of `quasiquote' in
<expression> to what the binding outside the outer `letrec-syntax' was).

Chez Scheme has `alias' for this purpose:
https://cisco.github.io/ChezScheme/csug9.5/syntax.html#./syntax:h10.

What can I do in Scheme? If this is currently impossible, please consider
this post as a feature request for `alias' or a similar binding construct.
:-)

-- Marc

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

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

* Re: Aliasing an identifier
  2018-11-15 16:55 Aliasing an identifier Marc Nieper-Wißkirchen
@ 2018-11-17 15:17 ` Marc Nieper-Wißkirchen
  2018-11-18 11:15   ` Marc Nieper-Wißkirchen
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Nieper-Wißkirchen @ 2018-11-17 15:17 UTC (permalink / raw)
  To: guile-devel

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

Am Do., 15. Nov. 2018 um 17:55 Uhr schrieb Marc Nieper-Wißkirchen <
marc.nieper@gmail.com>:

> I would like to alias an identifier in Guile. By this, I mean the
> following: Given a bound identifier `x', I want to lexically introduce
> another identifier `y' with the same binding as `x' so that `x' and `y'
> become `free-identifier=?'.
>
> The following is one use case: I have written a macro `custom-quasiquote`,
> which has a similar syntax and does similar things as `quasiquote' does.
> Because I would like to use the special reader syntax for `quasiquote', I
> would do:
>
> (letrec-syntax ((quasiquote <custom-quasiquote-transformer>))
>   <body>)
>
> In the <body>, whenever I write ``<template>', my
> <custom-quasiquote-transformer> is being applied to <template>.
>
> There may be parts in the <body> where I would like to use Scheme's
> quasiquotation. One try is to surround these parts with:
>
> (let-syntax ((quasiquote (identifier-syntax scheme-quasiquote)))
>   <expression>)
>
> Here, `scheme-quasiquote' is bound to `quasiquote' as exported by
> `(guile)'. However, this solution is not correct as the `quasiquote' local
> to <expression> is not `free-identifier=?' to `scheme-quasiquote'. Thus
> quasiquotations containing quasiquotes (that should become auxiliary
> syntax) won't work right.
>
> What I really need is to make the inner `quasiquote' a true alias of
> `scheme-quasiquote' (or rather to restore the binding of `quasiquote' in
> <expression> to what the binding outside the outer `letrec-syntax' was).
>
> Chez Scheme has `alias' for this purpose:
> https://cisco.github.io/ChezScheme/csug9.5/syntax.html#./syntax:h10.
>
> What can I do in Scheme? If this is currently impossible, please consider
> this post as a feature request for `alias' or a similar binding construct.
> :-)
>

Typo. "What can I in GUILE?" was the question I intended to ask. :-)

I gave it a try to implement `define-alias' in Guile. My first
approximation to a solution was to add a clause like

((define-alias-form)
  (let ((id (wrap value w mod))
        (label (id-var-name e w mod)))
    (extend-ribcage! ribcage id label)
    (parse (cdr body) (cons id ids) labels var-ids vars vals bindings)))

to `expand-body' in `psyntax.scm'. (A similar clause is added to
`expand-top-sequence' and `syntax-type' is extended to recognize
`define-alias' and return `define-alias-form' for the type.)

With identifiers lexically bound in the same module, my change does what it
is supposed to do. The following test passes:

(pass-if "alias is free-identifier=?"
  (let ((x #t))
    (define-syntax foo
      (syntax-rules (x)
        ((foo x) #t)
        ((foo _) #f)))
    (let ()
      (define-alias y x)
      (foo y))))

My code, however, doesn't work when the aliased identifier is global and/or
comes from another module: The following test fails:

(pass-if-equal "alias is free-identifier=? with globals"
    '(1 5)
  (let ()
    (define-alias comma unquote)
    `(1 (comma (+ 2 3)))))

I see that my attempt to bind the identifier `y' to `x's label (if given
`(define-alias y x)') is too naive. I have taken a look at `free-id=?' and
`resolve-identifier' in `psyntax.scm', but the way modules are handled in
`psyntax.scm' is still new to me. Thus I'm glad about any hints.

-- Marc

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

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

* Re: Aliasing an identifier
  2018-11-17 15:17 ` Marc Nieper-Wißkirchen
@ 2018-11-18 11:15   ` Marc Nieper-Wißkirchen
  0 siblings, 0 replies; 3+ messages in thread
From: Marc Nieper-Wißkirchen @ 2018-11-18 11:15 UTC (permalink / raw)
  To: guile-devel


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

Am Sa., 17. Nov. 2018 um 16:17 Uhr schrieb Marc Nieper-Wißkirchen <
marc.nieper@gmail.com>:

> Am Do., 15. Nov. 2018 um 17:55 Uhr schrieb Marc Nieper-Wißkirchen <
> marc.nieper@gmail.com>:
>
>> I would like to alias an identifier in Guile. By this, I mean the
>> following: Given a bound identifier `x', I want to lexically introduce
>> another identifier `y' with the same binding as `x' so that `x' and `y'
>> become `free-identifier=?'.
>>
>> Typo. "What can I in GUILE?" was the question I intended to ask. :-)
>
> I gave it a try to implement `define-alias' in Guile. My first
> approximation to a solution was to add a clause like
>
> ((define-alias-form)
>   (let ((id (wrap value w mod))
>         (label (id-var-name e w mod)))
>     (extend-ribcage! ribcage id label)
>     (parse (cdr body) (cons id ids) labels var-ids vars vals bindings)))
>
> to `expand-body' in `psyntax.scm'. (A similar clause is added to
> `expand-top-sequence' and `syntax-type' is extended to recognize
> `define-alias' and return `define-alias-form' for the type.)
>
> With identifiers lexically bound in the same module, my change does what
> it is supposed to do. The following test passes:
>
> (pass-if "alias is free-identifier=?"
>   (let ((x #t))
>     (define-syntax foo
>       (syntax-rules (x)
>         ((foo x) #t)
>         ((foo _) #f)))
>     (let ()
>       (define-alias y x)
>       (foo y))))
>
> My code, however, doesn't work when the aliased identifier is global
> and/or comes from another module: The following test fails:
>
> (pass-if-equal "alias is free-identifier=? with globals"
>     '(1 5)
>   (let ()
>     (define-alias comma unquote)
>     `(1 (comma (+ 2 3)))))
>
> I see that my attempt to bind the identifier `y' to `x's label (if given
> `(define-alias y x)') is too naive. I have taken a look at `free-id=?' and
> `resolve-identifier' in `psyntax.scm', but the way modules are handled in
> `psyntax.scm' is still new to me. Thus I'm glad about any hints.
>

The problem seems to lie in the code of `free-id=?' in `psyntax.scm'.
`free-id=?' contains the following clause:

((symbol? ni)
  ;; `i' is not lexically bound.  Assert that `j' is free,
  ;; and if so, compare their bindings, that they are either
  ;; bound to the same variable, or both unbound and have
  ;; the same name.
  (and (eq? nj (id-sym-name j))
       (let ((bi (id-module-binding i mi)))
         (if bi
             (eq? bi (id-module-binding j mj))
             (and (not (id-module-binding j mj))
                  (eq? ni nj))))
       (eq? (id-module-binding i mi) (id-module-binding j mj))))

`free-id=?' is called by the transformer of `quasiquote' to check whether
`comma' and `unquote' are `free-identifier=?'. If I understand the code of
`free-id=?' correctly, `ni' and `nj' become the labels of `comma' and
`unquote', respectively, which are both the same due to how I have tried to
implement `define-alias'. These labels are symbols because they are not
lexically bound but (imported) globals (from the module `(guile)').

The code from `free-id=?' cited above looks up the module bindings of
`comma' and `unquote' but not by their (symbol) labels, but by their
identifier names. This fails because there is no global identifier bound
with the name `comma'. (Independently, too things about the code look
strange to me. Firstly, the code seems to make the relation defined by
`free-id=?' non-symmetric: For the second identifier `j', it is checked
whether its symbol name is the same as its label. This does not happen for
the identifier `i'. Secondly, the last `eq?' comparison seems to be
superfluous.)

I have rewritten the above clause as follows:

((symbol? ni)
  ;; `i' is not lexically bound.  Assert that `j' is free,
  ;; and if so, compare their bindings, that they are either
  ;; bound to the same variable, or both unbound and have
  ;; the same name.
  (and (symbol? nj)
       (let ((bi (id-module-binding ni mi)))
         (if bi
             (eq? bi (id-module-binding nj mj))
             (and (not (id-module-binding nj mj))
               (eq? ni nj)))))))

The main difference is that I use `ni' and `nj' (the symbol labels) to look
up the binding (I also have to check explicitly that the label of `j' also
makes `j' as not lexically bound.)

I think this implements the correct semantics of free-id=?. And, indeed,
the following test now passes:

(pass-if-equal "alias is free-identifier=? with globals"
    '(1 5)
  (let ()
    (define-alias comma unquote)
    `(1 (comma (+ 2 3)))))

Also this test now works correctly:

(pass-if "alias is free-identifier=? with unbound"
  (let ()
    (define-syntax foo
      (syntax-rules (x z)
        ((foo z) #f)
        ((foo x) #t)
        ((foo _) #f)))
    (let ()
      (define-alias y x)
      (foo y))))

The new semantics `free-id=?' are compatible with all existing tests in the
Guile test suite. If you want to experiment with my ideas, I have attached
a patch file.

-- Marc

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

[-- Attachment #2: define-alias.patch --]
[-- Type: text/x-patch, Size: 17896 bytes --]

diff --git a/.gitignore b/.gitignore
index dc8eedaf4..7d2d79daa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -168,3 +168,4 @@ INSTALL
 /meta/build-env
 /lib/limits.h
 /lib/stdint.h
+/filesys-test-link.tmp
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index adc699713..41feb947c 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -954,13 +954,12 @@
             ;; and if so, compare their bindings, that they are either
             ;; bound to the same variable, or both unbound and have
             ;; the same name.
-            (and (eq? nj (id-sym-name j))
-                 (let ((bi (id-module-binding i mi)))
+            (and (symbol? nj)
+                 (let ((bi (id-module-binding ni mi)))
                    (if bi
-                       (eq? bi (id-module-binding j mj))
-                       (and (not (id-module-binding j mj))
-                            (eq? ni nj))))
-                 (eq? (id-module-binding i mi) (id-module-binding j mj))))
+                       (eq? bi (id-module-binding nj mj))
+                       (and (not (id-module-binding nj mj))
+                            (eq? ni nj))))))
            (else
             ;; Otherwise `i' is bound, so check that `j' is bound, and
             ;; bound to the same thing.
@@ -1129,6 +1128,11 @@
                                                        mod))
                               (lambda ()
                                 (build-global-definition s var (expand e r w mod)))))))))
+                  ((define-alias-form)
+                   (let ((id (wrap value w mod))
+                         (label (id-var-name e w mod)))
+                     (extend-ribcage! ribcage id label)
+                     '()))
                   ((define-syntax-form define-syntax-parameter-form)
                    (let* ((id (wrap value w mod))
                           (label (gen-label))
@@ -1272,6 +1276,7 @@
     ;;    call                   none          any other call
     ;;    begin-form             none          begin expression
     ;;    define-form            id            variable definition
+    ;;    define-alias-form      id            alias definition
     ;;    define-syntax-form     id            syntax definition
     ;;    define-syntax-parameter-form id      syntax parameter definition
     ;;    local-syntax-form      rec?          syntax definition
@@ -1359,6 +1364,11 @@
                               (wrap e w mod)
                               #'(if #f #f)
                               empty-wrap s mod))))
+                  ((define-alias)
+                   (syntax-case e ()
+                     ((_ name val)
+                      (and (id? #'name) (id? #'val))
+                      (values 'define-alias-form #'name e #'val w s mod))))
                   ((define-syntax)
                    (syntax-case e ()
                      ((_ name val)
@@ -1443,7 +1453,8 @@
                 (if (memq 'eval when-list)
                     (expand-sequence #'(e1 e2 ...) r w s mod)
                     (expand-void))))))
-          ((define-form define-syntax-form define-syntax-parameter-form)
+          ((define-form define-alias-form define-syntax-form
+             define-syntax-parameter-form)
            (syntax-violation #f "definition in expression context, where definitions are not allowed,"
                              (source-wrap form w s mod)))
           ((syntax)
@@ -1600,6 +1611,12 @@
                                     (cons id var-ids)
                                     (cons var vars) (cons (cons er (wrap e w mod)) vals)
                                     (cons (make-binding 'lexical var) bindings)))))
+                        ((define-alias-form)
+                         (let ((id (wrap value w mod))
+                               (label (id-var-name e w mod)))
+                           (extend-ribcage! ribcage id label)
+                           (parse (cdr body) (cons id ids) labels var-ids vars vals
+                                  bindings)))
                         ((define-syntax-form)
                          (let ((id (wrap value w mod))
                                (label (gen-label))
@@ -1727,8 +1744,8 @@
              (call-with-values
                  (lambda () (resolve-identifier
                              (make-syntax '#{ $sc-ellipsis }#
-                                                 (syntax-wrap e)
-                                                 (syntax-module e))
+                                          (syntax-wrap e)
+                                          (syntax-module e))
                              empty-wrap r mod #f))
                (lambda (type value mod)
                  (if (eq? type 'ellipsis)
@@ -2036,10 +2053,10 @@
                            (eval-local-transformer (expand x trans-r w mod) mod)))
                         #'(val ...)))))
             (expand-body #'(e1 e2 ...)
-                      (source-wrap e w s mod)
-                      (extend-env names bindings r)
-                      w
-                      mod)))
+                         (source-wrap e w s mod)
+                         (extend-env names bindings r)
+                         w
+                         mod)))
          (_ (syntax-violation 'syntax-parameterize "bad syntax"
                               (source-wrap e w s mod))))))
 
@@ -2290,8 +2307,8 @@
                         (let ((id (if (symbol? #'dots)
                                       '#{ $sc-ellipsis }#
                                       (make-syntax '#{ $sc-ellipsis }#
-                                                          (syntax-wrap #'dots)
-                                                          (syntax-module #'dots)))))
+                                                   (syntax-wrap #'dots)
+                                                   (syntax-module #'dots)))))
                           (let ((ids (list id))
                                 (labels (list (gen-label)))
                                 (bindings (list (make-binding 'ellipsis (source-wrap #'dots w s mod)))))
@@ -2503,6 +2520,8 @@
 
     (global-extend 'define 'define '())
 
+    (global-extend 'define-alias 'define-alias '())
+
     (global-extend 'define-syntax 'define-syntax '())
     (global-extend 'define-syntax-parameter 'define-syntax-parameter '())
 
@@ -2519,12 +2538,12 @@
                              (syntax-case p* ()
                                ((x . y)
                                 (call-with-values
-                                     (lambda () (cvt* #'y n ids))
-                                   (lambda (y ids)
-                                     (call-with-values
-                                         (lambda () (cvt #'x n ids))
-                                       (lambda (x ids)
-                                         (values (cons x y) ids))))))
+                                    (lambda () (cvt* #'y n ids))
+                                  (lambda (y ids)
+                                    (call-with-values
+                                        (lambda () (cvt #'x n ids))
+                                      (lambda (x ids)
+                                        (values (cons x y) ids))))))
                                (_ (cvt p* n ids)))))
                          
                          (define (v-reverse x)
@@ -2589,15 +2608,15 @@
                               'apply
                               (list (build-simple-lambda no-source (map syntax->datum ids) #f new-vars '()
                                                          (expand exp
-                                                              (extend-env
-                                                               labels
-                                                               (map (lambda (var level)
-                                                                      (make-binding 'syntax `(,var . ,level)))
-                                                                    new-vars
-                                                                    (map cdr pvars))
-                                                               r)
-                                                              (make-binding-wrap ids labels empty-wrap)
-                                                              mod))
+                                                                 (extend-env
+                                                                  labels
+                                                                  (map (lambda (var level)
+                                                                         (make-binding 'syntax `(,var . ,level)))
+                                                                       new-vars
+                                                                       (map cdr pvars))
+                                                                  r)
+                                                                 (make-binding-wrap ids labels empty-wrap)
+                                                                 mod))
                                     y))))))
 
                      (define gen-clause
@@ -2653,12 +2672,12 @@
                                                        no-source (list (syntax->datum #'pat)) #f (list var)
                                                        '()
                                                        (expand #'exp
-                                                            (extend-env labels
-                                                                        (list (make-binding 'syntax `(,var . 0)))
-                                                                        r)
-                                                            (make-binding-wrap #'(pat)
-                                                                               labels empty-wrap)
-                                                            mod))
+                                                               (extend-env labels
+                                                                           (list (make-binding 'syntax `(,var . 0)))
+                                                                           r)
+                                                               (make-binding-wrap #'(pat)
+                                                                                  labels empty-wrap)
+                                                               mod))
                                                       (list x))))
                                     (gen-clause x keys (cdr clauses) r
                                                 #'pat #t #'exp mod)))
@@ -2696,58 +2715,58 @@
     ;; expanded, and the expanded definitions are also residualized into
     ;; the object file if we are compiling a file.
     (set! macroexpand
-          (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))))))
+      (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! identifier?
-          (lambda (x)
-            (nonsymbol-id? x)))
+      (lambda (x)
+        (nonsymbol-id? x)))
 
     (set! datum->syntax
-          (lambda (id datum)
-            (make-syntax datum (syntax-wrap id)
-                                (syntax-module id))))
+      (lambda (id datum)
+        (make-syntax datum (syntax-wrap id)
+                     (syntax-module id))))
 
     (set! syntax->datum
-          ;; accepts any object, since syntax objects may consist partially
-          ;; or entirely of unwrapped, nonsymbolic data
-          (lambda (x)
-            (strip x empty-wrap)))
+      ;; accepts any object, since syntax objects may consist partially
+      ;; or entirely of unwrapped, nonsymbolic data
+      (lambda (x)
+        (strip x empty-wrap)))
 
     (set! syntax-source
-          (lambda (x) (source-annotation x)))
+      (lambda (x) (source-annotation x)))
 
     (set! generate-temporaries
-          (lambda (ls)
-            (arg-check list? ls 'generate-temporaries)
-            (let ((mod (cons 'hygiene (module-name (current-module)))))
-              (map (lambda (x)
-                     (wrap (module-gensym "t") top-wrap mod))
-                   ls))))
+      (lambda (ls)
+        (arg-check list? ls 'generate-temporaries)
+        (let ((mod (cons 'hygiene (module-name (current-module)))))
+          (map (lambda (x)
+                 (wrap (module-gensym "t") top-wrap mod))
+               ls))))
 
     (set! free-identifier=?
-          (lambda (x y)
-            (arg-check nonsymbol-id? x 'free-identifier=?)
-            (arg-check nonsymbol-id? y 'free-identifier=?)
-            (free-id=? x y)))
+      (lambda (x y)
+        (arg-check nonsymbol-id? x 'free-identifier=?)
+        (arg-check nonsymbol-id? y 'free-identifier=?)
+        (free-id=? x y)))
 
     (set! bound-identifier=?
-          (lambda (x y)
-            (arg-check nonsymbol-id? x 'bound-identifier=?)
-            (arg-check nonsymbol-id? y 'bound-identifier=?)
-            (bound-id=? x y)))
+      (lambda (x y)
+        (arg-check nonsymbol-id? x 'bound-identifier=?)
+        (arg-check nonsymbol-id? y 'bound-identifier=?)
+        (bound-id=? x y)))
 
     (set! syntax-violation
-          (lambda* (who message form #:optional subform)
-            (arg-check (lambda (x) (or (not x) (string? x) (symbol? x)))
-                       who 'syntax-violation)
-            (arg-check string? message 'syntax-violation)
-            (throw 'syntax-error who message
-                   (or (source-annotation subform)
-                       (source-annotation form))
-                   (strip form empty-wrap)
-                   (and subform (strip subform empty-wrap)))))
+      (lambda* (who message form #:optional subform)
+        (arg-check (lambda (x) (or (not x) (string? x) (symbol? x)))
+                   who 'syntax-violation)
+        (arg-check string? message 'syntax-violation)
+        (throw 'syntax-error who message
+               (or (source-annotation subform)
+                   (source-annotation form))
+               (strip form empty-wrap)
+               (and subform (strip subform empty-wrap)))))
 
     (let ()
       (define (%syntax-module id)
@@ -2788,8 +2807,8 @@
                  ((ellipsis)
                   (values 'ellipsis
                           (make-syntax (syntax-expression value)
-                                              (anti-mark (syntax-wrap value))
-                                              (syntax-module value))))
+                                       (anti-mark (syntax-wrap value))
+                                       (syntax-module value))))
                  (else (values 'other #f))))))))
 
       (define (syntax-locally-bound-identifiers id)
@@ -2913,8 +2932,8 @@
            ((null? p) (and (null? e) r))
            ((pair? p)
             (and (pair? e) (match (car e) (car p) w
-                             (match (cdr e) (cdr p) w r mod)
-                             mod)))
+                                  (match (cdr e) (cdr p) w r mod)
+                                  mod)))
            ((eq? p 'each-any)
             (let ((l (match-each-any e w mod))) (and l (cons l r))))
            (else
@@ -2960,14 +2979,14 @@
            (else (match* e p w r mod)))))
 
       (set! $sc-dispatch
-            (lambda (e p)
-              (cond
-               ((eq? p 'any) (list e))
-               ((eq? p '_) '())
-               ((syntax? e)
-                (match* (syntax-expression e)
-                        p (syntax-wrap e) '() (syntax-module e)))
-               (else (match* e p empty-wrap '() #f))))))))
+        (lambda (e p)
+          (cond
+           ((eq? p 'any) (list e))
+           ((eq? p '_) '())
+           ((syntax? e)
+            (match* (syntax-expression e)
+                    p (syntax-wrap e) '() (syntax-module e)))
+           (else (match* e p empty-wrap '() #f))))))))
 
 
 (define-syntax with-syntax
diff --git a/test-suite/tests/syntax.test b/test-suite/tests/syntax.test
index 883004a27..67df87b3d 100644
--- a/test-suite/tests/syntax.test
+++ b/test-suite/tests/syntax.test
@@ -1649,6 +1649,50 @@
         (hash interpreted most-positive-fixnum)
       (hash compiled most-positive-fixnum))))
 
+(with-test-prefix "aliases"
+  (pass-if "aliased variables are eq?"
+    (let ((x "var"))
+      (define-alias y x)
+      (eq? x y)))
+
+  (pass-if "can alias definition in the same body"
+    (let ((y #f))
+      (define x #t)
+      (define-alias y x)
+      y))
+
+  (pass-if "right hand side of alias-definition is not postponed"
+    (let ((x #t))
+      (define-alias y x)
+      (define x #f)
+      y))
+
+  (pass-if "alias is free-identifier=?"
+    (let ((x #t))
+      (define-syntax foo
+        (syntax-rules (x)
+          ((foo x) #t)
+          ((foo _) #f)))
+      (let ()
+        (define-alias y x)
+        (foo y))))
+
+  (pass-if "alias is free-identifier=? with unbound"
+    (let ()
+      (define-syntax foo
+        (syntax-rules (x z)
+          ((foo z) #f)
+          ((foo x) #t)
+          ((foo _) #f)))
+      (let ()
+        (define-alias y x)
+        (foo y))))
+
+  (pass-if-equal "alias is free-identifier=? with globals"
+      '(1 5)
+    (let ()
+      (define-alias comma unquote)
+      `(1 (comma (+ 2 3))))))
 
 ;;; Local Variables:
 ;;; eval: (put 'pass-if-syntax-error 'scheme-indent-function 1)

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

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

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-15 16:55 Aliasing an identifier Marc Nieper-Wißkirchen
2018-11-17 15:17 ` Marc Nieper-Wißkirchen
2018-11-18 11:15   ` Marc Nieper-Wißkirchen

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