HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

haxe.Int64 Numeric Literal Suffix #92

Closed Aidan63 closed 2 years ago

Aidan63 commented 2 years ago

Would allow appending an integer literal with i64 to create a haxe.Int64.

final myInt64 = 800000000i64;

Rendered version

Simn commented 2 years ago

I'm in favor of this. Could you create a suffix table for all relevant numeric types as a kind of "if we add type X, we'll use suffix Y for it"? That way we can be sure to not run into surprises down the line.

Aurel300 commented 2 years ago

I think usually 64-bit numbers are long longs in C(++) and are notated with LL. So I would prefer these suffixes:

We might also consider suffixes for floats (Single or Double) to make this consistent for all number literals?

haxiomic commented 2 years ago

To add a different voice, suffixes and the 'long' / 'short' terminology are pet peeve of mine in languages – I feel like to know what they mean by looking at them I need to go to the language manual and find a suffix table :/

For example as Aurel300 mentioned, I can't tell how many bytes in 800000000L, is it 4 or 8? I'd prefer something super explicit like a check-type expression (800000000:Int64). If brevity is important here we could support shorter type names and maybe allow the expression without parens when possible

final v = 100:I8;
final v = 100:I16;
final v = 100:I32;
final v = 100:I64;

final v = 100:F32;
final v = 100:F64;
Aurel300 commented 2 years ago

I agree long etc is a relic of the past and it's not clear what it means. We could take inspiration from another language, Rust. Rust also has number suffixes, but they indicate very clearly the bitlength and signedness of the number: 42u8, 301i16, 321321u32, 1i64, 5.5f32 etc.

Aidan63 commented 2 years ago

If we go with a single letter suffix something like the following might work for the usual integer sizes

b/B for a byte or int8 type.

s/S for a short or int16 type.

i/I for a int or int32 type.

l/L for a long or int64 type.

We could also specify that adding a u in front would create an unsigned version. This might get us into a bit of a muddle if we want to support suffixes for floating point types as well. Haxe's Float is already double precision, so if we wanted the s suffix for the Single floating point type that would conflict with a 16bit integer suffix.

Thinking about it, it might be better to not use single letter to avoid this ambiguity (and means the suffixes have more meaning to eventual haxe types / not rely on c naming legacy).

final v = 100i8;
final v = 100i16;
final v = 100i32;
final v = 100i64;

final v = 100f32;
final v = 100f64;

edit: beat by Aurel for the more qualified suffixes suggestion.

Simn commented 2 years ago

Yes, this indeed looks better in every way.

RealyUniqueName commented 2 years ago

What about case sensitivity?

Aidan63 commented 2 years ago

I've updated the proposal to use the i64 suffix, I've also added a table of potential integer and float suffixes for future types in the opening possibilities section.

I don't feel strongly one way or another about case sensitivity of the suffixes, so for now I've mentioned in the detailed design section that the suffix should be case sensitive for simplicity.

haxiomic commented 2 years ago

I wonder if we can do away with suffixes in favor of implicit typing – If the following worked (where long literals are implicitly typed as Int64) then I'm not convinced they'd be necessary

// 8589934592 = 2 ^ 33
var x: Int64 = 8589934592;  // ✓
var x: Int32 = 8589934592; // ✗ compiler error: literal is too long to be represented as Int32. Use cast to force and truncate 

var x = 8589934592; // long int literal automatically typed as Int64 

var x: UInt64 = 8589934592; // compiler knows we expect UInt64 here so we can type the literal as UInt64
var x: UInt32 = 8589934592; // we type the literal as UInt32 and discover it's too long and warn user
Aidan63 commented 2 years ago

I definitely agree that implicit typing could be used / improved here as well. Currently integer literals too large to fit in 32 bits become a float which probably makes sense from a historical point of view (guessing that was before haxe.Int64 was a thing), but can be a bit unexpected.

But I don't think that sort of typing invalidates suffixes. I tend to not add type annotations where possible so being able to write code such as

var x = 8589934592i16;
var x = 8589934592u64;

feels much more natural to me and would stylistically align to what I tend to write.

TheDrawingCoder-Gamer commented 2 years ago

Imo Int64 is not good for regular use case because it's considered a class on some targets, which precludes it from being assigned to vars (very frustratingly making me split my bitflags into two enum abstracts). It's good to have a suffix but Int64 needs fixing

Simn commented 2 years ago

This proposal has been accepted, see https://haxe.org/blog/evolution-meeting-2021/ for details.