Search code examples
scalafloating-pointliteralsread-eval-print-loopscala-repl

Error with floating point literal in Scala REPL


The definiton for floating point literal in Scala is

floatingPointLiteral  ::=  digit {digit} ‘.’ digit {digit} [exponentPart] [floatType]
                        |  ‘.’ digit {digit} [exponentPart] [floatType]
                        |  digit {digit} exponentPart [floatType]
                        |  digit {digit} [exponentPart] floatType
exponentPart          ::=  (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit}
floatType             ::=  ‘F’ | ‘f’ | ‘D’ | ‘d’

When I try to input floating point literal that starts with a dot I get an error:

scala> .123
        ^
   error: ';' expected but double literal found.

If is assign such literal to some variable everything is fine

scala> val x = .123
x: Double = 0.123

Why it behaves like that?


Solution

  • Probably the quote you pasted is from the Syntax Summary.

    Before we answer your question, let's notice the following:

    scala> 1.213
    res1: Double = 1.213
    

    So the issue here is not the floating point, but the fact that the expression starts with a dot. It makes the console, just like a regular Scala program, to evaluate the expression on the last object calculated.

    Let's do an example:

    scala> val d = 1.123
    d: Double = 1.123
    
    scala> .equals(1.123)
    res10: Boolean = true
    
    scala> .equals(1.123)
    res11: Boolean = false
    
    scala> .toString
    res12: String = false
    

    As you can see, every new line, is a follow up of the previous. You can go back, for example:

    scala> res10
    res13: Boolean = true
    

    But the object in cache is the last result.

    In your example, probably the last successful run of your console was val x = .123, which put the last res as a Double. When you ran .123 you are starting another BlockStat. The lexer identifies it is a Block, and therefore expects a semi (which is a ;) between the different BlockStats.

    When starting a new console, it works as expected:

    scala> .123
    res0: Double = 0.123