-
Notifications
You must be signed in to change notification settings - Fork 21
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
allow named fields in active patterns #1341
Comments
I think that might complicate active patterns too much. What could be done instead is to allow anonymous records in patterns. This would naturally extend an existing feature without requiring a proper design like the one that would be needed for adding fields to active patterns. |
I'd like to be able to deconstruct those partially, but there is still the concern of active patterns being ingrained for the kind of thing that my suggestion touches on, it is right in the guidelines: Given this less than ideal situation, I'm feeling partial deconstruction, and ability label fields is orthogonal to "pattern match anonymous records". I've spent some time considering how anonymous and named records are used in context of DU while I was pondering on sharing this suggestion (idea if there would be a possibility to use record syntax for DU case which has all fields named, but it could be ambiguous); it still feels (to me) this suggestion, and the infrastructure to deal with named fields without changing the representation (like C# for tuples), could be a good fit to active patterns, especially in the context they are recommended for in terms of ABI, but tend to pale in terms of tooling & analysis support compared to matching the concrete representation. I could see this infrastructure as being useful in other contexts, and maybe, already present in context of non generative type providers. edit: I'll add that for context of binary compatibility that active patterns are advertised for, I feel not allowing names, and only using positional is actually problematic. |
That's exactly what you can do with record patterns. |
I'll consider an update to the design guideline, in meantime this suggestion or other enhancements to active pattern comes up, I think the recommendation with active pattern should be that they ideally return a record to allow partial and named deconstruction. The issue with record is then they don't allow positional, which is also what people may want. This is something only DU allow (picking named or positional, and named allowing partial deconstruction), and somehow, it feels active pattern should allow the same. |
Active patterns act a bit like a tailored callback which is a predicate, conceptually close to a function signature (type signatures, those things "ideally always" need to give the possibility to attach a label on top of the positional type/value. C# allows this kind of "extra meta info" on the tuples, F# has the anonymous record types (but their il representation is like a record AFAIK), CompiledNameAttribute, non generative type providers, where some kind of "name possibly only in metadata, not IL name of members" situation occurs. We could change the underlying representation of active pattern to an anonymous DU, and have a syntax to define the name, which works like DU, but defined in the banana clips to meet this suggestion. I also don't understand how the design guideline around it helps with binary compatibility / hiding representation. Having an active pattern layer sounds like having a specific "visitor pattern" implemented, but this thing can also change over time like a DU (but with no naming of fields possible, so far); a visitor pattern that is manually implemented though (the impl. body of the active pattern is a visitor pattern, but which only allows a single call, and no naming of arguments), can have use for repeated calls, or submitting several patterns, rather than a single return value, to help maintain binary compatibility / hiding representation. In context of pattern matching, and using active patterns for binary compat, as we know, it would just match the first case that is in the This could specifically be a feature in the language around DUs (a way to add a visitor layer API, that is hand written, but attached to the type), that would generate visitor interface with extensible set of callbacks, that are possibly "API or representation"-change resistant, encapsulated in the active pattern concept of F# but maybe some other ways as well (to vend an interface of type "visitor pattern"). I think by now, this suggestion is just an area of reflection about active patterns, representation, and expressivity of the match (allowing or not named and positional, etc.); if the specific suggestion in the top post doesn't meet interest, maybe we can transfer the issue as a discussion. Aside, along your line of reasoning, maybe F# can have a special syntax for the mighty "anything deconstructor" that would express the match as an anonymous record? It is separate usefulness than what I'm after (active patterns should enable labels on the values, similar as some think the same should apply to Rather than adding "one more syntax specific to anonymous record", we can consider if there is something we can do with "anonymous record" syntax in the context of pattern match, so it could unify different syntaxes by supporting it on more things than anonymous record, but be the path towards a more general pattern matching. |
I'm trying to use a library which exposes active patterns instead of the data types with their internal definition.
https://github.com/fsprojects/FSharp.Data/blob/8a6688f34abede0a80306e6c802601ef74edf473/src/FSharp.Data.Html.Core/HtmlActivePatterns.fs
The experience isn't as good as direct access to the representation, but it could be improved:
I suggest we allow active patterns to define field names:
Here, I defined the field names explicitly (this is just a suggested syntax).
Possibly, if those aren't defined, but the value given is a plain identifier like in the code above, it would put the equivalent of
nameof identifier
for the name.Possibly, we would issue a warning (on by default in new projects), when the names are not defined.
If we don't want to change the representation, we may make this work like C# value tuple with names work.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-tuples#tuple-field-names
The deconstruction syntax would allow partial deconstruction, using the usual syntax with explicit field names instead of positional one.
We may also allow the constructor syntax to specify the names (and have a check that enforces consistency):
The text was updated successfully, but these errors were encountered: