hello,
i'm having a bug i have found no explanation for now....
I'm porting my code from Racket/R6RS to Racket.
For now i just have to translate R6RS library into Racket module for each files , so there is only the headers that change.
in Racket/R6RS i will use library
and in Racket module
and other things provide
instead of export
, require
versus import
etc....
for example, for the last modified file:
i have this R6RS code of a library:
#!r6rs
(library (nfx) ; R6RS
(export $nfx$)
(import (rnrs base (6))
(for (rnrs base (6)) expand) ; import at expand phase (not run phase)
(for (rnrs syntax-case (6)) expand)
(for (Scheme+R6RS n-arity) expand) ; at phase: 1; the transformer environment
(for (Scheme+R6RS infix-with-precedence-to-prefix) expand) ; at phase: 1; the transformer environment
(for (Scheme+R6RS operators-list) expand);; at phase: 1; the transformer environment
(for (only (rnrs io simple (6)) display newline) expand)
)
;; Welcome to DrRacket, version 8.13 [cs].
;; Language: r6rs, with debugging; memory limit: 8192 MB.
;; > ($nfx$ 3 * 5 + 2)
;; $nfx$ : parsed-args={.#<syntax:15-interactions from an unsaved editor:3:15 +> {.#<syntax:15-interactions from an unsaved editor:3:11 *> .#<syntax:15-interactions from an unsaved editor:3:9 3> .#<syntax:15-interactions from an unsaved editor:3:13 5>} .#<syntax:15-interactions from an unsaved editor:3:17 2>}
;; 17
(define-syntax $nfx$
(lambda (stx)
(syntax-case stx ()
;; note that to have $nfx$ called you need at minimum to have 2 different operator causing an operator precedence question
;; and then at least those 2 operators must be between operands each, so there is a need for 3 operand
;; the syntax then looks like this : e1 op1 e2 op2 e3 ..., example : 3 * 4 + 2
(($nfx$ e1 op1 e2 op2 e3 op ...) ; note: i add op because in scheme op ... could be non existent
;;#'(list e1 op1 e2 op2 e3 op ...)
(with-syntax ;; let
((parsed-args
;; TODO : make n-arity for <- and <+ only (because could be false with ** , but not implemented in n-arity for now)
(n-arity ;; this avoid : '{x <- y <- z <- t <- u <- 3 * 4 + 1}
;; SRFI-105.scm : !0 result = (<- (<- (<- (<- (<- x y) z) t) u) (+ (* 3 4) 1)) ;; fail set! ...
;; transform in : '(<- x y z t u (+ (* 3 4) 1))
(!0-generic #'(e1 op1 e2 op2 e3 op ...) ; apply operator precedence rules
infix-operators-lst-for-parser-syntax
;;(get-infix-operators-lst-for-parser-syntax)
(lambda (op a b) (list op a b))))))
(display "$nfx$ : parsed-args=") (display #'parsed-args) (newline)
#'parsed-args)))))
) ; end library
and i port it in a Racket module:
(module nfx racket
(provide $nfx$)
;; (import (rnrs base (6))
;; (for (rnrs base (6)) expand) ; import at expand phase (not run phase)
;; (for (rnrs syntax-case (6)) expand)
;; (for (Scheme+R6RS n-arity) expand) ; at phase: 1; the transformer environment
;; (for (Scheme+R6RS infix-with-precedence-to-prefix) expand) ; at phase: 1; the transformer environment
;; (for (Scheme+R6RS operators-list) expand);; at phase: 1; the transformer environment
;; (for (only (rnrs io simple (6)) display newline) expand)
;; )
(require (for-syntax Scheme+/n-arity)
(for-syntax Scheme+/infix-with-precedence-to-prefix)
(for-syntax Scheme+/operators-list))
;; Welcome to DrRacket, version 8.13 [cs].
;; Language: r6rs, with debugging; memory limit: 8192 MB.
;; > ($nfx$ 3 * 5 + 2)
;; $nfx$ : parsed-args={.#<syntax:15-interactions from an unsaved editor:3:15 +> {.#<syntax:15-interactions from an unsaved editor:3:11 *> .#<syntax:15-interactions from an unsaved editor:3:9 3> .#<syntax:15-interactions from an unsaved editor:3:13 5>} .#<syntax:15-interactions from an unsaved editor:3:17 2>}
;; 17
(define-syntax $nfx$
(lambda (stx)
(syntax-case stx ()
;; note that to have $nfx$ called you need at minimum to have 2 different operator causing an operator precedence question
;; and then at least those 2 operators must be between operands each, so there is a need for 3 operand
;; the syntax then looks like this : e1 op1 e2 op2 e3 ..., example : 3 * 4 + 2
(($nfx$ e1 op1 e2 op2 e3 op ...) ; note: i add op because in scheme op ... could be non existent
(with-syntax ;; let
((parsed-args
;; TODO : make n-arity for <- and <+ only (because could be false with ** , but not implemented in n-arity for now)
(n-arity ;; this avoids : '{x <- y <- z <- t <- u <- 3 * 4 + 1}
;; SRFI-105.scm : !0 result = (<- (<- (<- (<- (<- x y) z) t) u) (+ (* 3 4) 1)) ;; fail set! ...
;; transform in : '(<- x y z t u (+ (* 3 4) 1))
(!0-generic #'(e1 op1 e2 op2 e3 op ...) ; apply operator precedence rules
infix-operators-lst-for-parser-syntax
;;(get-infix-operators-lst-for-parser-syntax)
(lambda (op a b) (list op a b))))))
(display "$nfx$ : parsed-args=") (display #'parsed-args) (newline)
#'parsed-args)))))
) ; end module
the conclusion of this is that i did not changed a single line of the procedures or macro that where defined. They are the same in the two codes and in all the pair of files ,one being in R6RS the new one in Racket.
Now the weird thing: when executed the R6RS code works of course but not the Racket one.
When i trace the problem i come immediately to this point :
what was in R6RS a list of syntaxes objects
has became in Racket a syntax of a list of objects
. And this cause problem when i want to reverse
the list.
i can just provide the outputs of codes to show it:
With the Racket/R6RS version the result of 3 * 5 + 2 = 17
is well computed as the value of terms
is :
(.#<syntax:15-interactions from an unsaved editor:7:9 3> .#<syntax:15-interactions from an unsaved editor:7:11 *> .#<syntax:15-interactions from an unsaved editor:7:13 5> .#<syntax:15-interactions from an unsaved editor:7:15 +> .#<syntax:15-interactions from an unsaved editor:7:17 2>)
as show in the screenshot below:
but in Racket i got an error because of a different value for terms
:
#<syntax:Dropbox/git/Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/nfx.rkt:67:41 (3 * 5 + 2)>
and also the same code give the good result in Guile or Kawa...
GNU Guile 3.0.9
Copyright (C) 1995-2023 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)> (use-modules (nfx))
;;; note: source file /usr/share/guile/site/3.0/infix-with-precedence-to-prefix.scm
;;; newer than compiled /home/mattei/.cache/guile/ccache/3.0-LE-8-4.6/usr/share/guile/site/3.0/infix-with-precedence-to-prefix.scm.go
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;; or pass the --no-auto-compile argument to disable.
;;; compiling /usr/share/guile/site/3.0/infix-with-precedence-to-prefix.scm
;;; compiled /home/mattei/.cache/guile/ccache/3.0-LE-8-4.6/usr/share/guile/site/3.0/infix-with-precedence-to-prefix.scm.go
scheme@(guile-user)> ($nfx$ 3 * 5 + 2)
!0-generic : terms=(#<syntax:unknown file:2:7 3> #<syntax:unknown file:2:9 *> #<syntax:unknown file:2:11 5> #<syntax:unknown file:2:13 +> #<syntax:unknown file:2:15 2>)
$nfx$ : parsed-args=(#<syntax:unknown file:2:13 +> (#<syntax:unknown file:2:9 *> #<syntax:unknown file:2:7 3> #<syntax:unknown file:2:11 5>) #<syntax:unknown file:2:15 2>)
$1 = 17
Kawa (without displaying terms
)
#|kawa:1|# (import (nfx))
#|kawa:2|# ($nfx$ 3 * 5 + 2)
17