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
Pattern matching NewExpression/CallExpression #117
Comments
Note, there would be a compatibility risk to supporting this construct within destructuring assignment, as that syntax has existing semantics (evaluate both sides and then throw IIRC). But I see no risk for destructuring bind. |
As for matching constructors, why not support matching on the
|
@Luftzig Maybe that would make sense with the pinning feature? The proposal above adds something further--datatype-specific pattern matching logic, not just a way to pattern match on property accesses. |
I really like this, thank you! We should probably move this to a separate proposal, though, as I'd much rather this get integrated into destructuring at the same time as it lands in pattern matching. Making sure those are in sync is important to me. |
As an alternative to @Luftzig's idea, you could just define I would be okay if it were punted to a follow-up proposal. |
@littledan How breaking would it be to change that to something else? Typically, changing errors to non-errors is a lot less breaking than changing non-errors to anything else, including other non-errors. |
@zkat Yeah, I agree that this is a clean place to separate out. The place where it hooks into pattern matching is the protocol for indicating "no match" (so it'd be hard to add this separate proposal first and then pattern matching second unless we decide on that). |
(x: TS) => [A, B, C, ...] & (x is T & TE) | null |
Maybe we can use this to deconstruct on case (x) {
when Set([1, 2, 3]) -> expr
} (ref: #148 ) |
I don’t see how; there’s no robust cross-realm way to identify instances, and any first-class instanceof support is something I’d block. |
Here's a quick summary of Scala's unapply. (Briefly, though, it would be via a presumably symbol-keyed method on Set/ Map, not by special-casing those types.) Or maybe I don't understand your objection? Edit: though I guess the cross-realm thing might still be an issue? But I don't think that's an issue which would come up much in practice. |
Note that Scala's extractor methods are defined on the companion objects of a type, meaning they'd be equivalent to static methods rather than instance methods (i.e. defined on the I think Scala's extractor methods could work for this usecase without cross-realm issues. case (x) {
when Set(1, 2, 3) -> { some statements... }
} could naïvely desugar to something like const [a, b, c] = Set[someMagicUnapplySymbol](x);
if (a === 1 && b === 2 && c === 3) {
some statements...
} |
The proposal has been updated in #174. The current design has no facility for matching against NewExpression or CallExpression. If, taking into account the updated proposal, someone still feels there's a plausible way it could, or should do so, please open a new issue. |
Maybe it still the case. The old syntax seems like enables the custom pattern ( |
Indeed, patterns can’t look like function calls right now, and tbh I’m not sure how that really even makes sense. Now that the proposal much more explicitly separates patterns, expressions, and bindings, it seems clearer to me that this idea doesn’t make much sense, but I’m happy to hear arguments in a new issue :-) |
In the May 2018 TC39 meeting, @zkat presented the possibility of having pattern matching on NewExpressions. I think this is a great idea, but I didn't see anything in this repository for it. I wanted to suggest some concrete syntax and semantics
Syntax and semantics
Syntax of new things that can be put as the thing which comes after
when
:When matching against any of the three constructs, the expression (either
CallExpression
orMemberExpression
) is evaluated, and a Symbol-named method is called, with the object being patched passed in as the argument. For thenew
constructs, let's call that methodSymbol.invertConstruct
; for calls, let's call thisSymbol.invertCall
. The method is expected to return eithernull
(indicating a failed match) or an iterator. If it returns non-null, that value is treated as an iterator and is matched against the argument list of the construct/call, with the same algorithm as pattern matching on Array literals.Example
Let's do Lisp! Stack space and useful variable names be damned.
(Note, the above depends on the ability to use the above example depends on the ability to use
case
expressions, as proposed in #116.)There's a million ways this could be implemented, but here's an especially poorly designed one:
Possible future extensions
invert
function.Shameless, irrelevant plug: see my related work in Factor.
The text was updated successfully, but these errors were encountered: