-
Notifications
You must be signed in to change notification settings - Fork 71
RFC: Long Integer Type #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| Current methods of representing 64-bit integers in Luau are done with high-low pairs or by splitting them among vectors which leads to poor ergonomics and may not be sufficient for cases where performance is important. | ||
|
|
||
| In the case of a high-low pair implementation each individual number takes 16 bytes (or 24) and needs to be be handled together which can be confusing. | ||
|
|
||
| In the case of vector implementations, ergonomics are improved by storing the entire integer in one value however you have the same issues of implementation complexity and lack of integration with the type system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think 'what some people do' is actually a good motivation for a value type.
Motivation should come from problems that are being solved.
People can just do a custom userdata type like it was done in Lua 5.1 modules and have the right ergonomics.
Breaking apart in vector bits is only a 'trick' that you are not required to follow.
|
|
||
| In the case of a high-low pair implementation each individual number takes 16 bytes (or 24) and needs to be be handled together which can be confusing. | ||
|
|
||
| In the case of vector implementations, ergonomics are improved by storing the entire integer in one value however you have the same issues of implementation complexity and lack of integration with the type system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Custom userdata can also integrate into the type system, no one is forced to use the trick with worse ergonomics.
docs/type-long-integer.md
Outdated
| As Luau grows the restriction to doubles will be an increasing pain point for any use case which involves a 64-bit integer. | ||
| System support for 64-bit integers is ubiquitous their use is widespread. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no restriction currently as an embedder can have custom userdata types.
Even out conformance tests implement an int64 type for userdata testing.
docs/type-long-integer.md
Outdated
| As Luau grows the restriction to doubles will be an increasing pain point for any use case which involves a 64-bit integer. | ||
| System support for 64-bit integers is ubiquitous their use is widespread. | ||
|
|
||
| While a runtime could implement 64-bit integers with userdata, performing an allocation for each integer (which can easily fit within an existing Luau value) is an onerous requirement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not an onerous requirement in a language like Luau.
Userdata path is a completely normal way to implement custom types for the embedder.
Languages similar to Luau also take the same boxed garbage-collectable object paths in their implementation and Luau has an efficient allocator to support this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the section here in favor of other ones. The intent is not to say userdata are inappropriate or insufficient in general, but that for the specific case of simple 64-bit integer, a value type representation will have better performance characteristic than a boxed implementation can reasonably provide.
docs/type-long-integer.md
Outdated
| System support for 64-bit integers is ubiquitous their use is widespread. | ||
|
|
||
| While a runtime could implement 64-bit integers with userdata, performing an allocation for each integer (which can easily fit within an existing Luau value) is an onerous requirement. | ||
| A lightuserdata could avoid this allocation this but implementers will not be able to use operators or have any integration with the type system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Embedders should use userdata and for many motivating cases of this type (none of which are included in this RFC btw) it works perfectly well.
| While a runtime could implement 64-bit integers with userdata, performing an allocation for each integer (which can easily fit within an existing Luau value) is an onerous requirement. | ||
| A lightuserdata could avoid this allocation this but implementers will not be able to use operators or have any integration with the type system. | ||
|
|
||
| Most other high-level language have builtin support for 64-bit integers, including Lua since 5.3. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many don't or have the same solution as a userdata already solves so arguably it is already included in Luau.
Luau aims for a small core that is extendable and embedders built on it and bring in their own types as they need.
We don't have to have everything implemented in core.
Having an int64 type can be simple enough and useful, so I can see it in Luau, just finding the motivation really lacking in this RFC in particular.
| @@ -0,0 +1,96 @@ | |||
| # Long Integer Type | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we will go with this name if this goes forward.
What is 'long' and why it is 64 bit.
We don't even have an integer type to have a 'long' counterpart and by itself it stands to confuse.
|
I think calling the library |
|
|
||
| Converts a long to a string representation with the given base. | ||
|
|
||
| `long.add`, `long.sub`, `long.mul`, `long.div`, `long.mod`, `long.udiv`, `long.umod`, `long.band`, `long.bor`, `long.xor`, `long.lt`, `long.le`, `long.ult` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not allow for using metamethods like how vector does? Is there any runtime implications here that I'm unfamiliar with?
Even then I feel like those runtime issues could be overcome by having a third optimization level that removes loadstring and get/set fenv, with this third optimization level being a thing until luau is ready to just flat out remove loadstring and get/set fenv.
Roblox could also then add a property to workspace for using optimization level 3 in-game rather than level 2.
Having a third optimization level has been an idea thats been on my mind for awhile now, and I think it'd be a good way to start a push for finally removing loadstring and get/set fenv. As people would be able to see the performance improvements directly, rather than just having the loose idea of improved performance.
Would also be a lot better than just having a random devforum announcement out of nowhere one day saying you have 6 months to remove get/set fenv and loadstring from your game.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the result of an ultimatum given to me in the ROSS discord saying that an RFC with operators will not go forward
I would like to make a suggestion for the motivational section:Benchmarks show a significant performance gap between heap-allocated userdata and value types. A simple addition loop with
The userdata approach is significantly slower primarily due to allocation overhead and pointer indirection. |
Rendered