justinethier/cyclone

Evaluating `1#` results in `#f`?

jpellegrini opened this issue ยท 8 comments

Hello,

cyclone> 1#
#f
cyclone> 2#2
#f
cyclone> 0.#
#f

The # symbol is usually meant to indicate zeros in inexact numbers:

gosh$ (+ 12# 1#)
130.0
stklos> 4##
400.0
> 5#  ;; Gambit
50.
> 3# ;; Chez
30.0
#;1> 10# ;; Chicken
100.0
scheme@(guile-user)> 9#
$1 = 90.0
1 ]=> 55#   ;; MIT
;Value: 550.

Although, as far as I can see, this is not part of R7RS. But Cyclone seems to return false whenever there's a # in a number (I'd expect it to either signal an error (as Chibi does) or follow the same behavior of other Schemes, although really, it doesn't seem to be part of the standard anyway).

Maybe this is a small glitch in the reader? Or, if this is some Cyclone extension that I don't know, I apologize.

This is part of older standards, for example R5RS section 6.2.4:

A numerical constant may be specified to be either exact or inexact by a prefix. The prefixes are #e for exact, and #i for inexact. An exactness prefix may appear before or after any radix prefix that is used. If the written representation of a number has no exactness prefix the constant may be either inexact or exact. It is inexact if it contains a decimal point, an exponent, or a # character in the place of a digit, otherwise it is exact.

This was changed in R7RS to remove the language regarding #:

A numerical constant can be specified to be either exact or inexact by a prefix. The prefixes are #e for exact, and #i for inexact. An exactness prefix can appear before or after any radix prefix that is used. If the written representation of a number has no exactness prefix, the constant is inexact if it contains a decimal point or an exponent. Otherwise, it is exact.

So there is no requirement to implement this behavior. But perhaps we could do better than simply returning #f.

Right now, Cyclone's reader uses string->number internally to parse numbers and returns the result directly.

It would probably be better to raise an error instead in cases where the reader cannot parse the number, such as 1#.

It would probably be better to raise an error instead in cases where the reader cannot parse the number, such as 1#.

But what about symbols that start with a number, such as 1A? Cyclone also parses these as #f, but the standard requires them to be read as symbols:

(define 1A -2) (+ 1A -3) => -5 in other Schemes

But (define 1A -2) results in Error: Invalid type: expected pair, found : #f in Cyclone.

That's a good edge case.

Chibi has trouble with this, too:

justin@ubuntu:~$ rlwrap chibi-scheme
> (define 1A 2)
ERROR on line 1: invalid numeric syntax: #\A
> 2
> ERROR on line 1: too many ')'s
> 1A
ERROR on line 2: invalid numeric syntax: #\A
> (define |1A| 2)
> 1A
ERROR on line 4: invalid numeric syntax: #\A
> |1A|
2

Compared with Cyclone:

cyclone> (define 1A 2)
Error: Invalid type: expected pair, found : #f
cyclone> (define |1A| 2)
ok
cyclone> 1A
#f
cyclone> |1A|
2

That said, we can probably do better here.

lassik commented

But what about symbols that start with a number, such as 1A? Cyclone also parses these as #f, but the standard requires them to be read as symbols:

R7RS does not require that. From the grammar:

<identifier> -> <initial> <subsequent>*
| <vertical line> <symbol element>* <vertical line>
| <peculiar identifier>

<initial> -> <letter> | <special initial>
lassik commented

More generally, tokens starting with a digit are not reliably read as symbols in Scheme.

R7RS does not require that. From the grammar:

My bad. It's usual for Scheme implementations to read those as symbols, but not required indeed! Sorry!

I see that commit 334787b fixes this! :) Cool!