chicken-janitors
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-janitors] #1441: Macro keywords unexpectedly match against


From: Chicken Trac
Subject: Re: [Chicken-janitors] #1441: Macro keywords unexpectedly match against imported identifiers
Date: Sat, 24 Feb 2018 09:31:19 -0000

#1441: Macro keywords unexpectedly match against imported identifiers
-------------------------------------+-------------------------------------
            Reporter:  sjamaan       |      Owner:  sjamaan
                Type:  defect        |     Status:  new
            Priority:  major         |  Milestone:  4.14.0
           Component:  expander      |    Version:  4.13.0
          Resolution:                |   Keywords:  hygiene, syntax-rules,
Estimated difficulty:  hard          |  capture
-------------------------------------+-------------------------------------

Comment (by sjamaan):

 Original bug report case ported to Racket:

 {{{
 ;; unhygienic-loop-racket.scm
 #lang racket

 (provide loop)

 (define-syntax find-identifier
   (syntax-rules ()
     ((_ ident (x . y) sk fk)
      (find-identifier ident x sk (find-identifier ident y sk fk)))
     ((_ ident #(x ...) sk fk)
      (find-identifier ident (x ...) sk fk))
     ((_ ident form sk fk)
      (let-syntax
          ((check
            (syntax-rules (ident)
              ((_ ident ident* (s-f . s-args) fk_) (s-f ident* . s-args))
              ((_ x y sk_ fk_) fk_))))
        (check form form sk fk)))))


 (define-syntax loop
   (syntax-rules ()
     ((_ . exps)
      (let-syntax
          ((l (syntax-rules ()
                ((_ ident exps_)
                 (call-with-current-continuation
                  (lambda (ident)
                    (let f ()
                      (begin 'prevent-empty-begin . exps_)
                      (f))))))))
        (find-identifier break exps (l exps) (l bogus exps))))))
 }}}

 {{{
 ;; myfoo-racket.scm
 #lang racket

 (provide foo)

 (define foo 2)
 }}}

 Running it shows a difference, but not 100% the same as CIHCKEN 4.13.0
 depending on the place where {{{break}}} was defined:

 {{{
 Welcome to Racket v6.7.
 > (require "unhygienic-loop-racket.scm")
 > (loop (break 'foo))
 'foo
 > (require "break-racket.scm")
 > (loop (break 'foo))
 ; application: not a procedure;
 ;  expected a procedure that can be applied to arguments
 ;   given: "elsewhere"
 ; [,bt for context]
 > (define break 2)
 > (loop (break 'foo))
 'foo
 }}}

 In Scheme48, it behaves differently:

 {{{
 ;; unhygienic-loop-s48.scm
 (define-syntax find-identifier
   (syntax-rules ()
     ((_ ident (x . y) sk fk)
      (find-identifier ident x sk (find-identifier ident y sk fk)))
     ((_ ident #(x ...) sk fk)
      (find-identifier ident (x ...) sk fk))
     ((_ ident form sk fk)
      (let-syntax
          ((check
            (syntax-rules (ident)
              ((_ ident ident* (s-f . s-args) fk_) (s-f ident* . s-args))
              ((_ x y sk_ fk_) fk_))))
        (check form form sk fk)))))


 (define-syntax loop
   (syntax-rules ()
     ((_ . exps)
      (let-syntax
          ((l (syntax-rules ()
                ((_ ident exps_)
                 (call-with-current-continuation
                  (lambda (ident)
                    (let f ()
                      (begin 'prevent-empty-begin . exps_)
                      (f))))))))
        (find-identifier break exps (l exps) (l bogus exps))))))
 }}}

 {{{
 ;;; break-s48
 (define break "elsewhere")
 }}}

 {{{
 ;;; packages.scm
 (define-structure unhygienic-loop-s48 (export loop)
    (open scheme)
    (files unhygienic-loop-s48))

 (define-structure break-s48 (export break)
    (open scheme)
    (files break-s48))
 }}}


 When running it:

 {{{
 Welcome to Scheme 48 1.9 (made by binet on 2017-03-16)
 See http://s48.org/ for more information.
 Please report bugs to address@hidden
 Get more information at http://www.s48.org/.
 Type ,? (comma question-mark) for help.
 > ,config ,load packages.scm
 > ,open unhygienic-loop-s48
 > (loop (break 'foo))

 warning: invalid variable reference [get-location]
          loop
          #{package 284 user}

 assertion-violation: undefined variable [global]
                      break
                      user
 1> ,open break-s48
 Newly accessible in user: (break)
 1> (loop (break 'foo))

 warning: invalid variable reference [get-location]
          loop
          #{package 284 user}

 assertion-violation: attempt to call a non-procedure [call]
                      ("elsewhere" '(foo))
 1> (define break 2)
 ; no values returned
 1> (loop (break 'foo))

 warning: invalid variable reference [get-location]
          loop
          #{package 284 user}

 assertion-violation: attempt to call a non-procedure [call]
                      (2 '(foo))

 }}}

 Whereas in Chibi:

 {{{
 ;;; unhygienic-loop-chibi.sld
 (define-library (unhygienic-loop-chibi)
   (export loop)
   (import (scheme base))
   (begin
     (define-syntax find-identifier
       (syntax-rules ()
         ((_ ident (x . y) sk fk)
          (find-identifier ident x sk (find-identifier ident y sk fk)))
         ((_ ident #(x ...) sk fk)
          (find-identifier ident (x ...) sk fk))
         ((_ ident form sk fk)
          (let-syntax
              ((check
                (syntax-rules (ident)
                  ((_ ident ident* (s-f . s-args) fk_) (s-f ident* .
 s-args))
                  ((_ x y sk_ fk_) fk_))))
            (check form form sk fk)))))

     (define-syntax loop
       (syntax-rules ()
         ((_ . exps)
          (let-syntax
              ((l (syntax-rules ()
                    ((_ ident exps_)
                     (call-with-current-continuation
                      (lambda (ident)
                        (let f ()
                          (begin 'prevent-empty-begin . exps_)
                          (f))))))))
            (find-identifier break exps (l exps) (l bogus exps))))))))
 }}}

 {{{
 ;;; break-chibi.sld
 (define-library (break-chibi)
   (export break)
   (import (scheme base))
   (begin (define break "elsewhere")))
 }}}

 Running it gives me:

 {{{
 > (import (unhygienic-loop-chibi))
 > (loop (break 'foo))
 foo
 > (import (break-chibi))
 > (loop (break 'foo))
 foo
 > (define break 1)
 > (loop (break 'foo))
 foo
 }}}

 In Gauche, I get the same results as in Chibi with the R7RS library
 definitions.

 Perhaps others can check other r7rs implementations?

 My preliminary conclusion is that this is not a bug, just a very big
 "undefined behaviour"-type hole in the specification.

--
Ticket URL: <https://bugs.call-cc.org/ticket/1441#comment:11>
CHICKEN Scheme <https://www.call-cc.org/>
CHICKEN Scheme is a compiler for the Scheme programming language.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]