Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

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

Open
ePaul opened this issue Sep 4, 2019 · 3 comments
Open

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

ePaul opened this issue Sep 4, 2019 · 3 comments

Comments

@ePaul
Copy link
Contributor

ePaul commented Sep 4, 2019

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.

@xkr47
Copy link
Contributor

xkr47 commented Sep 6, 2019

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

@kingjon3377
Copy link

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);
}

@ePaul
Copy link
Contributor Author

ePaul commented Sep 9, 2019

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?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants