Skip to content

Conversation

@zth
Copy link
Member

@zth zth commented Oct 27, 2024

More examples for when unboxed variant pattern matching code isn't as efficient as it could be.

Comment on lines 12 to 21
let match = json.id;
if (match === undefined) {
return;
}
if (match === null) {
return;
}
if (typeof match !== "string") {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the bottom case should be enough, as it covers the 2 cases on top as well.

Comment on lines 22 to 12
let match$1 = json.name;
if (match$1 === undefined) {
return;
}
if (match$1 === null) {
return;
}
if (typeof match$1 !== "string") {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, bottom case is enough.

Comment on lines 32 to 20
let match$2 = json.age;
if (match$2 === undefined) {
return;
}
if (match$2 === null) {
return;
}
if (typeof match$2 !== "number") {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And same here, bottom case is enough.

}
let email = json.email;
let tmp;
tmp = email !== undefined && !(email === null || typeof email !== "string") ? email : undefined;
Copy link
Member Author

@zth zth Oct 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is similar to the above - typeof email !== "string" ? undefined : email or even typeof email === "string" ? email : undefined would be ideal.

return;
}
let match$2 = json.users;
if (match$2 !== undefined && !(match$2 === null || !Array.isArray(match$2))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - Array.isArray(match$2) would cover these.

@cristianoc
Copy link
Collaborator

Let's cut down and use the latest compiler:

type group = {
  id: string,
  name: string,
}


let decodeGroup = group => {
  switch group {
  | (dict{"id": JSON.String(id), "name": String(name)}) =>
    Some({
      id,
      name,
    })
  | _ => None
  }
}

gives:

function decodeGroup(group) {
  let match = group.id;
  if (match === undefined) {
    return;
  }
  if (match === null) {
    return;
  }
  if (typeof match !== "string") {
    return;
  }
  let match$1 = group.name;
  if (match$1 !== undefined && !(match$1 === null || typeof match$1 !== "string")) {
    return {
      id: match,
      name: match$1
    };
  }
  
}

@cristianoc
Copy link
Collaborator

cristianoc commented Oct 28, 2024

@cristianoc
Copy link
Collaborator

One might need special, different algorithms to compile untagged variants pattern matching differently.

cristianoc and others added 7 commits November 2, 2024 10:42
First step: remove the distinction between cases with and without payload in the toplevel algorithm.

On this test:
```res
@unboxed
type rec t =
  | Boolean(bool)
  | @as(null) Null
  | String(string)
  | Number(float)
  | Object(Dict.t<t>)
  | Array(array<t>)

type group = {
  id: string,
  name: string,
}

let decodeGroup = group => {
  switch group {
  | (dict{"id": String(id), "name": String(name)}) =>
  (id, name)
  | _ => ("e", "f")
  }
}
```

Before:
```js
function decodeGroup(group) {
  let match = group.id;
  if (match === undefined) {
    return [
      "e",
      "f"
    ];
  }
  if (match === null) {
    return [
      "e",
      "f"
    ];
  }
  if (typeof match !== "string") {
    return [
      "e",
      "f"
    ];
  }
  let match$1 = group.name;
  if (match$1 !== undefined && !(match$1 === null || typeof match$1 !== "string")) {
    return [
      match,
      match$1
    ];
  } else {
    return [
      "e",
      "f"
    ];
  }
}
```

After:
```
function decodeGroup(group) {
  let match = group.id;
  if (match === undefined) {
    return [
      "e",
      "f"
    ];
  }
  if (typeof match !== "string") {
    return [
      "e",
      "f"
    ];
  }
  let match$1 = group.name;
  if (match$1 !== undefined && typeof match$1 === "string") {
    return [
      match,
      match$1
    ];
  } else {
    return [
      "e",
      "f"
    ];
  }
}

```

The 3 cases have become 2: check for optional fields and check for which case it is.
@cristianoc cristianoc force-pushed the add-json-decoder-examples branch from 94904b4 to 59b2ed7 Compare November 4, 2024 04:41
@cristianoc cristianoc changed the base branch from master to untagged-pattern-matching November 4, 2024 04:42
@cristianoc
Copy link
Collaborator

@zth: 59b2ed7

Base automatically changed from untagged-pattern-matching to master November 5, 2024 06:39
@cristianoc cristianoc closed this Nov 5, 2024
@cristianoc cristianoc deleted the add-json-decoder-examples branch November 5, 2024 06:40
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

Successfully merging this pull request may close these issues.

2 participants