Skip to content
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

Implementation experience in GraalVM and use case in Oracle Database #83

Open
jirkamarsik opened this issue Aug 21, 2023 · 2 comments
Open

Comments

@jirkamarsik
Copy link
Collaborator

Jirka Maršík from Oracle Labs here. We've been following the development of the operator overloading and decimal proposals for ECMAScript. We missed the Decimal session at the last TC39 meeting and so we wanted to report our experiences and position here.

We are developing a JavaScript engine as part of GraalVM and that engine is embedded in Oracle's database products as a scripting engine for user-defined functions. Our use case is like the postgres example presented at the July 2023 TC39 meeting. We have a database with its own high-precision decimal numbers and we want JavaScript developers to be able to consume and work with these numbers in their scripts. Currently, developers can either choose to map these numbers to JavaScript's Number (which loses precision) or to a class called OracleNumber that wraps database numbers and delegates to the database's internal numeric implementation. However, there are downsides to using OracleNumber. There is no operator support, so expressions become clumsy to write and hard to read. Furthermore, since OracleNumber is a custom class, we cannot expect third-party code to work with it. The Decimal proposal in its current form only solves the latter issue but not the former one. We would like to see operator support for Decimals so that developers are not tempted to use the imprecise Number type just because of convenience. We would welcome operator support in any form, either by overloading operators for Decimal objects or by introducing a new primitive type, though we would prefer the new primitive to avoid issues with object identity and strict equality.

We have seen feedback to the proposal that introducing a new primitive type would be prohibitively expensive for implementers. We have prototyped a proof-of-concept implementation of the Decimal128 proposal as it is documented in the proposal's GitHub repo. The prototype adds a new primitive type, decimal128, to GraalVM JavaScript. While the prototype is using a naive data representation and arithmetic operation implementations, the installation of the new primitive into the engine is at a production-ready level. This means that we updated the inline caches and speculative optimizations to work on decimal128 the same way they work for number and bigint. We can report that doing so was not difficult. This was in part because bigint already paved the way for adding a new primitive. The amount of code that was added is comparable to the code added for bigint support but the amount of work required was significantly smaller since we could use our bigint work as a template for decimal128 support. In its current state, our decimal128 branch has changed 3545 lines of code, with 455 of those lines being a small test suite. In conclusion, our experience implementing a new primitive in GraalVM JavaScript has been positive and we believe that it is worth it for operator support and the strict equality semantics.

@jessealama What is your view as the proposal's champion? Are decimals as primitives still on the table?

I also have a few questions about the object-based solution to decimals. Are there any plans on how to handle strict equality with decimals as objects? Is there a long-term vision to add operator support to object-based decimals later on? If decimals were to land in the spec as objects, we might end up implementing them as objects and overload the operators. If there's a plan to add operators to decimal objects later down the road, we'd like to get our implementation as close to that future spec as possible.

@ljharb
Copy link
Member

ljharb commented Aug 21, 2023

I personally believe that Decimals simply aren't worth it unless they are primitives, including for the reasons indicated above.

@jessealama
Copy link
Collaborator

Thanks for taking the time to describe this use case! (And sorry for the delay getting back to you — I was on a long-ish vacation when you wrote.)

Speaking for myself, decimal literals and operator overloading are still on the table. I think this is the way to go, long-term (agreeing here with @ljharb).

But thanks to my experience in TC39, presenting stage 1 updates a couple of times now, I now see these as goals to be achieved over time. I see us getting there in stages; it will probably involve work on operator overloading, and, of course, getting in the trenches alongside engine implementors to address their concerns.

My current thinking on decimal, based on feedback from a variety of sources, is a modest approach that could work and head us down the road we want, would be to make a Decimal128 (or Decimal -- the name is TBD) "utility object" similar to Math. It would have static methods that work on already existing built-in types (string, numbers, and big integers) and return built-in types (probably just strings). This approach would make working with literal decimal data rather bulky, but it does address the use cases of data interchange and "lightweight" calculation use case fairly well. In other words, programmatically working with decimals, with few or no decimal "literals" (i.e., strings), would be addressed. I think engine implementors would probably be open to this approach since it is minimally invasive from their standpoint. JS developers would at least be able to start to work with decimals, albeit with admittedly suboptimal ergonomics. This way, we can at least start to get some data about decimals and get back to work on operator overloading.

tl;dr We can do this, but it will take time and will probably go through a few iterations.

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

No branches or pull requests

3 participants