Closed MasonProtter closed 4 years ago
I know what you want.. Although just as what you said, it's antithetical to some goals of MLStyle.
The most flexible class of pattern matching is called first-class pattern matching, in which patterns can be constructed in purely runtime.
function f(pat, x)
match(pat => "Ok", wildcard => "Error")(x)
end
or
function f(pat, x)
case1 = Case(pat, ctx -> ctx.some_var)
case2 = Case(wildcard, _ -> 0)
match([case1, case2], x)
end
It's something I ran into a bit with https://github.com/MasonProtter/PatternDispatch.jl which I found rather frustrating.
Could you explain your concerns somewhere and share them with me?
First-class pattern matching will have the performance issues and impediments about optimization .
Julia's optimizations for constructing data types are not that advanced so far, hence first-class patterns can introduce a lot of memory allocations and bring notable overhead.
Besides, some performance optimizations for pattern matching is expensive to runtime, and usually used in static languages, so as to have practical first-class patterns in Julia, we have to drop these optimizations.
You mentioned generated patterns
Advantages of first-class patterns are quite charming:
@match
is decided once it got compiled/macroexpend
ed, for a first-class pattern, it can sync up with the code patches. So far Python guys are actually introducing first-class patterns, although I don't know if they aware of this fact.
https://www.python.org/dev/peps/pep-0622/#id10
They used to have a __match__
protocol, you can specify the behavior of C(a, b, ...)
by providing a proper C.__match__
.
For patterns like [1, 2, 3]
or (1, 2, 3)
, we can refer to Array.__match__
and Tuple.__match__
.
If possible I hope you could open a thread at discourse. It's quite interesting that I feel like to discuss.
However, this is technically impossible for MLStyle and also violate the design of MLStyle, I have to close it.
I managed to achieve this behaviour with RuntimeGeneratedFunctions.jl and MatchCore.jl. I will make the code public as soon as it's ready. Performance wise, it takes a second to warm up. I think I could get better performance by "pre-generating" the pattern matching runtime generated function that does the job.
It even works at macro expansion time! The main downside is that when matching at runtime you have to specify in which module you are executing the pattern matching block to access externally defined variables though.
I suspect this might be a bit antithetical to the idea of MLStyle as being able to be runtime free, but I think there are cases where you'd really want to be able to specify the pattern at runtime instead of macroexpansion time, even if there is a large performance penalty.
I'm imagining something like
This can be useful if you're programatically generating patterns. It's something I ran into a bit with https://github.com/MasonProtter/PatternDispatch.jl which I found rather frustrating.