-
Notifications
You must be signed in to change notification settings - Fork 0
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
RFC: int
semantics
#1
base: main
Are you sure you want to change the base?
Conversation
This is still TBD, but the suggested actions to the compiler are:
Any early feedback and additional suggestions are welcome :) |
Have you measured the perf implications of changing multiplication from the current one? |
I don't think it's a good idea to implicitly convert infinity to min/max value of |
So does |
It depends on the environment. In my measurements, in Node.js, inlined I ran it on quickjs to see the impact of the optimization. The results are 30% faster for inlined On the other hand, in Bun, suiteimport { summary, run, bench } from './node_modules/mitata/src/main.mjs';
const min_value = -(2 ** 31);
const max_value = 2 ** 31 - 1;
function* randomIntegers(n) {
for (let i = 0; i < n; i++) {
yield Math.floor(Math.random() * 2 ** 32) + min_value;
}
}
const length = 1000;
const x = [...randomIntegers(length)];
const y = [...randomIntegers(length)];
summary(() => {
bench('Math.imul', () => {
for (let i = 0; i < length; i++) {
void Math.imul(x[i], y[i]);
}
});
// function mul(x, y) {
// return x * y | 0;
// }
// bench('mul', () => {
// for (let i = 0; i < length; i++) {
// mul(x[i], y[i]);
// }
// });
bench('mul (inline)', () => {
for (let i = 0; i < length; i++) {
void (x[i] * y[i] | 0);
}
});
});
await run(); |
This is great though I now don't understand what "Change the implementation of multiply from Math.imul to fromNumber" means. Concretely the compilation of |
let f = (a, b) => a * b currently emit this code function f(a, b) {
return Math.imul(a, b);
} I'm requesting to change it to this code function f(a, b) {
return a * b | 0;
} just like we do for |
Since both Runtime dispatch is required when it is outside the compiler's capabilities. |
OK I think the entire RFC can be written in a few lines if one defines operations using |
For example, in the case of |
Oh sorry, I had to focus on explaining the current behavior as it is before making changes 😞 |
IMO we can leave it as the responsibility of stdlib.
As @glennsl originally pointed out, My intention in the |
I added the |
Actually I was referring to the stdlib function to convert float to int. Then similar questions for all the operators. |
Then I think stdlib should always use |
The way we've dealt with these things before is to have 2 or more variants in the stdlib. In this case, we could for example have |
That makes sense. |
Using |
For example, we can have type errorKind = [#Overflow_value]
exception ConversionError(errorKind)
let toInt: float => int // raise ConversionError
module Safe = {
let toInt: float => result<int, errorKind>
} We could also create both |
If there is an alternative API, then assuming conversion I prefer using result type in this case too. If you think that is overkill, |
I guess in this case, it f there are 2-3 kinds of errors, result makes sense to document what they are. |
So if one uses the version returning result one would do eg
and when converting to using the function that raises:
|
One minor problem is that if we introduce this API style for Then we'll need more error definitions per conversion. We need to propose a module convention to split these errors. |
Preview