Why F# compiler gets into twist with seq{0L..-5L..-10L}?

f#

Solution

I agree that this is a bit odd behavior. It is generally recommended (although this is not strictly required by the specification) to write spaces around `..` and it works correctly in that case. So I'd recommend using:

seq { 0 .. -5 .. -10 }
seq { 0L .. -5L .. -10L }

Why is this behaving differently for `int` and `int64`? You may notice that when you write `1..-2` and `1L..-2`, Visual Studio colorizes the text differently (in the first case `..` has the same color as numbers, in the other case, it has the same color as `..` with spaces).

The problem is that when the compiler sees `1.`, it may mean a floating point value (`1.0`) or it may be a start of `1..`, so this case is handled specially. For `1L.`, this is not a problem - `1L.` has to be the beginning of `1L..`.

So, if you write `1..-5..-10`, the compiler uses the special handling and generates a sequence. If you write `1L..-5..-10`, then the compiler parses `..-` as a unary operator that is applied to `5L`. Writing the spaces resolves the ambiguity between unary operator and `..` followed by a negative number.

For reference, here is a screenshot from my Visual Studio (which shows `10..` in green, but `..` on the second line in yellow - not particularly noticeable difference, but they are different :-))

Problem

I'm having a bit of trouble declaring a descending sequence of `int64`. What I want is this: ``` seq{0L..-5L..-10L};; ``` However, I get an error: ``` seq{0L..-5L..-10L};; ---^^^^^^^^^^^^^^^ stdin(5,4): error FS0739: Invalid object, sequence or record expression ``` Interestingly, it works with plain `int`: ``` > seq{0..-5..-10};; val it : seq<int> = seq [0; -5; -10] ``` Even more interestingly, if I put spaces between `..`, it starts working with `int64` too: ``` > seq{0L .. -5L .. -10L};; val it : seq<int64> = seq [0L; -5L; -10L] ``` Can someone explain why the compiler gets into the twist with `seq{0L..-5L..-10L}`?

Original source