[racket] Parsing Numbers
Hi all,
I've been playing with the number tower in Racket and I noticed it appears to
drift from the R5RS and R6RS standard. Now, I know the Racket rebrand grants PLT
Scheme to now drift from the standard, but I think this may actually be
unintentional. So let me know if I've misunderstood this.
Section 7.1.1 or R5RS [1] states:
"""
<number> -> <num2> | <num8> | <num10> | <num16>
The following rules for <num R>, <complex R>, <real R>, <ureal R>, <uinteger R>,
and <prefix R> should be replicated for R = 2, 8, 10, and 16. There are no
rules for <decimal 2>, <decimal 8>, and <decimal 16>, which means that numbers
containing decimal points or exponents must be in decimal radix.
"""
Section 4.2 of R6RS [2] states:
"""
The rules for <num R>, <complex R>, <real R>, <ureal R>, <uinteger R>, and
<prefix R> below should be replicated for R = 2, 8, 10, and 16. There are no
rules for <decimal 2>, <decimal 8>, and <decimal 16>, which means that number
representations containing decimal points or exponents must be in decimal radix.
"""
However, Racket accepts number representations with decimals or exponents [3].
Trying this out on other implementations of varying conformance, I see that SISC
[4], Bigloo [5] and Guile [6] don't allow this. Am I misunderstanding the
specification here or is this a bug or is Racket intentionally doing something
outside the standard?
Thanks for the help!
Ewan
[1]
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-10.html#%_sec_7.1.1
[2] http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-7.html#node_sec_4.2
[3] Here's what I put into Racket:
Welcome to Racket v5.0.
> 1.0
1.0
> 1e10
10000000000.0
> #o6
6
> #o60
48
> #o60.3 ;<===
48.375
> #b10
2
> #b10.10 ;<===
2.5
> #b10e10 ;<===
8.0
This doesn't seem correct. #o and #b shouldn't accept decimals or exponents. It
should either return two values as entering "> 1 1" would or it should yield an
error.
[4] Here's what I put into SISC 1.16.6:
#;> 1
1
#;> 1e10
1.0e10
#;> #o6
6
#;> #o60
48
#;> #o60.3
Error in read-code: error reading from port '#<character-input-port>':
unexpected token where number was mandatory.
---------------------------
To enable more detailed stack tracing, set the dynamic parameter
max-stack-trace-depth to a non-zero value, e.g. 16.
---------------------------
Some stack trace entries may have been suppressed. To see all entries set the
dynamic parameter suppressed-stack-trace-source-kinds to '().
#;> #b10
2
#;> #b10.10
Error in read-code: error reading from port '#<character-input-port>':
unexpected token where number was mandatory.
#;> #b10e10
Error in read-code: error reading from port '#<character-input-port>':
unexpected token where number was mandatory.
[5] Here's what I put into Bigloo (3.4a)
1:=> 1
1
1:=> 1e10
1.0e10
1:=> #o6
6
1:=> #o60
48
1:=> #o60.3
48
1:=> 0.3
1:=> #b10
2
1:=> #b10.10
2
1:=> 0.1
1:=> #b10e10
2
1:=> *** ERROR:eval:
Unbound variable (from top-level) -- e10
What bigloo does is more surprising at first since it's parsing the octal
#o60.3 as two numbers, #o60 and 0.3. And it's correct to yield an error with
#b10e10. But I think this is inline with the standard.
[6] Here's what Guile 1.8.7 says:
guile> 1
1
guile> 1e10
1.0e10
guile> #o6
6
guile> #o60
48
guile> #o60.3
ERROR: In procedure scm_lreadr:
ERROR: #<unknown port>:5:1: unknown # object
ABORT: (read-error)
guile> #b10
2
guile> #b10.10
ERROR: In procedure scm_lreadr:
ERROR: #<unknown port>:7:1: unknown # object
ABORT: (read-error)
guile> #b10e10
ERROR: In procedure scm_lreadr:
ERROR: #<unknown port>:8:1: unknown # object
ABORT: (read-error)