Error 'cond: unbound identifier; also, no #%app syntax transformer is bound'

Hello,

i have an error i can not resolve in racket/r6rs. The almost same code works in Guile (pure Guile) and Kawa (approx. r7rs) .
I think it should works in Racket but i have re-written a lot of code in R6RS and i will lost all those code if i can not find a solution in r6rs.

It is a module that allow some syntax like (if test then statements else other-statements) and is also compatible with classic 'if' of scheme.

It is a bit long but here is the code:

#!r6rs


;; /Applications/Racket\ v8.13/bin/plt-r6rs --install if-then-else.scm
;; [installing /Users/mattei/Library/Racket/8.13/collects/if-then-else/main.ss]
;; [Compiling /Users/mattei/Library/Racket/8.13/collects/if-then-else/main.ss]



(library (if-then-else) ; R6RS

  (export if)
  
  (import (rnrs base (6))
	  (rnrs syntax-case (6))
	  ;;(only (racket) syntax-case)
	  (for (rnrs base (6)) expand) ; import at expand phase (not run phase)
	  (for (rnrs syntax-case (6)) expand)
	  (only (srfi :1) third)
	  (declare)
	  (insert)
	  (syntax)
	  (for (if-parser) expand)
	  (for (only (rnrs io simple (6)) display newline) expand))

  


(define-syntax if
  
  (lambda (stx)
    
    (syntax-case stx (then else)
      
      ((if tst ...)

       (with-syntax ((parsed-args  (call-parse-if-args-syntax #'(tst ...))))

		    (display "if : parsed-args=") (display #'parsed-args) (newline)
       		    #'parsed-args)))))
		    

) ; end module

the other modules are:

#!r6rs


;; /Applications/Racket\ v8.13/bin/plt-r6rs --install if-parser.scm



(library (if-parser) ; R6RS

  (export then=?
	  else=?
	  call-parse-if-args-syntax)
  
  (import (rnrs base (6))
	  ;;(for (rnrs base (6)) expand) ; import at expand phase (not run phase)
	  (rnrs syntax-case (6))
	  (only (srfi :1) third)
	  (declare)
	  (insert)
	  (syntax))

;; usefull procedures and macro for the next part of code
(define (then=? arg)

  (or (datum=? arg 'then)
      (datum=? arg 'THEN)))

  ;; (or (equal? arg 'then)
  ;;     (equal? arg 'THEN)
  ;;     (check-syntax=? #'then arg)
  ;;     (check-syntax=? #'THEN arg)))

(define (else=? arg)

  (or (datum=? arg 'else)
      (datum=? arg 'ELSE)))

  ;; (or (equal? arg 'else)
  ;;     (equal? arg 'ELSE)
  ;;     (check-syntax=? #'else arg)
  ;;     (check-syntax=? #'ELSE arg)))


;; > (if #f else 3)
;; 3
;; > (if #t else 3)
;; > (if #t 2 else 3)
;; 2
;; > (if #t then 2 else 3)
;; 2
;; > (if #f then 2 else 3)
;; 3
;; > (if #f then 1 2 else 3 4)
;; 4
;; > (if #t then 1 2 else 3 4)
;; 2
;; > (if #t 1 2 3)
;; 3
;; > (if #t then 1 2 else 3 4 then 5)
;; . . SRFI-105.rkt:181:17: if: then after else near : '(then 5)
;; > (if #t then 1 2 else 3 4 else 5)
;; . . SRFI-105.rkt:181:17: if: 2 else inside near: '(else 5)
;; > (if #t else 1 2 then 3 4)
;; . . SRFI-105.rkt:181:17: if: then after else near : '(then 3 4)
;; > (if #t then 1 2 then 3 4)
;; . . SRFI-105.rkt:181:17: if: 2 then inside near: '(then 3 4)


;; #|kawa:1|# (import (if-then-else))
;; #|kawa:2|# (if (< 2 3) then "2 < 3" else "error")
;; 2 < 3


(define (call-parse-if-args-syntax Largs) ; Largs = (test e1 ...)

  ;;(display "Largs=") (display Largs) (newline)
  (define lenL (length Largs))

  (declare test e1)
  
  (cond ((< lenL 2)
	 (error "if: too few arguments:" Largs)))

  (set! test (car Largs))
  (set! e1 (cadr Largs))

  
  ; deal with the old 2 args 'if' but modified
  (cond ((and (= lenL 2) (then=? e1))
	 (error "if: syntax error,found (if test then) only: near " Largs))
	((and (= lenL 2) (else=? e1))
	 (error "if: syntax error,found (if test else) only: near " Largs))
	((= lenL 2) #`(cond (#,test #,e1))) ; (if test e1)
	
	 ((and (= lenL 3) (then=? e1)) #`(cond (#,test ; (if test then e2)
						#,(third Largs))))
	 ((and (= lenL 3) (else=? e1)) #`(cond ((not #,test) ; (if test else e2)
						 #,(third Largs))))
	 ((= lenL 3) #`(cond (#,test #,e1)
			     (else #,(third Largs))))

	 (else

	  (let ()
	    (define L-then '())
	    (define L-else '())
	    (define cpt-then 0)
	    (define cpt-else 0)
	    
	    (define (parse-if-args L)
	    
	    (cond ((null? L) (set! L-then (reverse L-then))
		             (set! L-else (reverse L-else)))
		   		   			 		   
		   ((then=? (car L)) (cond ((= cpt-else 1)
				       (error "if: then after else near :" L)))
		                     (cond ((= cpt-then 1)
				       (error "if: 2 then inside near:" L)))
		                     (set! cpt-then (+ 1 cpt-then))
		                     (parse-if-args (cdr L))) ; recurse
		   
		   ((else=? (car L)) (cond ((= cpt-else 1)
				       (error "if: 2 else inside near:" L)))
		                     (set! cpt-else (+ 1 cpt-else))
		                     (parse-if-args (cdr L))) ; recurse

		   
		   ((and (>= cpt-then 1) (= cpt-else 0)) (insert-set! (car L) L-then)
		                                         (parse-if-args (cdr L))) ; recurse

		   
		   ((>= cpt-else 1) (insert-set! (car L) L-else)
		                    (parse-if-args (cdr L)))  ; recurse
		   
		   (else ; start with 'then' directives but without 'then' keyword !
		    ;; i allow this syntax but this is dangerous:  risk of confusion with regular scheme syntax
		    
		    (insert-set! (car L) L-then)
		    
		    (set! cpt-then 1)
		    (parse-if-args (cdr L))))) ; recurse
	    
	    (define Lr (cdr Largs)) ; list of arguments of 'if' without the test
						    
	    (parse-if-args Lr) ; call the parsing of arguments
	    
	    (cond ((null? L-then) #`(cond ((not #,test)
					   (let ()
					     #,@L-else))))
		  ((null? L-else) #`(cond (#,test
					   (let ()
					     #,@L-then))))
		  (else ;; `(if-scheme ,test
			;; 	    (let ()
			;; 	      ,@L-then)
			;; 	    (let ()
			;; 	      ,@L-else)))))))
		   #`(cond  (#,test (let ()
				      #,@L-then))
			    (else
			     (let ()
			       #,@L-else)))))))))


) ; end library


;; /Applications/Racket\ v8.13/bin/plt-r6rs --install declare.scm 


#!r6rs

(library (declare)

  (export declare)

  (import (rnrs base (6)))

;; (declare ls dyn) ;; declare multiple variables

(define-syntax declare
  (syntax-rules ()
    ((_ var1 ...) (begin
		      (define var1 '())
		      ...))))


) ; end library
#!r6rs


;; /Applications/Racket\ v8.13/bin/plt-r6rs --install insert.scm


(library (insert)

  (export insert
	  insert-set!)
  
  (import (rnrs base (6)))
  
  


;; library procedures and macro
(define insert cons)

;; insert and set 
(define-syntax insert-set!
  (syntax-rules ()
    ((_ expr var)
     (set! var (insert expr var)))))

) ;; end module declaration
;; installation:

;; plt-r6rs --install syntax.scm


#!r6rs

(library (syntax)
  
  (export datum=?  
	  member-syntax
	  ;;member-normal&syntax
	  )
  
  (import (rnrs base (6))
	  (rnrs syntax-case (6))
	  (only (srfi :1) any member)
	  (only (racket) syntax?))


  ;; racket does not allow to syntax->datum an object not being (syntax something)
  (define (datum=? obj1 obj2)

    (cond ((and (syntax? obj1) (syntax? obj2))
	   (eq? (syntax->datum obj1)
		(syntax->datum obj2)))
	  ((and (syntax? obj1) (not (syntax? obj2)))
	   (eq? (syntax->datum obj1)
		obj2))
	  ((and (not (syntax? obj1)) (syntax? obj2))
	   (eq? obj1
		(syntax->datum obj2)))
	  (else
	   (eq? obj1 obj2))))
	  

;; Welcome to DrRacket, version 8.13 [cs].
;; Language: r6rs, with debugging; memory limit: 8192 MB.
;; > (define op-lst (list #'* #'+ #'- #'/))
;; > (member-syntax #'+ op-lst)
;; #t



;; (member-syntax '+ '(- + / *))
;; #t
;; (member-syntax + (list - + / *))
;; #t
;; (member-syntax + (list - / *))
;; #f
;; (member-syntax '+ '(- / *))
  ;; #f

 ;; > (member-syntax #'+ (list - + / *))
;;#f

  (define (member-syntax x lst)
    (any (lambda (y)
	   (datum=? x y))
	 lst))


  ;; (define (member-normal&syntax x lst)
  ;; (or (member x lst)
  ;;     (member-syntax x lst)))



) ; end library



the error is on single example:

Welcome to DrRacket, version 8.13 [cs].
Language: r6rs, with debugging; memory limit: 8192 MB.
> (if #t 7)
if : parsed-args=.#<syntax:Users/mattei/Library/Racket/8.13/collects/if-parser/main.ss:111:22 (cond (#t 7))>
. ../../../../Library/Racket/8.13/collects/if-parser/main.ss:111:23: cond: unbound identifier;
 also, no #%app syntax transformer is bound
  context...:
  other binding...:
  context at layer 1...: in: cond

not so fun :frowning:

even if rewritting some code in pure Racket should solve the problem as i suppose it is tied to r6rs.

regards,

Damien

i add a screenshot of both code and output with full syntax info:

here is a solution:



#!r6rs


;; /Applications/Racket\ v8.13/bin/plt-r6rs --install if-then-else.scm
;; [installing /Users/mattei/Library/Racket/8.13/collects/if-then-else/main.ss]
;; [Compiling /Users/mattei/Library/Racket/8.13/collects/if-then-else/main.ss]



(library (if-then-else) ; R6RS

  (export if)
  
  (import (rnrs base (6))
	  (rnrs syntax-case (6))
	  ;;(only (racket) syntax-case)
	  (for (rnrs base (6)) expand) ; import at expand phase (not run phase)
	  (for (rnrs syntax-case (6)) expand)
	  (for (only (srfi :1) third) expand)
	  (for (declare) expand)
	  (for (insert) expand)
	  (for (syntax) expand)
	  ;;(for (if-parser) expand)
	  ;;(if-parser)
	  (for (only (rnrs io simple (6)) display newline) expand))

  


(define-syntax if
  
  (lambda (stx)
    
    (syntax-case stx (then else)
      
      ((if tst ...)

       (with-syntax ((parsed-args  ;;#'(cond (#t 3))))

		      (let* ((then=? (lambda (arg)
				       (or (datum=? arg 'then)
					   (datum=? arg 'THEN))))
			     
			     (else=? (lambda (arg)
				       (or (datum=? arg 'else)
					   (datum=? arg 'ELSE))))

			      (call-parse-if-args-syntax

			      (lambda (Largs) ; Largs = (test e1 ...)

							  ;;(display "Largs=") (display Largs) (newline)
							  (define lenL (length Largs))

							  (declare test e1)
							  
							  (cond ((< lenL 2)
								 (error "if: too few arguments:" Largs)))

							  (set! test (car Largs))
							  (set! e1 (cadr Largs))

							  
					; deal with the old 2 args 'if' but modified
							  (cond ((and (= lenL 2) (then=? e1))
								 (error "if: syntax error,found (if test then) only: near " Largs))
								((and (= lenL 2) (else=? e1))
								 (error "if: syntax error,found (if test else) only: near " Largs))
								((= lenL 2) #`(cond (#,test #,e1))) ; (if test e1)
								
								((and (= lenL 3) (then=? e1)) #`(cond (#,test ; (if test then e2)
												       #,(third Largs))))
								((and (= lenL 3) (else=? e1)) #`(cond ((not #,test) ; (if test else e2)
												       #,(third Largs))))
								((= lenL 3) #`(cond (#,test #,e1)
										    (else #,(third Largs))))

								(else

								 (let ()
								   (define L-then '())
								   (define L-else '())
								   (define cpt-then 0)
								   (define cpt-else 0)
								   
								   (define (parse-if-args L)
								     
								     (cond ((null? L) (set! L-then (reverse L-then))
									    (set! L-else (reverse L-else)))
		   		   			 		   
									   ((then=? (car L)) (cond ((= cpt-else 1)
												    (error "if: then after else near :" L)))
									    (cond ((= cpt-then 1)
										   (error "if: 2 then inside near:" L)))
									    (set! cpt-then (+ 1 cpt-then))
									    (parse-if-args (cdr L))) ; recurse
									   
									   ((else=? (car L)) (cond ((= cpt-else 1)
												    (error "if: 2 else inside near:" L)))
									    (set! cpt-else (+ 1 cpt-else))
									    (parse-if-args (cdr L))) ; recurse

									   
									   ((and (>= cpt-then 1) (= cpt-else 0)) (insert-set! (car L) L-then)
									    (parse-if-args (cdr L))) ; recurse

									   
									   ((>= cpt-else 1) (insert-set! (car L) L-else)
									    (parse-if-args (cdr L)))  ; recurse
									   
									   (else ; start with 'then' directives but without 'then' keyword !
									    ;; i allow this syntax but this is dangerous:  risk of confusion with regular scheme syntax
									    
									    (insert-set! (car L) L-then)
									    
									    (set! cpt-then 1)
									    (parse-if-args (cdr L))))) ; recurse
								   
								   (define Lr (cdr Largs)) ; list of arguments of 'if' without the test
								   
								   (parse-if-args Lr) ; call the parsing of arguments
								   
								   (cond ((null? L-then) #`(cond ((not #,test)
												  (let ()
												    #,@L-else))))
									 ((null? L-else) #`(cond (#,test
												  (let ()
												    #,@L-then))))
									 (else ;; `(if-scheme ,test
									  ;; 	    (let ()
									  ;; 	      ,@L-then)
									  ;; 	    (let ()
									  ;; 	      ,@L-else)))))))
									  #`(cond  (#,test (let ()
											     #,@L-then))
										   (else
										    (let ()
										      #,@L-else))))))))))
			

			     )
			     
			    
			(call-parse-if-args-syntax #'(tst ...)))))

		     (display "if : parsed-args=") (display #'parsed-args) (newline)
		     #'parsed-args)))))
		    

) ; end module

seems the syntax transformer that generate a syntax must be all in the same file , probably because the syntax is described relatively to the module file (when it is from another file the bindings are unbounds) but i do not understand all...

when all is in the same file and inside the (with-syntax ...) block it is ok otherwise it fails.

all the 'syntax info' must be relative to if-then-else module:

Welcome to DrRacket, version 8.13 [cs].
Language: r6rs, with debugging; memory limit: 8192 MB.
> (if #t 7)
if : parsed-args=.#<syntax:Users/mattei/Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/if-then-else.scm:86:78 (cond (#t 7))>
7
> (define x 7)
> (if #t x)
if : parsed-args=.#<syntax:Users/mattei/Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/if-then-else.scm:86:78 (cond (#t x))>
7

> (if #t then 1 x else 3 4)
if : parsed-args=.#<syntax:Users/mattei/Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/if-then-else.scm:151:76 (cond (#t (let () 1 x)) (else (let () 3 4)))>
7

:smiley:

No, that's not correct.

The problem is that your (if-parser) library does not import any bindings at phase level -1 (in Racket, we call this the template phase level), so the syntax objects created at phase level 0 (i.e. the run phase level) in the (if-parser) module have no bindings in scope. You can fix this by changing:

(import (rnrs base (6)))

to:

(import (for (rnrs base (6))
             run
             (meta -1)))

and likewise for any other imports that should be in scope in syntax objects.

I strongly encourage you not to use plt-r6rs --install to install libraries.

Instead, using the Racket package system will let you manage updates, dependencies, and distribution. It will also make development easier, as you can simply edit files in place. Additionally, when asking for help, you could link to a Git repository from which your code could be easily installed.

Using Racket's package system would also encourage (though not strictly require) using naming conventions followed by both the Racket and wider Scheme communities: When working on a project, instead of creating many libraries like (if-then-else), (if-parser), (declare), (syntax), etc. at the top level of the library namespace, group libraries under a single top-level name, e.g. (Scheme+ if-then-else), (Scheme+ if-parser), (Scheme+ declare), etc.

To create a package, create a file named info.rkt with contents like this:

#lang info

(define pkg-name "Scheme-PLUS") ; "+" not allowed in package names
(define collection "Scheme+")
(define pkg-desc "Scheme+ for Racket")
(define version "9.1")
(define pkg-authors '(damien))
(define license 'GPL-3.0-or-later)

(define deps
  '("base"
    "r6rs-lib"))
(define build-deps
  '())

Place files like if-then-else.sls (or .ss, .rkt, .mzscheme.sls, or .mzscheme.ss, but note that .scm is not supported for use from Racket's R6RS implementation) in the same directory as the info.rkt file. In that directory, run raco pkg install --name Scheme-PLUS . (you can omit --name Scheme-PLUS if the directory name is the same as the package name). You now have a package! You can import your libraries using (import (Scheme+ if-then-else)) etc. If you want to create a library used as (import (Scheme+)), put it in a file named main.sls. You can recompile everything in your package by running raco setup Scheme+. Running raco pkg install or raco setup may warn you about other package dependencies you should list in your info.rkt file.

3 Likes

yes it works now this way too.
I read the 'template' syntax document, but it is long and i'm not english fluent so all the concept are not easy to understand for me. So i learn it by practising and coding.

the R6RS working library header for 'if-parser' is now this:

(library (if-parser) ; R6RS

  (export then=?
	  else=?
	  call-parse-if-args-syntax)
  
  (import (rnrs base (6))
	  (for (rnrs base (6))
             run
             (meta -1))
	  
	  (rnrs syntax-case (6))
	  (only (srfi :1) third)
	  (declare)
	  (insert)
	  (syntax))

.....

this solution is very special to Racket/R6RS , in Guile and Kawa for example i was able to put all in the same file without being defined in the syntax transformer 'with-syntax' block, the codes looks like this:

;; guile code
(define-module (if-then-else)

  ;;#:use-module (guile)

  #:use-module (srfi srfi-1) ; first ,third
  #:use-module (insert)
  #:use-module (syntax)
  
  ;;#:replace ( if )
  #:export ( if )

  ) ;; end module declaration

.....

;; Kawa code
(define-library (if-then-else) ; R7RS

  (import (rename (kawa base) (if if-scheme)) ;; no more need as if-scheme replaced by cond
	  (srfi 1)
	  (insert)
	  (syntax))

  (export if)
 
....

as you suggest it i will make the code available online on github , i did not do it yet because the Racket/R6RS code of Scheme+ is not finished and i'm facing the dilemma to fork the code to have both a Racket/Scheme version and a Racket/Scheme/R6RS version because they are different and the both could be uselfull. I hope to fork it soon on github and commit the under development code.

Also the actual Racket/Scheme version is old and the new one will use less parsing and more modules, like the Kawa and Guile version but ,again, perheaps i should have written it first in Racket/Scheme instead of Racket/Scheme/R6RS. I wrongly thought that the new Racket/Scheme/R6RS version could directly replace the old Racket/Scheme version.

I used plt-r6rs because it was documented in racket r6rs lib and i experienced problem installing and desinstalling r6rs module with the GUI of Racket.

But also with plt-r6rs i was unable to deinstall module ,i just do :

rm -rf /Users/mattei/Library/Racket/8.13/collects/if-parser

I will try to use 'raco' now from command line, and of course info.rkt files which is already done in the old version:

The difference is that Racket's R6RS implementation uses "explicit phasing", whereas Guile and most other R6RS implementations use "implicit phasing" as proposed in a paper by Ghuloum and Dybvig. I was surprised how limited the coverage of this topic in the actual report was when I went looking just now. This paragraph from the end of report section 7.2, "Import and export levels", permits implementations to adopt "implicit phasing":

An implementation may distinguish instances/visits of a library for different phases or to use an instance/visit at any phase as an instance/visit at any other phase. An implementation may further expand each library form with distinct visits of libraries in any phase and/or instances of libraries in phases above 0. An implementation may create instances/visits of more libraries at more phases than required to satisfy references. When an identifier appears as an expression in a phase that is inconsistent with the identifier's level, then an implementation may raise an exception either at expand time or run time, or it may allow the reference. Thus, a library whose meaning depends on whether the instances of a library are distinguished or shared across phases or library expansions may be unportable.

Rationale section 7.5, "Instantiation and initialization", adds:

Opinions vary on how libraries should be instantiated and initialized during the expansion and execution of library bodies, whether library instances should be distinguished across phases, and whether levels should be declared so that they constrain identifier uses to particular phases. This report therefore leaves considerable latitude to implementations, while attempting to provide enough guarantees to make portable libraries feasible.

2 Likes

yes interpretation and implementation can cause some problem with portability.

For the modularity i'm using this info.rkt file now:

#lang info

(define pkg-name "Scheme-PLUS-for-Racket-R6RS") ; "+" not allowed in package names
(define collection "Scheme+")
(define compile-omit-paths '("tmp" "tmp2"))
(define pkg-desc "Scheme+ for Racket R6RS")
(define version "9.1")
(define pkg-authors '(mattei))
(define license 'GPL-3.0-or-later)

(define deps
  '("base"
    "r6rs-lib"
    "srfi-lib"
    "sci"))
;;"reprovide-lang-lib"))

(define build-deps
  '())

i'm moving all .scm file to .scm files and (import (Scheme+ name-of-sub-lib) ....

it will take a few hours or days if all goes well:

/Applications/Racket\ v8.13/bin/raco pkg install --name Scheme-PLUS-for-Racket-R6RS
Linking current directory as a package
raco setup: version: 8.13
raco setup: platform: aarch64-macosx [cs]
raco setup: target machine: tarm64osx
raco setup: installation name: 8.13
raco setup: variants: cs
raco setup: main collects: /Applications/Racket v8.13/collects/
raco setup: collects paths: 
raco setup:   /Users/mattei/Library/Racket/8.13/collects
raco setup:   /Applications/Racket v8.13/collects/
raco setup: main pkgs: /Applications/Racket v8.13/share/pkgs
raco setup: pkgs paths: 
raco setup:   /Applications/Racket v8.13/share/pkgs
raco setup:   /Users/mattei/Library/Racket/8.13/pkgs
raco setup: links files: 
raco setup:   /Applications/Racket v8.13/share/links.rktd
raco setup:   /Users/mattei/Library/Racket/8.13/links.rktd
raco setup: main docs: /Applications/Racket v8.13/doc
raco setup: --- updating info-domain tables ---                    [19:04:04]
raco setup: updating: /Users/mattei/Library/Racket/8.13/share/info-cache.rktd
raco setup: --- pre-installing collections ---                     [19:04:04]
raco setup: --- installing foreign libraries ---                   [19:04:04]
raco setup: --- installing shared files ---                        [19:04:04]
raco setup: --- compiling collections ---                          [19:04:04]
raco setup: --- parallel build using 8 jobs ---                    [19:04:04]
raco setup: 7: idle
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 100%
raco setup: --- creating launchers ---                             [19:04:05]
raco setup: --- installing man pages ---                           [19:04:05]
raco setup: --- building documentation ---                         [19:04:05]
raco setup: --- installing collections ---                         [19:04:07]
raco setup: --- post-installing collections ---                    [19:04:07]

it also works with GUI packager

i just have, as you said, to rename .scm file to .sls file

strange name .sls google throw me to Salt state files :smiley:
from https://saltproject.io/

again some name not really portable...

I believe .sls stands for Scheme Library Source. You might also see .sps for Scheme Program Source. AIUI these are variants of the older .ss for Scheme Source.

Invoking guile --r6rs will enable support for .sls in Guile's load path … but, yes, this is a microcosm of the experience of trying to write portable Scheme.

1 Like

unfortunately i have been warn to not use Guile R6RS module features due to bugs in the export bindings features but this is out of topic. So Scheme+ is modular in Guile modules,not R6RS syntax, and that is well like that.

again some complication:

i can run the if-then-else.sls in REPL but i cannot use it in a module, if i use this module:

;; r6repl.rkt


#!r6rs


(library (r6repl)

  (export)

  (import (Scheme+ if-then-else))

)

tha actual ,under development , R6RS version of Scheme+ is available here:

the error i got is :

Welcome to DrRacket, version 8.13 [cs].
Language: r6rs, with debugging; memory limit: 128 MB.
. module: identifier already required for label
  also provided by: (lib "Scheme+/if-then-else.sls") in: if

Interactions disabled: r6rs does not support a REPL (no #%top-interaction)

at the bottom of the GUI windows i have too:

r6repl.rkt:11:2: module: identifier already required for label
  at: if
  in: (lib "Scheme+/if-then-else.sls")
  also provided by: (lib "Scheme+/if-then-else.sls")
  #(59 647)

i understand R6RS dislike i redefine 'if'

i found the bug:

i imported 'if' in the macro environment at a phase when i was redefining 'if' ... not a good idea... but why was it working in R6RS REPL ? i do not really know.

;;(for (rnrs base (6)) expand) ; import at expand phase (not run phase)
   (for (except (rnrs base (6)) if) expand)

except solve the problem

Welcome to DrRacket, version 8.13 [cs].
Language: r6rs, with debugging; memory limit: 128 MB.
> (if #t then 7)
if : parsed-args=.#<syntax:if-parser.sls:117:41 (cond (#t 7))>
7

should be good this time...

also this works:

 (rename (rnrs base (6)) (if if-scheme)) expand)

the section 7.2 is very important:

https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-10.html#node_sec_7.2

it explain the need of negative index :astonished: for phase levels
but is missing of examples, i only get a few info about it here. Decorator in Python can be hard to understand too when one make complex decorators. I'm self questioning if Rhombus that is based on Racket as kept such system and how it is expressed in this language....