Skip to content

damien-mattei/Scheme-PLUS-for-Racket

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scheme-PLUS-for-Racket

Scheme+ for DrRacket by Damien Mattei.

Install as a package with the package manager (could be a 24 hours delay from github.com to pkgs.racket-lang.org) or from Github source code.

The documentation is here (for Racket but generally works also for other Scheme implementations):

https://docs.racket-lang.org/Scheme-PLUS-for-Racket/index.html

An other but a bit outdated documentation is here: https://github.com/damien-mattei/Scheme-PLUS-for-Racket/blob/gh-pages/README.md

Designed to use with SRFI 105 Curly Infix reader for Racket.

Scheme+ schema

With Racket you do not need to define/declare a variable with the Scheme+ operator <+. Because the binding of the variable is autodetect you can simply set the variable with <- (or :=) and Scheme+ will do the job.

The Racket GUI can not display the line of error in a Scheme+ program. If you have to debug your source code you must generate a Scheme file from your Scheme+ file with curly-infix2prefix4racket and load the result file in Racket GUI. Then you will have all the debug information of Racket on the scheme file.Another solution is to simply copy/paste the pure Racket code generated by the SRFI 105 Curly Infix parser and run it like a normal Racket program. Again you will have all the information about errors with the true line number displayed. Another method is to use the Makefile provided (see docs).


Changes of version 17.1:

Fixes a bug in string slicing affecting only one of the multiple use with negative indexes , was a bad copy/paste from vector code used for string code: replaced now vector-ref by the good string-ref.

Now ok:

{"toto.txt"[-3 : -1]}

($bracket-apply$ "toto.txt" -3 : -1)
"tx"

Example update for subset sum problem, now find solutions, or approximation, using memoization and backtracking.

Changes of version 17.0:

Add another syntax for if inspired from Python (statement if test else statement2).

Examples:

(def+ (foo)
    ("test positif" if ((#f or #f) and #t) else "test negatif"))

(foo)
"test negatif"
{"test positif" if ((#f or #f) and #t) else "test negatif"}

(if (and (or #f #f) #t) "test positif" "test negatif") ; result of parsing

"test negatif"

Changes of version 15.8:

Changes for SRFI 105 for Racket version 12.7: provide some necessary exported names.


Changes of version 15.7:

Documented define+ and define. Updated documentation according to SRFI 105 REPL removal of #<eof> display.


Changes of version 15.4:

Example of documentation updated about def+ and in introduction.


Changes of version 15.3:

Example of documentation updated about lambda+.


Changes of version 15.2:

lambda+ allows return but not return-rec.


Changes of version 15.1:

Add lambda+ :

(define foo (lambda+ () 7))
	(foo)
	7

> (define foo (lambda+ () (return (3 * 5 + 2))
	                       'not_good))
(define foo (lambda+ () (return (3 * 5 + 2)) 'not_good))
#<eof>
> (foo)
(foo)
17
#<eof>




(define x 3)


#<eof>
> (define foo (rec bar (lambda+ ()
                                (when (x = 3)
                                  {x := x + 1}
                                  (display "super!")(newline)
                                  (bar))
                                (return (3 * 5 + 2))
                                'not_good)))


(define foo
  (rec
   bar
   (lambda+
    ()
    (when (x = 3) (:= x (+ x 1)) (display "super!") (newline) (bar))
    (return (3 * 5 + 2))
    'not_good)))


#<eof>
> (foo)


(foo)
super!
17


#<eof>
>


Changes of version 15.0:

A few optimization on [ ] and assignment of containers (vectors,...).



Changes of version 14.8:

Updated link to documentation in README.



Changes of version 14.7:

Example updated.(ssigma-approx-solution-list-memo in SssDyna+.rkt use memoization)


Changes of version 14.5:

Example updated.(ssigma-fast-approx-solution-condx-list in SssRec+.rkt)


Changes of version 14.3:

Examples updated.

Bug correction: <+ which is almost never used with Racket was no more working at least since version 14.2, this would have above all be a problem when upgrading other Scheme+ implementation other than Scheme+ for Racket.


Changes of version 14.2:

Documentation in Racket package

Added Makefile example in doc.

Infix expression parsing is enhanced.When the parser is not able to know all the operators for precedence at parser stage it passes the job to the runtime stage. Rationale: when an operator is not directly readable but results of the evaluation at runtime of a procedure result or a symbol then the infix to prefix with operator precedence can not do the job at pre-parsing stage in SRFI-105 ,it is then forced to prepare the job and pass it at runtime. This is done by inserting in the code a sequence of instructions that will be evaluated at runtime at a moment when more syntax is evaluated. This give to the infix notation the same power than prefix one: the ability to evaluate the operands and apply the operators with precedence in all the situations.Note that prefix notation has not to do this because the parenthesis ( ) remove the need to apply operator precedence. Example,in this simple code the sign1 and (sign2) are not know at parsing stage but result of a later evaluation giving a sole sign for number 7:

> (define sign1 -)

(define sign1 -)

#<eof>
> (define (sign2) +)

(define (sign2) +)

#<eof>
> {sign1 (sign2) 7}
;; the code below is generated by the parser
(!*prec-generic-infix-parser-runtime
 (list sign1 (sign2) 7)
 (lambda (op a b) (op a b)))
 
-7 ; the result

This version do a runtime evaluation of operators,signs,in/equalities symbols when needed at runtime.
(define (tre) 3)
(define (due) 2)
(define (multiply) *)
(define (minus) -)
(define (quattro) 4)
(define (cinque) 5)
;; the code below is generated by the parser
(!*prec-generic-infix-parser-runtime
   (list (tre) (multiply) (due) (minus) (quattro))
   (lambda (op a b) (op a b)))

2 ;  the result

(define (inferior-or-equal) <=)
(define (inferior-strict-or-equal) (inferior-or-equal))
(define (three) 3)
(define (inferior) <)
{2 (inferior) (three) (inferior-strict-or-equal) 4}
;; the code below is generated by the parser
(!*prec-generic-infix-parser-runtime
  (list 2 (inferior) (three) (inferior-strict-or-equal) 4)
  (lambda (op a b) (op a b)))

#t ; the result

> {2 (inferior) (three) (inferior-strict-or-equal) 4 = 2}


(!*prec-generic-infix-parser-runtime
  (list 2 (inferior) (three) (inferior-strict-or-equal) 4 = 2)
  (lambda (op a b) (op a b)))
  
;; some debug info:
;; !*prec-generic-infix-parser-runtime launching in/equalities-state-1
;; !*prec-generic-infix-parser-runtime after in/equalities : deep-terms=(2 #<procedure:<> 3 #<procedure:<=> 4 #<procedure:=> 2)

;; !*prec-generic-infix-parser-runtime : multiple in/equalities detected
;; !*prec-generic-infix-parser-runtime : in-eq-terms=(#<procedure:&&> (#<procedure:<> 2 3) (#<procedure:<=> 3 4) (#<procedure:=> 4 2))

#f ; result

#<eof>

Note in the debug info the && procedure that replace the and macro because we are at runtime,we apply recursively and we can not do this on a macro,thus the need of a procedure.


Complex number superscripted: as i does not exist in superscript and I exist but is not mathematical convention we also can use j which exist in superscript set char and which is electrical convention for pure imaginary number i.


The examples have been updated.
Correct error in documentation about overloading [ ] and some typos.

Added Qi operator in the documentation.

Debugged online doc of racket package system.



Changes of version 12.1:

Package requires now SRFI-105 for Racket for the scribble documentation that contains macros that check the dependancies and make the build process fail otherwise on the Racket Package Server. This should solve the problem of compilation on the Racket Package Server that failed just because of the documentation. This problem was not impacting a manual installation from Github source code in the DrRacket GUI Package Manager.

Changes of version 11.8:

Test to debug the documentation problem with the Racket package server

Changes of version 11.7:

Removed debug info display that should have been commented before releasing the previous version. Some new doc will be commited, but it should not be as it is work in progress.

Changes of version 11.5:

Correct a bug introduced in v11.3: in def+ source code it is no more $nfx$ that should be used but instead $nfx$-rec. Rationale: def+ allows both infix and prefix expression in normal parenthesis ( ) by autodetection and this feature is mainly done by $nfx$-rec, at contrary $nfx$ is now generally preferred for expressions that should be only infix,for example the ones in curly parenthesis { }.

Changes of version 11.4:

Correct a bug introduced in v11.3 by commenting 2 lines of code that where indeed usefull for multiple in/equalities, now works again.

Examples:

{#t and (#f or 1 < 2 <= 2)}
(and #t (or #f (and (< 1 2) (<= 2 2)))) ; displayed parsed code
#t

#<eof>

{0 ≤ 1 ≤ 2 and #f}
(and (≤ 0 1 2) #f)
#f

Changes of version 11.3:

Remove the need of pragma for strict SRFI-105 mode by autodetecting the strict syntax and the required application in context.

Example:

(define (cinque) 5)
(define (minus) -)
{(cinque) + {(cinque) (minus) 3}}
(+ (cinque) ((minus) (cinque) 3)) ; parsed result displayed
7

Better detection of infix mode allowing some sort of expressions to be detected as infix even if we have procedures as operands:

(define (cinque) 5)
(define (tre) 3)
(define (due) 2)
{(cinque) * (tre) - (due)}

(- (* (cinque) (tre)) (due)) ; parsed result displayed
13

#<eof>

Changes of version 11.0:

Less syntax transformers used.Infix to prefix with operator precedence is now done by default in the reader parser stage. This result in better compatiblity with other language that change the syntax, for example it should be compatible with Qi (even if not tested).Also the external parsing allows extended features with superscripted syntax with not only constants but variables too. Example:

(define (foo) (define n 3) {3 ⁻²·⁽ⁿ⁻⁴⁾})
(foo)
9

Changes of version 10.8:

Only internal changes in code. Prepare for a greater upgrade.Moved some n-arity code use from nfx to infix-with-precedence-to-prefix module. Updated relatively with the code changes the personal internal documentation design of Scheme+ which is hosted in the Kawa Scheme+ project for historical reason.

Changes of version 10.7:

No change in API but i removed depandancies between Scheme+ and SRFI-105-curly-infix that was alternating-parameters procedure. The procedure is now duplicated like it was in old versions. This is not elegant but remove dependancies that would lead in future version when i will use more scheme+ procedure in SRFI-105 parser in fatal circular dependancies.

Changes of version 10.5:

Correct some typos about assignment operators.(strangely a line was commented)

Check that infix code is correct before parsing it to prefix.(previously some wrong code could have been truncated by the parser to the most great valid expression)

Changes of version 10.4:

Correct a bug that ommiting assignment operators (<- := -> =:) from being correctly detected as infix in the case the first argument is a procedure which is arising with Racket's contracts.

Example:

{positive-integer? -> (listof positive-integer-triplet?)}

The bug was also preventing a known scheme procedure to be re-assigned (note that by definition procedure are immutable in a Racket module), example now working:

(define (my-cons a b) (display "hello from my-cons") (newline) (cons a b))
(declare a-new-cons)
{a-new-cons := my-cons}
(a-new-cons "hello" "world")
hello from my-cons
'("hello" . "world")

Note for reader: i apologize because perheaps this summary is not clear. At least for Racket's contract i have to update Scheme+ and the pragmas code of SRFI-105.

Deprecate range.rkt module providing in-range and reversed as in-range is already existing for stream in Racket and was conflicting and used as list which is already done by range from racket/list. reversed was just reverse and was just named the same way as in Python for porting code.

Added some more examples and update code examples according to this release.

New feature of version 10.3:

Allow multiples In/equalities in expression, examples:

(when {0 ≤ x0 ≤ xws  and 0 ≤ x1 ≤ xws and
       0 ≤ y0 ≤ ywsp and 0 ≤ y1 ≤ ywsp}
     (send dc draw-line
		   x0 y0
		   x1 y1))

{#t and (#f or 1 < 2 <= 2)}
#t

{#t and (#f or 1 < 2 < 2)}
#f

(in/equalities-state-1 '(x + 2 < 3 and a + 1 < 3 * b <= c - 1 < d + 2 or y * 3 > 4 and f and 1 < 2 < 3)  '() '() '()  '())
'(x + 2 < 3 and ((a + 1) < (3 * b) <= (c - 1) < (d + 2)) or y * 3 > 4 and f and (1 < 2 < 3))

I present some features of scheme+ for racket that allow the melting in an expression of both infix and prefix sub-expressions. There is a disambiguating algorithm based on a finite state machine. Note that some expression would need to be detected not only at the syntax parsing but at the execution stage.(which is not yet implemented,will be in future version).

This feature allow to get rid of use of special { } curly brackets as it is now auto-detected by scheme syntax transformers, and so you just have to use normal ( ) parenthesis. But then you have to use a special definition procedure called define+ but i have modified in scheme+ the classic define of scheme to integrate in it the define+ special feature, still with 100% compatibility with scheme. So you rarely have to use define+. As there is no more needs to use { } you can get rid of the use of #lang reader SRFI-105 if you just use the infix/prefix syntax, but if you want to use the indexing via [ ] yo still need the SRFI-105 parser.

Note that it could be strange to mix infix and prefix sub-expressions in an expression it is more logic to keep the same syntax in all the expression. It just could be possible because the algorithm is recursive and check the syntax for all the sub expressions, allowing the mix

Here is some concrete examples:

Note that i really prefer for infix definitions a syntax like {x := infix_expressions ...} instead of (define x infix_expressions ...)

Welcome to DrRacket, version 8.17 [cs].
Language: racket, with debugging; memory limit: 14000 MB.
> (require Scheme+)

Scheme+ v10.0 by Damien Mattei

(define x  3 * 5 + 2)
x
17

(define t  3 * (+ 2 4) - 1)
t
17

(define z  (3 + 1) * (2 * (+ 2 1) - (sin 0.3)) + ((* 2 5) - 5))
z
27.817919173354642

(define x  1 + 2 + 3)
x
6

(define k  10.0 - 3.0 - 4.0 + 1 - 5.0 * 2.0 ** 3.0 / 7.0 ** 3.0)
k
3.883381924198251

(define a 7)
(define b 3)
(define r  a * - b)
r
-21

(define s  3 ² + 2 · 3 · 5 + 5 ²)
 s
64

(define s  3 ² + 2 * 3 * 5 + 5 ²)
s
64

And here is a simple list of examples or piece of code tested or running REPL-SRFI-105-Racket.rkt :

Welcome to DrRacket, version 8.14 [cs].
Language: reader SRFI-105, with debugging; memory limit: 8192 MB.
SRFI 105 Curly Infix for Scheme+ v9.8
SRFI-105 Curly Infix parser for Racket Scheme and R6RS by Damien MATTEI
(based on code from David A. Wheeler and Alan Manuel K. Gloria.)

Possibly skipping some header's lines containing space,tabs,new line,etc  or comments.

SRFI-105.rkt : number of skipped lines (comments, spaces, directives,...) at header's beginning : 12

Parsed curly infix code result = 

(module repl racket (provide (all-defined-out)) (require Scheme+))

Scheme+ v10.0 by Damien Mattei

;; examples in REPL begins here:
{3 * (+ 2 4) - 1}
17

{(- 7 (3 * (+ 2 4) - 1))}
-10

{(3 + 1) * (2 * (+ 2 1) - sin(0.3)) + ((* 2 5) - 5)}
27.817919173354642
;; the above is in prefix : (+ (* (+ 3 1) (- (* 2 (+ 2 1)) (sin 0.3))) (- (* 2 5) 5))

(define n 7)
{2 * (- n 4)}
6

(define a 3)
(define b 5)
{n + (- b a)}
9


Here is a few more syntax available in this version of Scheme+ with SRFI-105 reader:

#lang SRFI-105
(require Scheme+)
(define (foo x y) {-4 · sin(x) + x · y ² - 5 · x / y})
(foo 1.23 3.4)
8.640021262861444

{2 ³}
8

{3 · (2 ³ - 1)}
21

{(2 ³) ⁴}
4096

(define+ (chaos p q d x0 y0)
  
  ;;(define a {2 * cos{2 * pi * p / q}}) ; or {2 * (cos {2 * pi * p / q})} or {2 * cos({2 * pi * p / q})}
  (define a   2 * (cos (2 * pi * p / q)))
  (define+ ksx  (√ ((2 + a) / 2)) ) ;; (sqrt {(2 + a) / 2})) ; or sqrt{{2 + a} / 2}
  {ksy := (√ ((2 - a) / 2))}    ; (sqrt {(2 - a) / 2})} ; or (define ksy (sqrt {{2 - a} / 2}))
  
  (stream-map (lambda (z)
                (match-let (((vector x y) z))
                  (vector ((ksx / (√ 2)) * (x + y))
			  {(ksy / (√ 2)) * ((- x) + y)})))
                  (stream-iterate (lambda (z)
                                    (match-let (((vector x y) z))
                                      (vector
                                       ;;((a * x) + y + (d * x) / (add1 (x ** 2))) ; infix left to right evaluation avoid extra parenthesis but is hard for humans
				       ((a * x) + y + (d * x) / (add1 (x ²)))
				       (- x))))
				  (vector x0 y0))))


(define+ (line-length x0 y0 x1 y1)
  (√ ((x1 - x0) ² + (y1 - y0) ²)))