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

polymorphic equality and inequality #1252

Open
disconcision opened this issue Mar 19, 2024 · 3 comments
Open

polymorphic equality and inequality #1252

disconcision opened this issue Mar 19, 2024 · 3 comments
Assignees

Comments

@disconcision
Copy link
Member

@cyrus- are you still okay making the equality operator polymorphic? I've done this on the LLM branch for convenience, so I'll copy-paste some code here to accelerate someone doing it for real.

  1. Add case to statics.re:
| BinOp(Int(Equals | NotEquals), e1, e2) =>
  let (e1, m) = go(~mode=Syn, e1, m);
  let (e2, m) = go(~mode=Ana(e1.ty), e2, m);
  add(~self=Just(Bool), ~co_ctx=CoCtx.union([e1.co_ctx, e2.co_ctx]), m);
  1. Add cases to dynamics
    | BinIntOp(Equals, d1, d2) =>
      let* r1 = evaluate(env, d1);
      let* r2 = evaluate(env, d2);
      switch (r1, r2) {
      | (BoxedValue(d1'), BoxedValue(d2')) =>
        let b =
          DHExp.fast_equal(DHExp.strip_casts(d1'), DHExp.strip_casts(d2'));
        return(BoxedValue(BoolLit(b)));
      | (BoxedValue(d1'), Indet(d2'))
      | (Indet(d1'), BoxedValue(d2'))
      | (Indet(d1'), Indet(d2')) =>
        return(Indet(BinIntOp(Equals, d1', d2')))
      };

    | BinIntOp(NotEquals, d1, d2) =>
      let* r1 = evaluate(env, d1);
      let* r2 = evaluate(env, d2);
      switch (r1, r2) {
      | (BoxedValue(d1'), BoxedValue(d2')) =>
        let b =
          !DHExp.fast_equal(DHExp.strip_casts(d1'), DHExp.strip_casts(d2'));
        return(BoxedValue(BoolLit(b)));
      | (BoxedValue(d1'), Indet(d2'))
      | (Indet(d1'), BoxedValue(d2'))
      | (Indet(d1'), Indet(d2')) =>
        return(Indet(BinIntOp(Equals, d1', d2')))
      };
  1. Fix DHExp.fast_equals throws exceptions in certain cases #1243 to prevent above from crashing

The above is sufficient to get it basically working. Remaining issues:

  1. Decide on behavior on edge cases, in particular function values. We could prohibit comparisons of types (which contain) arrow types at the static level, or just always return false at the dynamic level. The latter is simpler, but can be confusing, especially if you have a large type that you've forgotten has an arrow somewhere in it (this happens in the Hazel model type not infrequently...). The above code currently just compares for structural equality of function implementations, including closed over values
  2. Data structures cleanup and backcompat: Remove operators from Int BinOp subtype, remove float and string specific operators (maybe? backwards compatibility is starting to become a concern)
  3. Update langdocs
@cyrus- cyrus- changed the title polymorphic equality and inequality (starter project?) polymorphic equality and inequality Mar 20, 2024
@cyrus-
Copy link
Member

cyrus- commented Mar 20, 2024

Yeah, I'm okay with adding this for now with the plan to rip it out down the line when we have implicits. I'll mark it as a possible starter project.

@cyrus-
Copy link
Member

cyrus- commented Apr 9, 2024

@disconcision @GuoDCZ is planning to take a look at this as a starter project. is the relevant code in this PR? #1148 (or is it in the plus branch?)

@disconcision
Copy link
Member Author

neither. it's in llama-lsp-lookahead (something something hardest problem in computer science). note that literally all the relevant code written so far is reproduced above though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Team Language
Development

No branches or pull requests

3 participants