ceylon icon indicating copy to clipboard operation
ceylon copied to clipboard

for-loop over byte ranges gives type error on try.ceylon-lang.org

Open ePaul opened this issue 6 years ago • 3 comments

Wrong behavior Try to iterate over a range of bytes with a for-loop:

for (b in 0.byte..3.byte) {
    print(b);
}

Try it! Trying to run this on try.ceylon-lang.org gives this error:

	undefined	 — 	Runtime error:
	undefined	 — 	--- TypeError: $1i.compare is not a function
Script ended with no output

Expected behavior Running this code should print

0
1
2
3

Analysis From the error message, it looks like some part of the compiler is trying to convert this into a classic increment-comparison loop. But bytes in Ceylon have no total ordering, and thus also no comparison operators or compare functions.

ePaul avatar Sep 04 '19 16:09 ePaul

Should the .. operator complain about the type not having total ordering? Or how should it work?

xkr47 avatar Sep 06 '19 09:09 xkr47

The .. operator is syntax sugar for ceylon.language::span, which only requires that its arguments be of a type satisfying Enumerable, and (per its docs)

An Enumerable type is characterized by each element having well-defined offset and neighbour() functions.

Bytes don't have a total ordering in Ceylon because they aren't specifically signed or unsigned, and offset and neighbour are defined in terms of modular arithmetic, wrapping around.

I tried the code in the OP above on the JVM, and it gives the results shown under "Expected behavior" above. I also compiled it to JS using ceylon compile-js, and the code above compiled to

var $3=(0).$_byte,$2=(3).$_byte,$4=$3.compare($2),$5=$4===m$1.smaller()?'successor':'predecessor';for(var $6=m$1.eorl$($4);$6($2,$3);$3=$3[$5]){
m$1.print($3);
}

kingjon3377 avatar Sep 06 '19 12:09 kingjon3377

Ah, so the problem is not on the loop condition, but already when trying to figure out whether to do an upwards or downwards iteration, which doesn't apply for a recursive Enumerable type like Byte. I guess that first comparison should call $3.offset($2) < 0?

ePaul avatar Sep 09 '19 08:09 ePaul