Open wenkokke opened 2 years ago
Good stuff thanks for filing. A couple thoughts:
Patterns and values are rather different and merging them might let to very confusing selections...
Are you suggesting that "arg" matches the matched value when the cursor is on "match"? There could be arbitrarily nested function calls in x, so having a keyword that jumps directly to the top of the match construct might be extremely useful?
Let's talk this one out when we discuss the haskell stuff. I like to merge when I can to keep vocabulary down but when it doesn't make sense I'm always happy to add another scope type
I think it makes more sense to discuss this while we’re working on Rust support as rust pattern matching capabilities and syntax is more complex than that of Haskell. And it’s such an integral part of the language that I don’t see much sense adding rust support without pattern matching support.
We should probably think about how we can make match arms consistent with case arms. Ref: https://github.com/cursorless-dev/cursorless/issues/247
That’s probably a technical limitation, but if it isn’t I would actually allowed each language to define it’s own scopes instead of trying to define a set of common ones and having languages where not all of them are defined. Sure, there’s a lot of commonalities between PLs, but there’s also a lot of differences which would be quite hard to model properly. IMHO it doesn’t even worth trying to do this.
That’s probably a technical limitation, but if it isn’t I would actually allowed each language to define it’s own scopes instead of trying to define a set of common ones and having languages where not all of them are defined
Yes, today all languages share scope types, and that is in fact a technical limitation that we'd like to remove. Unfortunately, we're dependent on Talon RPC to make that happen, so it's tough to say when exactly we'll be able to move past that limitation
However, even once we are able to have language-specific scope types, consistency is still important. For people who work in multiple languages, consistency is quite helpful. It's one of the nice things about using knausj, for example. You can use roughly the same set of commands to work in many languages. I don't think we need to be dogmatic about consistency, but I'd argue that we should only drop it if we have a good reason to do so.
More concretely, in this case, I would argue that match statements and case statements are conceptually similar enough that we should align the scope types across languages. They have the same elements in all the languages we're talking about here (Python, Typescript, Haskell, and Rust):
In an attempt to reduce cognitive load, I would push for using the same scope types for each of these across languages.
I would argue for the following:
"subject"
. Alternately, I would be tempted to just not have a scope type for this one at all, as you can just use the hat"branch"
. We should also support this for branches of an if
statement"name"
, "key"
, and "condition"
. Note that in eg Typescript, this would not include the case
keyword itself
"key"
because it looks like the left-hand side of a match,"name"
because that's what we use for the left-hand side of assignments, ie even if is a pattern on the left-hand side, so this is kinda similar to that setup. "condition"
because it looks like the conditions of an if
statement with multiple branches"value"
. We could also support "inside branch"
, but that should be follow-up work, because today there are no syntactic scope types that support "inside"
, even though it should be technically quite easy now that #672 has mergedFollowing your great example, @purpleP, I've taken some screenshots 😊
"subject"
/ unsupported"branch"
"name"
/ "key"
/ "condition"
"value"
"inside branch"
And it’s such an integral part of the language that I don’t see much sense adding rust support without pattern matching support.
I think that is fine, as long as we have a fast follow-up PR that introduces it for more languages. I am a bit hesitant to introduce a new scope type that isn't supported by most languages. The follow-up would be a nice first PR for someone fwiw
I think it makes more sense to discuss this while we’re working on Rust support as rust pattern matching capabilities and syntax is more complex than that of Haskell. And it’s such an integral part of the language that I don’t see much sense adding rust support without pattern matching support.
Wait, could you elaborate how Rust’s patterns are more complex? I don’t think I follow.
(I do agree, though, that they’re an essential part of any language which supports them.)
I think it makes more sense to discuss this while we’re working on Rust support as rust pattern matching capabilities and syntax is more complex than that of Haskell. And it’s such an integral part of the language that I don’t see much sense adding rust support without pattern matching support.
Wait, could you elaborate how Rust’s patterns are more complex? I don’t think I follow.
(I do agree, though, that they’re an essential part of any language which supports them.)
Unless some extensions were added to GHC or I am missing something Haskell’s pattern matching can only do the opposite of a type constructor, right (aside from primitive types)? It can only match against a type constructors, right?
And in rust they’ve added a few additional ad-hoc features like slice patterns, guard clauses and ability to match on numeric and alphabetical ranges.
Ohh, I didn't know about those! On the Haskell sided, boolean guards, pattern guards, pattern synonyms, record patterns, and view patterns complicate things as well.
However, I think it'd make sense to start by designing for just the basic patterns on algebraic data types.
@pokey I like your proposal.
Ok I've edited my comment above with some new terms after a discussion with @AndreasArvidsson and @phillco. Tl;dr:
"case"
became "branch"
"condition"
became "subject"
or not supported"name"
added synonyms "key"
and "condition"
See the updated comment for discussion
edit @pokey:
As discussed in https://github.com/cursorless-dev/cursorless/issues/579#issuecomment-1161627378, we'd like to proceed as follows:
Original
There currently is no keyword for selecting alternatives in a match construct. Examples of match constructs are:
or
We probably want three keywords:
matched
to select the value matched on, i.e.,x
;<ordinal> pattern
to select the i’th pattern, i.e.,Alt1
toAltN
above; and<ordinal> case
to select the i’th case, i.e.,exp1
toexpN
above.Unmodified
pattern
andcase
should probably to the scopes relative to the named mark or cursor, i.e.,pattern
refers toAlt1
if the mark or cursor is in eitherAlt1
orexp1
, and similarly forcase
.