I think when working with primitives, an ExpressionPattern will be enormously helpful. Take the following trivial example code:
if (x < 5) {
console.log("small");
} else if (x < 10) {
console.log("medium");
} else {
console.log("large");
}
By having an ExpressionPattern this code is greatly simplified:
match (x) {
< 5: console.log("small")
< 10: console.log("medium")
else: console.log("large")
}
An alternate syntax (which, admittedly, would significantly impact this proposal) would be to auto-bind to a generic value (like it in Kotlin), allowing expressions like this:
match (x) {
it < 5: console.log("small")
it < 10: console.log("medium")
else: console.log("large")
}
I think it would make sense to bind to this instead of introducing a new keyword if this was going to done. Could you post more examples? This does not appear to substantially shrink the code.
Both your first and then your second suggestions were (previously) implemented in LightScript's pattern matching. The parsing was not as hard as one might think.
Ultimately, we found the syntax too confusing, and it caused a bunch of trouble as well (particularly with nested matchs, iirc). this, I think, would be even more problematic.
Allowing a syntax for predicates and guards was the best we could come up with, resulting in either
match (x) {
isLessThanFive(x): console.log("small"),
isLessThanTen(x): console.log("medium")
}
or
```js
match (x) {
Number if x < 5: console.log("small"),
if x < 10: console.log("medium") // not sure that guards without patterns would be allowed
}
I see we now have this
match (x) {
/reg(exp)/ -> [, exp]: exp
}
So what about this?
//--------------------------------------------v not match
const y = boolean => boolean ? [1, 2, 3] : undefined
const match = x => (...args) => ({
[Symbol.matches]: x(...args)
})
const z = x => match (x) {
match(boolean) -> [a, b, c]: c,
match(boolean): {throw new Error('')}
}
z(true) // 3
z(false) // Error
Emm.. By the way, when I am typing /reg(exp)/ -> [, a], I want to add -> exp instead of : exp, maybe -> is a better choice?
match(e){
/reg(exp)/ -> [, exp] -> exp
}
@Jack-Works assuming I understand your example correctly(apologies if I am not) aren't you just implementing named pattern groups for JavaScript pattern matching and your example RegExps. Seems to me that should be a separate proposal and named groups should be implemented with some sort of syntax as I mentioned in my issues page. Your example suffers from the same way JavaScript Regex work currently in that order matters.
I clarify my ideas again, sorry for the confusing example.
What I want to say is that despite deconstructing, when we are handling MatchBody of literals and references, can we check if it has [Symbol.matches], if it has, call the method, else, treat it as something use ________(I don't know what is it) to compare.
Like this (fall into [Symbol.matches] path)
var x = {[Symbol.matches]: (y) => {console.log(y, ' is matching!'); return true}}
match (e) {
x: 'matched!' // there is [Symbol.matches] on x, so call it
}
or
var y = Symbol() // ummm i think there is no [Symbol.matches] on y right?
// it should on Symbol[Symbol.matches]
var q = y
match (q){
y: 'Matched!' // by compare expression 'y' and 'q'
}
Em.. does it work like this now?
I think here Symbol.matches should be used.
It gives less dense code but more clear and doesn't complicate syntax
const lessThan = x => ({[Symbol.matches]: y => y < x });
match (x) {
lessThan(5): console.log("small"),
lessThan(10): console.log("medium"),
intentionRevealingName(curriedArg): console.log("42"),
else: console.log("large")
}
Hey y'all! #65 has gotten merged, and a lot of issues have become irrelevant or significantly changed in context. Because of the magnitude of changes and subtle differences in things that seem similar, we've decided to just nuke all existing issues so we can start fresh. Thank you so much for the contributions and discussions and feel free to create new issues if something seems to still be relevant, and link to the original, related issue so we can have a paper trail (but have the benefit of that clean slate anyway).
As far as this issue goes: the new proposal includes a fairly terse guard feature which I think will be more than sufficient to cover what this is trying to achieve while making it manageable with nesting, so I pretty much consider this issue resolved. :)
Most helpful comment
Both your first and then your second suggestions were (previously) implemented in LightScript's pattern matching. The parsing was not as hard as one might think.
Ultimately, we found the syntax too confusing, and
itcaused a bunch of trouble as well (particularly with nestedmatchs, iirc).this, I think, would be even more problematic.Allowing a syntax for predicates and guards was the best we could come up with, resulting in either
or
```js
match (x) {
Number if x < 5: console.log("small"),
if x < 10: console.log("medium") // not sure that guards without patterns would be allowed
}