Mutable mpair vs immutable pair, how to port code

hello again,

i have a serious problem porting code from Racket that use immutable list to r6rs at some point i got this error i do not understand and do not know how to solve:

<- : #'parsed-args=.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/assignment.sls:228:31 (list index)>
. . ../assignment.sls:236:27: mcdr: contract violation
  expected: mpair?
  given: #<syntax:/home/mattei/git/Scheme-PLUS-for-Racket-R6RS/assignment.sls:228:31 (list index)>

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

the error occurs in this part of code (the lines number are added in comments):

(with-syntax ((parsed-args
			    			     
			     #`(list #,@(parse-square-brackets-arguments-lister-syntax #'(index ...)))) ;; line 228

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

	 
	     (case (length (cdr #'parsed-args)) ; putting code here optimise run-time  line 236
			 
			     
			     ((0) 
			      
				  #'(assignment-argument-0 container expr))

			     ;; 1 argument in [ ]
			     ;; T[index]
			     ((1)
			     
				  #'(assignment-argument-1 container
							   (first parsed-args)
							   expr))



regards,

note: sometimes when i read scheme doc:
https://standards.scheme.org/corrected-r6rs/r6rs-Z-H-15.html
i feel humble :slightly_smiling_face:

The problem you are seeing is not actually because of mutable vs. immutable pairs. You are calling (cdr #'parsed-args), but #'parsed-args is a syntax object, not a pair (neither mutable pair nor an immutable pair).

I'm not entirely clear on what you want to do, but you may want to use let instead of with-syntax, to use syntax-case instead of dispatching on (length (cdr ❓)), and/or use syntax->datum somewhere.

For R6RS, libraries §12.2 says, “Wrapped syntax objects that are not identifiers may or may not be distinct from other types of values.” In Racket, wrapped syntax objects are distinct, and syntax objects tend to be wrapped.

It's unfortunate that the error is reported using the Racket name mcdr instead of the R6RS name cdr. The “realm” mechanism developed for Rhombus might enable improving the situation, if someone wanted to take that on.

yes i do not understand why Racket complains about mcdr , i even removed the (cdr ... code and it still complain about that.

I supposed the problem comes when merging / using in the same code R6RS and Racket (GUI, stream-list, etc...) code that use immutable list
i tried to use :

(compatibility mlist)

with no success

this is really a problem, i understand you propose to refactor the code but
this code takes me many weeks to set it up in Kawa and Guile and it used to work this way. I always tried when debugging in Kawa,Guile... 'let' and other ways.

What i will do is made a Racket version to see if the problem is always here, if not i will drop R6RS support.

But i'm not sure it is a problem with my library because a simple code that do not use my library have problem running:

(match-let ((`(,p ,q ,d ,x ,y ,n) datum))

will produce this error:

bracket-apply : #'parsed-args={.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/bracket-apply.sls:148:30 list> .#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 1>}
$nfx$ : parsed-args={.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 :=> .#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 index> {.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 +> .#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 index> .#<syntax:git/Scheme-PLUS-for-Racket-R6RS/examples/chaos+.rkt:1:6 1>}}
index=0
. . match-let: no matching clause for (mcons 1 (mcons 34 (mcons 5 (mcons 0.1 (mcons 0 (mcons 60000 '()))))))
> 

you see again the mcons , i suppose calling Racket features from R6RS is the problem.

i find also this on stackoverflow:

yes part of the problem comes from here, because if i add mlist->list to the code :

 (match-let ((`(,p ,q ,d ,x ,y ,n) (mlist->list datum)))

the program makes no error at this point ,it continues to another mutable pair error:

. . mcar: contract violation
  expected: mpair?
  given: '(#(0.09957341762950345 -0.009226835946330196) #(0.5891202753544278 -0.07304370468211024) #(2.8948983096965915 -0.3958855703479349) #(4.057083902560204 -1.040081590745382) #(4.434875941080433 -1.8269775535980202) #(4.431419628476375 -2.64856082973...

i will continue correcting the code like that....

one hour later....

i have to play with mutable and immutable list at many point of the code, and as r6rs report wrongly the problem:

. . ../assignment.sls:239:27: mcdr: contract violation
  expected: mpair?
  given: #<syntax:/home/mattei/git/Scheme-PLUS-for-Racket-R6RS/assignment.sls:231:31 (list index)>

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

it should not say, mcdr but cdr, this bugs should be corrected in racket/r6rs but i'm not sure there is a lot of support for r6rs , if i remember the R6RS language was proposed in Racket gui "choose language" many years ago but no more now...

ok here is what's look like the code now :

 (define im*data* (mlist->list *data*))
  
  (for-racket ([datum im*data*]) ; 'for-racket' is the original 'for' of Racket but renamed

	      (display "index=") (display index) (newline)

	      {imdatum <- (mlist->list datum)}
	    
	      (match-let ((`(,p ,q ,d ,x ,y ,n) imdatum))
	      
	      {imlst-points <- (stream->list
				(stream-take
				 (chaos p q d x y) n))}

	      (display "after imlst-points") (newline)
	      (display (mlist? imlst-points)) (newline)
	      {lst-points <- (list->mlist imlst-points)}
	      
	      (define max-norm-x-y (max-list-norm-x-y lst-points)) ; maximum

	      (display "after max-norm-x-y") (newline)

	      (when graphic-mode ; no memory overloading in this mode
		;; Make a frame by instantiating the frame% class
		{frm[index] ← (new frame% [label (format "Chaos+ ~a" index)]
				          [width xws]
				          [height yws])})


here we are at the heart of hard problem , i rewrote the library that define <- for R6RS , so why does it complains not having those mutable list in (list index) , as you say it is syntax , not list, but why it is syntax for Racket and not R6RS..... ok ok ok.... "fichu probleme" (damn problem) as we say in France...

:slightly_smiling_face: do not ask 'how?' but it works now...

i simplified the code took example on other part of code ( bracket-apply for [ ] , $nfx$ for infix) and noticed a variant of code more simple used many times with success:

(with-syntax
	     ;;(let-syntax
	     ;; (let
	     ((parsed-args

	       (cons #'list (parse-square-brackets-arguments-lister-syntax #'(index ...))))
	      ;;#`(list #,@(parse-square-brackets-arguments-lister-syntax #'(index ...))))
	      ;;(parse-square-brackets-arguments-lister-syntax #'(index ...)))

			    ) ; end definitions
			   
	   (display "<- : #'parsed-args=") (display #'parsed-args) (newline)
	   (display "<- : (list? #'parsed-args)=") (display (list? #'parsed-args)) (newline)
	   (display "<- : (mlist? #'parsed-args)=") (display (mlist? #'parsed-args)) (newline)
	   (display "<- : (length #'parsed-args)=") (display (length #'parsed-args)) (newline)

	   #'(assignment-next4list-args container parsed-args expr)))

the important point is the simple (cons #'list (parse-square-brackets-arguments-lister-syntax #'(index ...))) instead of the complex
#`(list #,@(parse-square-brackets-arguments-lister-syntax #'(index ...)))

i noticed it in the version of Kawa and Guile too:

i faced the problem with Guile and Kawa too , but it worked , i suppose should modify those code too

it is ok on some file, not on others...

i extracted the different case in another procedure as in other files:

(define (assignment-next4list-args container parsed-args expr) 

  	   (case (length parsed-args)
			       
			     ;; 0 argument in []
			     ;; T[]
			     ;; {v[] <- #(1 2 3)}
			     ;; > v
			     ;;'#(1 2 3)
			     ((0) 
			      ;;(begin
			      ;; 	  (display "<- case 0 : parsed-args=") (display parsed-args) (newline)
				  (assignment-argument-0 container expr));)  ; possible to have NO index

			     ;; 1 argument in [ ]
			     ;; T[index]
			     ((1)
			      ;;(begin
			       	;;  (display "<- case 1 : parsed-args=") (display parsed-args) (newline)
				  (assignment-argument-1 container
							 (first parsed-args)
							 expr));)

			     ;; 2 arguments in [ ]
			     ;; ex: T[i1 :] , T[: i2], T[i1 i2] , T[: :]   
			     ;; {#(1 2 3 4 5)[inexact->exact(floor(2.7)) :]}
			     ;; '#(3 4 5)
			     ((2)
			      ;; (begin
			      ;; 	  (display "<- case 2 : parsed-args=") (display parsed-args) (newline)
				  (assignment-argument-2 container
							 (first parsed-args)
							 (second parsed-args)
							 expr));)

			     ;; 3 arguments in [ ]
			     ;; T[i1 : i2] , T[i1 i2 i3] , T[: : s]
			     ((3)
			      ;; (begin
			      ;; 	  (display  "<- case 3 : 'parsed-args=") (display 'parsed-args) (newline)
				 
				  (assignment-argument-3 container					  
				  			 (first parsed-args)
				  			 (second parsed-args)
				  			 (third parsed-args)
				  			 expr));)
			     
			     ;; 4 arguments in [ ]
			     ;; T[: i2 : s] , T[i1 : : s] , T[i1 : i3 :] , T[i1 i2 i3 i4]
			     ((4)
			      (assignment-argument-4 container
						       (first parsed-args)
						       (second parsed-args)
						       (third parsed-args)
						       (fourth parsed-args)
						       expr))

			     ;; 5 arguments in [ ]
			     ;; T[i1 : i3 : s] , T[i1 i2 i3 i4 i5]
			     ((5)
			      (assignment-argument-5 container
						       (first parsed-args)
						       (second parsed-args)
						       (third parsed-args)
						       (fourth parsed-args)
						       (fifth parsed-args)
						       expr))

			     ;; more than 5 arguments in [ ]
			     ;; T[i1 i2 i3 i4 i5 i6 ...]
			     (else ; case
			      (assignment-argument-6-and-more container parsed-args expr))))

now it is ok to use in programs and in REPL:

> (define T (make-vector 5 0))
> {T[2] <- 7}

<- : #'(index ...) = (.#<syntax 2>)
<- : #'parsed-args=(.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/assignment.sls:241:23 list> .#<syntax 2>)
<- : (list? #'parsed-args)=#t
<- : (mlist? #'parsed-args)=#t
<- : (length #'parsed-args)=2
assignment.sls : assignment-argument-1
> T
'#(0 0 7 0 0)
> {T[2]}

bracket-apply : #'parsed-args=(.#<syntax:git/Scheme-PLUS-for-Racket-R6RS/bracket-apply.sls:148:30 list> .#<syntax 2>)
7
>

It is ok in R6RS/Racket, i should do a pure Racket version, that avoid the problem of mutable list...

doing it was as easy, clean and reliable as ....

https://www.youtube.com/watch?v=86ZnWc1B7W4

:slightly_smiling_face:

i will re-read ,check, and clean and uniform all version of code...