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

Strict pattern matching #2942

Open
samhh opened this issue Jun 6, 2024 · 8 comments
Open

Strict pattern matching #2942

samhh opened this issue Jun 6, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@samhh
Copy link

samhh commented Jun 6, 2024

What is the problem this feature would solve?

Walls of unneeded lambdas when pattern matching harm readability. For example:

import { Data } from "effect"

type Example = Data.TaggedEnum<{
  A: {},
  B: {},
  C: {},
  // etc
}>

const { $match } = Data.taggedEnum<Example>()

$match({
  A: () => "it is A",
  B: () => "this time it is B",
  C: () => "this is wild, it's C!",
  // etc
})

What is the feature you are proposing to solve the problem?

matchX simply makes each case strict. This has different performance characteristics, however in many cases it's viable and improves readability:

$matchX({
  A: "it is A",
  B: "this time it is B",
  C: "this is wild, it's C!",
  // etc
})

This is particularly relevant when there are potentially dozens of sum members.

What alternatives have you considered?

constant, tolerating the lambdas.

@samhh samhh added the enhancement New feature or request label Jun 6, 2024
@mikearnaldi
Copy link
Member

Given that JS has eager evaluation you generally don't want to compute the alternatives unless they match, this isn't something we would like to add for the time being

@samhh
Copy link
Author

samhh commented Jun 11, 2024

Given that JS has eager evaluation you generally don't want to compute the alternatives unless they match, this isn't something we would like to add for the time being

I'm really thinking primarily of the example where rather than expensive computations it's just strings or other primitives. We find in our codebase that this comes up quite a lot in pattern matching, and I perhaps naively wonder if this might be more performant than a redundant anonymous function call.

@mikearnaldi
Copy link
Member

Given that JS has eager evaluation you generally don't want to compute the alternatives unless they match, this isn't something we would like to add for the time being

I'm really thinking primarily of the example where rather than expensive computations it's just strings or other primitives. We find in our codebase that this comes up quite a lot in pattern matching, and I perhaps naively wonder if this might be more performant than a redundant anonymous function call.

If that kind of perf is important to you probably you shouldn't even use a matcher in the first place, preventive optimization is usually bad

@samhh
Copy link
Author

samhh commented Jun 11, 2024

If that kind of perf is important to you probably you shouldn't even use a matcher in the first place, preventive optimization is usually bad

I agree, but wasn't performance your primary concern?

Maybe there's unease about further complicating the pattern matching API, which'd make sense. Just thought I'd raise this though as, in considering a migration path from the fp-ts ecosystem, we've found ourselves quite liking matchX in sum-types.

@mikearnaldi
Copy link
Member

If that kind of perf is important to you probably you shouldn't even use a matcher in the first place, preventive optimization is usually bad

I agree, but wasn't performance your primary concern?

Maybe there's unease about further complicating the pattern matching API, which'd make sense. Just thought I'd raise this though as, in considering a migration path from the fp-ts ecosystem, we've found ourselves quite liking matchX in sum-types.

No, my primary concern was semantics, even in the Effect type we had to make matchers lazy because users expected branches not to be computed

@samhh
Copy link
Author

samhh commented Jun 11, 2024

No, my primary concern was semantics, even in the Effect type we had to make matchers lazy because users expected branches not to be computed

Gotcha, that makes holistic sense. Thanks for engaging. 🙂

@samhh samhh closed this as completed Jun 11, 2024
@mikearnaldi
Copy link
Member

Wondering if we could use the same api with an optional parameter though, as long as we don't duplicate functions and we can support it across the types I am not against

@samhh samhh reopened this Jun 11, 2024
@aminnairi
Copy link

You could also create an identity function that takes an argument, and return a function that return that argument.

const always = <Value>(value: Value) => () => value;

match({
  A: always("it is A"),
  B: always("this time it is B"),
  C: always("this is wild, it's C!"),
});

Similar to what Lodash or Ramda do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants