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

PoC: Unified infix operators #7057

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

cometkim
Copy link
Member

@cometkim cometkim commented Sep 28, 2024

Trying to solve #6477, but without implicit open

Rationale

As explained in #6477, we have the "infix explosion" problem. To relax it, I added some specialization to both type inference and primitive inspired by F#

https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/arithmetic-operators#operators-and-type-inference

The idea is, to extend the type inference rules for infix (and some unary) operations defined in Pervasives to specialize them for predefined types but fall back to int if they cannot be inferred or the types of the left-hand and right-hand are different.

let t1 = 1 + 2     // => external \"+": (int, int) => int = "%addint"
let t2 = 1. + 2.   // => external \"+": (float, float) => float = "%addfloat" 
let t3 = "1" + "2" // => external \"+": (string, string) => string = "%string_concat"
let t4 = 1n + 2n   // => external \"+": (bigint, bigint) => bigint = "%addbigint"

let fn1 = (a, b) => a + b        // => external \"+": (int, int) => int = "%addint"
let fn2 = (a: float, b) => a + b // => external \"+": (float, float) => float = "%addfloat" 
let fn3 = (a, b: float) => a + b // => external \"+": (float, float) => float = "%addfloat" 

let inv1 = (a: int, b: float) => a + b  // => external \"+": (int, int) => int = "%addint"
//                                   ^ error: cannot apply float here, expected int

This doesn't make a breaking change, since the existing operations are defined on int already.

However, we can introduce them as unified operators for the new codebase. They are still safe, as they are always specialized and not polymorphic.

Specialized operators:

Op Primitive supported types
\"~-" %neg int, float, bigint
\"~+" %identity int, float, bigint
\"+" %add int, float , bigint, string
\"-" %sub int, float, bigint
\"*" %mul int, float, bigint
\"/" %div int, float, bigint
mod %mod int, float, bigint
\"**" %pow int, float, bigint
abs %abs int, float, bigint
land %land int, bigint
lor %lor int, bigint
lxor %lxor int, bigint
lnot %lnot int, bigint
lsl %lsl int, bigint
lsr %lsr int
asr %asr int, bigint

Side note

This PR doesn't attempt to add custom ops or polymorphic ops, but that's the specialized custom ops already possible by opening a module.

Polymorphic ops should deprecated. they are unpredictable and inefficient, as explained in #7031. So in future versions, comparison will have consistent behavior with this. It will be a breaking change, but we don't have a better alternative yet.

@cometkim

This comment was marked as outdated.

@cometkim cometkim changed the title PoC: generic infix operators PoC: Unified infix operators Sep 28, 2024
@cometkim
Copy link
Member Author

Checking rhs type in inference adds quite a bit of complexity. I wonder if there are any use cases for this. If not, it makes sense to consider checking only lhs type.

@zth
Copy link
Collaborator

zth commented Oct 1, 2024

@cometkim you waiting on anything from any of us on this one?

@cometkim
Copy link
Member Author

cometkim commented Oct 4, 2024

@cometkim you waiting on anything from any of us on this one?

No, I just took a break from coding over the Korean holidays.

@zth
Copy link
Collaborator

zth commented Oct 4, 2024

@cometkim you waiting on anything from any of us on this one?

No, I just took a break from coding over the Korean holidays.

Enjoy your holidays!

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

Successfully merging this pull request may close these issues.

2 participants