-
Notifications
You must be signed in to change notification settings - Fork 90
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
What about matching types as well and use it instead "when" keyword? #190
Comments
"type" isn't a thing in JS beyond To do what you're suggesting would require using The way to do what you want is this: const getLength = vector => match (vector) {
when ({ x, y, z }) if (vector instanceof Vec3) { Math.hypot(x, y, z); }
when ({ x, y }) if (vector instanceof Vec3) { Math.hypot(x, y); }
if (vector instanceof Vec3) { vector.len(); }
.. ([...etc]) vector.length; // ArrayLike
.. { /* default */ 0; } // others
}; |
Yes, but this much more verbose. Also |
It is much more verbose, but it should be, since it’s semantics won’t be what everyone wants. Explicitness is better than brevity when the concise version isn’t consistently intuitive. |
matching by Type is very important feature for many scenarios. Just see this article and code example which use Also it very useful for syntax parsing: microsoft/TypeScript#2214 https://dev.realworldocaml.org/parsing-with-ocamllex-and-menhir.html |
A few of those examples use
but if a constructor check is what's really wanted here, can't you do match(vector) {
when ({ x, y, z, constructor: ^Vec3 }) { Math.hypot(x, y, z); }
} assuming const is = (value) => ({
[Symbol.matcher](matchable) {
if (Object.is(value, matchable)) {
return {
matched: true,
value: value
};
}
})
match(vector) {
when ({ x, y, z, constructor: ^is(Vec3) }) { Math.hypot(x, y, z); }
} Similarily, the mootools examples use their own |
@MaxGraey in languages with that concept, i agree - JS does not have it. The custom matcher protocol will let you define your own semantics so that you could do this: const getLength = vector => match (vector) {
when ^Vec3 and ({ x, y, z }) { Math.hypot(x, y, z); }
when ^Vec3 and ({ x, y }) { Math.hypot(x, y); }
when ^Vec3 { vector.len(); }
.. ([...etc]) vector.length; // ArrayLike
.. { /* default */ 0; } // others
}; |
The main idea provide stable and consistent matching by Type as well. It may be something special than just Basically all languages provide this feature. It's pretty important ingredient of PM which also will allow semantic checkers like typescript add exhaustive pattern analysis: https://tkdodo.eu/blog/exhaustive-matching-in-type-script |
Yes, but it's too complicated as for user space and js engines |
I have not heard any feedback yet that it's too complicated for either.
JavaScript does not provide this feature, and as such, pattern matching can not provide it either. A separate proposal (which is already in progress) would provide a mechanism for this, and there'd surely be a way to integrate the two at that time. |
Awesome! |
Closing based on discussion; happy to reopen if there's more to discuss. |
Just a quick note: in this code sample from @noppa:
It would not work as Noppa intended, whether or not The proposed semantics of the "value match" operator is that if the value is a primitive, it checks equality (as if you'd subbed in the value literally to produce a primitive-matcher); otherwise, it invokes the custom matcher protocol if it can; otherwise it's a runtime error. It works this way at least partially to avoid the possible confusion Noppa cites, where matching would work substantially differently based on whether the object defines its own protocol or not. That said, an object-equality custom matcher is easy to define: function IsClass(cls) {
return {
[Symbol.matcher]: val=>({matched: cls === val.constructor, value: val})
};
}
match(vector) {
when (^IsClass(Vec3) into {x,y,z}) { Math.hypot(x,y,z); }
} |
I propose match not only pattern but also type (by comparing constructors or class ids) at the same type as doing in many langs. And use
..
(double dot) for skipping this:is same as current proposal but if you match only
Vec3
class it may look like this:similar example on Python3:
The text was updated successfully, but these errors were encountered: