- Sagittarius (of course)
- Chibi Scheme
- Gauche
- Foment
July 28th 2014: Foment compiled on VC2010 has been added.
The purpose of this article is to show some corner cases of R7RS. Sagittarius is R6RS/R7RS and Chibi and Gauche are R5RS/R7RS implementation so there should be something but how much? So I've prepared this test script.
;; #!r7rs is supported only Gauche and Sagittarius... ;; #!r7rs (import (scheme base) (scheme write) (scheme read) (scheme file) (scheme inexact) (scheme lazy)) (define (print . args) (for-each display args) (newline)) ;; string ;; allow #\null in string? (print "String range") (write "abc\x0;def")(newline) ;; file ;; are binary and textual port separated? (print "Port separation") (define-syntax check-port (syntax-rules () ((_ opener reader data) (let ((in (opener data))) (guard (e (#t (print "ERROR: "(error-object-message e)) (close-input-port in))) (print 'opener ":" 'reader) (reader in) (close-input-port in)))))) ;; files (check-port open-binary-input-file read-char "r7rs-comp.scm") (check-port open-binary-input-file read-u8 "r7rs-comp.scm") (check-port open-input-file read-char "r7rs-comp.scm") (check-port open-input-file read-u8 "r7rs-comp.scm") ;; memory (check-port open-input-bytevector read-u8 #u8(0 1 2 3)) (check-port open-input-bytevector read-char #u8(0 1 2 3)) (check-port open-input-string read-u8 "abc") (check-port open-input-string read-char "abc") ;; error object (print "Error object") (define-syntax check-error (syntax-rules () ((_ pred expr) (guard (e (#t (print 'pred ":" (pred e)))) expr)))) (check-error error-object? (car 'a)) (check-error read-error? (read (open-input-string "#0#"))) (check-error file-error? (open-input-file "this doesn't exist.txt")) (define-syntax check (syntax-rules () ((_ expr) (guard (e (#t (print 'expr ":" (error-object-message e)))) (print 'expr ":" expr))))) ;; sqrt (print "Procedures") (check (sqrt 4)) ;; promise (print "Promise") (check (+ (delay (* 3 7)) 13))The script is constructed based on what I thought could be a corner case. Mostly port related procedures and error object. Then this is the output;
Sagittarius String range "abc\x0;def" Port separation open-binary-input-file:read-char ERROR: textual port required, but got #<file-binary-input-port r7rs-comp.scm> open-binary-input-file:read-u8 open-input-file:read-char open-input-file:read-u8 ERROR: "binary-port" required, but got #<transcoded-textual-input-port r7rs-comp.scm utf8-codec> open-input-bytevector:read-u8 open-input-bytevector:read-char ERROR: textual port required, but got #<bytearray-binary-input-port> open-input-string:read-u8 ERROR: "binary-port" required, but got #<string-textual-input-port> open-input-string:read-char Error object error-object?:#t file-error?:#t Procedures (sqrt 4):2 Promise (+ (delay (* 3 7)) 13):"number" required, but got (13 #<<promise> 0x80599100>) --- Chibi Scheme String range "abc\x00;def" Port separation open-binary-input-file:read-char open-binary-input-file:read-u8 open-input-file:read-char open-input-file:read-u8 open-input-bytevector:read-u8 open-input-bytevector:read-char open-input-string:read-u8 ERROR: not a binary port open-input-string:read-char Error object error-object?:#t read-error?:#t file-error?:#t Procedures (sqrt 4):2 Promise (+ (delay (* 3 7)) 13):invalid type, expected Number --- Gauche String range "abc\0def" Port separation open-binary-input-file:read-char open-binary-input-file:read-u8 open-input-file:read-char open-input-file:read-u8 open-input-bytevector:read-u8 open-input-bytevector:read-char open-input-string:read-u8 open-input-string:read-char Error object error-object?:#t read-error?:#t file-error?:#t Procedures (sqrt 4):2 Promise (+ (delay (* 3 7)) 13):operation + is not defined between 13 and #<promise 0x80445480>Following it the output from Foment
String range "abc^@def" Port separation open-binary-input-file:read-char ERROR: read-char: expected an open textual input port open-binary-input-file:read-u8 open-input-file:read-char open-input-file:read-u8 ERROR: read-u8: expected an open binary input port open-input-bytevector:read-u8 open-input-bytevector:read-char ERROR: read-char: expected an open textual input port open-input-string:read-u8 ERROR: read-u8: expected an open binary input port open-input-string:read-char Error object error-object?:#t file-error?:#t Procedures (sqrt 4):2 Promise (+ (delay (* 3 7)) 13):+: expected a numberHmmm, not much difference than I expected. The only difference is port related procedures. Gauche is the most tolerant then Chibi, Sagittarius is the strictest one. Well, Sagittarius is an R6RS implementation and it's required to be. Gauche's behaviour is a bit too flexible to me but still consistent. Chibi looks a bit tricky to me. It actually reject to pass texutal port to
read-u8
however read-char
accept binary port.Even though, R7RS explicitly says that implementation may reject
#\null
in strings however none of implementations does it. Interestingly, Foment doesn't support writing #\null
. So it writes as it is. It would be better to consider that it doesn't support properly or particially supported. So to write portable string library, users should not depend on null character.I thought error object could have some difference but not really (or the test script doesn't cover that much).
I was hoping one of the implementations (Chibi or Gauche though) have implicit forcing but the result was none of them.
The difference is small and it's avoidable if users are consistent. So if you write R7RS scripts and it could be run on Sagittarius, then most likely it would run on the other implementations.
No comments:
Post a Comment