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

Semantic-based optimization for untagged variants. #6108

Closed
zth opened this issue Apr 3, 2023 · 3 comments
Closed

Semantic-based optimization for untagged variants. #6108

zth opened this issue Apr 3, 2023 · 3 comments
Milestone

Comments

@zth
Copy link
Collaborator

zth commented Apr 3, 2023

There seems to be a few opportunities for semantic-based optimization for the compiler.

Here's an example of code generated via the new untagged variants functionality:

@unboxed
type rec t =
  | @as(undefined) Missing
  | @as(false) False
  | @as(true) True
  | @as(null) Null
  | String(string)
  | Number(float)
  | Object(Js.Dict.t<t>)
  | Array(array<t>)

type tagged_t =
  | JSONFalse
  | JSONTrue
  | JSONNull
  | JSONString(string)
  | JSONNumber(float)
  | JSONObject(Js.Dict.t<t>)
  | JSONArray(array<t>)

let someJson: t = %raw(`'[{"name": "Haan"}, {"name": "Mr"}, false]'`)->JSON.parseExn->Obj.magic

let check = s =>
  switch s {
  | Array([True, False, Array([String("My name is"), Number(10.)])]) => Console.log("yup")
  | _ => Console.log("Nope...")
  }
function check(s) {
  if (!(s instanceof Array) && typeof s !== "object" && typeof s !== "number" && typeof s !== "string") {
    console.log("Nope...");
    return ;
  }
  if (s instanceof Array) {
    if (s.length !== 3) {
      console.log("Nope...");
      return ;
    }
    var match = s[0];
    if (!(match instanceof Array) && typeof match !== "object" && typeof match !== "number" && typeof match !== "string" && match === true) {
      var match$1 = s[1];
      if (!(match$1 instanceof Array) && typeof match$1 !== "object" && typeof match$1 !== "number" && typeof match$1 !== "string" && match$1 === false) {
        var match$2 = s[2];
        if (!(match$2 instanceof Array) && typeof match$2 !== "object" && typeof match$2 !== "number" && typeof match$2 !== "string") {
          console.log("Nope...");
          return ;
        }
        if (match$2 instanceof Array) {
          if (match$2.length !== 2) {
            console.log("Nope...");
            return ;
          }
          var match$3 = match$2[0];
          if (!(match$3 instanceof Array) && typeof match$3 !== "object" && typeof match$3 !== "number" && typeof match$3 !== "string") {
            console.log("Nope...");
            return ;
          }
          if (typeof match$3 === "string" && match$3 === "My name is") {
            var match$4 = match$2[1];
            if (!(match$4 instanceof Array) && typeof match$4 !== "object" && typeof match$4 !== "number" && typeof match$4 !== "string") {
              console.log("Nope...");
              return ;
            }
            if (typeof match$4 === "number") {
              if (match$4 !== 10) {
                console.log("Nope...");
              } else {
                console.log("yup");
              }
              return ;
            }
            console.log("Nope...");
            return ;
          } else {
            console.log("Nope...");
            return ;
          }
        } else {
          console.log("Nope...");
          return ;
        }
      } else {
        console.log("Nope...");
        return ;
      }
    } else {
      console.log("Nope...");
      return ;
    }
  } else {
    console.log("Nope...");
    return ;
  }
}

Notice for example if (!(match instanceof Array) && typeof match !== "object" && typeof match !== "number" && typeof match !== "string" && match === true) { that could be just if (match === true).

cc @cristianoc

@cristianoc cristianoc added this to the v11.0 milestone Apr 4, 2023
@cristianoc
Copy link
Collaborator

The idea here is that semantic-based optimizations could simplify the generated code without adding additional complexity to the already complex pattern matching compiler.
There are areas in the back-end where these kinds of simplifications take place already, and this issue could be resolved by enriching those optimisations with domain specific knowledge about typeof/instanceof etc.
As an example, it is already the case that if the output of a pattern matching guard ends up being equivalent to true or false, further transformations kick off after pattern matching compilation.

@cristianoc cristianoc changed the title Semantic-based optimization Semantic-based optimization for untagged variants. Apr 9, 2023
@cometkim
Copy link
Contributor

Should beware of being broken by JS data types that are not yet handled, such as symbol and bigint

@cristianoc
Copy link
Collaborator

Should beware of being broken by JS data types that are not yet handled, such as symbol and bigint

Got an example of what's currently broken because of that?

cristianoc added a commit that referenced this issue Jun 22, 2023
* Example of complex pattern for untagged variant.

From #6108

* Some simplification.

* More optimization

* Optimize "or".

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

No branches or pull requests

3 participants