Earlier quoted context omitted.
> I've found the DLR is just as fast... with a much lower overhead Can you expand on this? I would not have expected that it would be faster than compiled expressions.
The codegen creates a cache of delegates (created using expression trees), but uses a structure more suited to the problem than a simple ConcurrentDictionary. [1]: http://geekswithblogs.net/simonc/archive/2012/07/20/inside-t...
Pattern Matching for Java
131–140 of 152 posts
Re: Pattern Matching for Java
#132Would be really great to see this make it's way into the language. Here are some ways I've found to work around its absence: * adding a match() function to a common base type. So if it could have subtypes Foo(x), Bar(y, z), then the signature would look like: T match(Function foo, BiFunction bar); * in the cases where I don't have control over the common base type, I've written a builder pattern that constructs a seq…
Just use another language if you want pattern matching so badly. Twisting Java to look like Scala doesn't do the language justice.
Re: Pattern Matching for Java
#133Earlier quoted context omitted.
would you be able to give me a pseudo code example of things that are easy to do with pattern matching, but not multiple dispatch? I'm intrigued, I always considered them equivalent.
Here's some concrete examples in Rust: http://pzol.github.io/getting_rusty/posts/20140417_destructu... It's not just about finding the right bit of code to run; it's also about pulling some fields out of the polymorphic value so they're available as nice short names, without qualification.
C# is a weird beast though - it's pure OO on some level, but then keeps making getters and setters even easier to write. It's easier to write an "object" where every field has a getter and setter, than it is to write an actual constructor for private variables, so that's what people do.
Re: Pattern Matching for Java
#134Why the fixation on pattern matching? Don't get me wrong, I enjoy the benefit it provides, but for OO code multiple dispatch is a more elegant and idiomatic way to solve the "I don't want to implement the visitor pattern" problem. FYI, I recently found out that C# can actually do multiple dispatch https://blogs.msdn.microsoft.com/shawnhar/2011/04/05/visitor...
To me it seems pattern matching without possibility to actually enforce that all cases are matched seems to miss the most useful scenario: What I want to do is create proper sum types. For some reason most OO languages were designed around the idea that being "open for extension" was a good thing. Normally if I make a base class, I want a closed and known set of sub classes. E.g. if I make a payment method then I wan…
It's equivalent of
_ -> default_function
At the end of a pattern matching statement.Essentially it's impossible for not all the cases to be matched, as far as I can see.
Re: Pattern Matching for Java
#135Earlier quoted context omitted.
Why does multiple dispatch bring type unsafe dynamism or runtime errors? Or do you just mean C#'s implementation of multiple dispatch?
Yep, there is no way to check the exhaustiveness in the compile time. Say you have an Expression parent class and a list of child classes: say Add, Const, Var, and a corresponding visitor. Add new child class, and the visitor would be non-exhaustive. Multiple dispatch is not very different in that sense. I think that Alan Key spoke about dynamic nature of OOP, that's one of the examples. Even in the statically typed…
class Expression {}
class Add : Expression {}
class Const : Expression {}
class Var : Expression {}
void FSpecialization(Expression e1, Expression e2) { ... }
void FSpecialization(Const c, Var v) { ... }
...
void F(Expression e1, Expression e2)
{
FSpecialization(e1 as dynamic, e2 as dynamic);
}
How is this not exhausted? Any new sub class of expression will be routed through to the first FSpecialization. Same as it would with a _ -> default_f
in algebraic pattern matching.Re: Pattern Matching for Java
#136Earlier quoted context omitted.
A dynamic type is probably just implemented as a tagged bit of data, surely. Which is the exact same way an algebraic datatype would be done. So I dunno why it would be any slower. I think the safety thing is a non issue as well - what arguments could you pass in to the statically typed function that would cause the use of dynamic to bite you in the ass?
> I think the safety thing is a non issue as well - what arguments could you pass in to the statically typed function that would cause the use of dynamic to bite you in the ass? None if the function is written correctly, but by that logic you don't need type safety at all. The point is that the dynamic technique gives you no warning if you forget to implement one of the cases.
void React(Animal me, Animal other)
{
ReactSpecialization(me as dynamic, other as dynamic);
}
Unless you pass in a casted value here, it's fool proof.Re: Pattern Matching for Java
#137Earlier quoted context omitted.
I am talking about what value you could pass into the multiple dispatch code in the article I linked to. I know you can cause run time type errors using dynamic in general, but in the code I linked it was very well contained and water tight. Dynamically typed languages usually represent objects as something like a struct with an int tag to represent the type, and a void pointer for its value. The actual reflection go…
> I am talking about what value you could pass into the multiple dispatch code in the article I linked to Ah, I misunderstood the question. Yes, in that case it's fairly type-safe. > The actual reflection going on in the code I posted for multiple dispatch would surely be nothing more than an int comparison Is this based on gut reaction or are you talking about optimizations that `dynamic` performs? I ask because my…
But to answer your question - yes, entirely based on gut reaction and what a compiler would ideally be able to do given the code posted. So very probably wrong.
Re: Pattern Matching for Java
#138Earlier quoted context omitted.
That's not the important/valuable use case for what people normally refer to as "pattern matching".
I've recently found dynamic pattern matching pretty valuable to completely replace REST-like server-side APIs with a data-oriented API that gets pattern matched and dispatched based on the actual values and shapes of the data structure. It helps almost completely avoid the /get/this /get/that /set/those explosion of API getters and setters that ultimately leads to very complex client logic that makes any notion of co…
Re: Pattern Matching for Java
#139Earlier quoted context omitted.
> I think the safety thing is a non issue as well - what arguments could you pass in to the statically typed function that would cause the use of dynamic to bite you in the ass? None if the function is written correctly, but by that logic you don't need type safety at all. The point is that the dynamic technique gives you no warning if you forget to implement one of the cases.
My point was that the dynamic technique in the posted code was written in a very small, contained point where it would be impossible due to the signature of the surrounding argument for it to go wrong. void React(Animal me, Animal other) { ReactSpecialization(me as dynamic, other as dynamic); } Unless you pass in a casted value here, it's fool proof.
Re: Pattern Matching for Java
#140Earlier quoted context omitted.
My point was that the dynamic technique in the posted code was written in a very small, contained point where it would be impossible due to the signature of the surrounding argument for it to go wrong. void React(Animal me, Animal other) { ReactSpecialization(me as dynamic, other as dynamic); } Unless you pass in a casted value here, it's fool proof.
The point is that if you forget to write one of the ReactSpecialization methods nothing detects it. Perhaps more importantly, if you add a new type of Animal there's nothing to tell you you need to write a bunch of new ReactSpecializations.
As an OO apologist I do feel compelled to point out that
type Animal = Cat | Dog | Mouse
let react = function (a, b)
| Cat, Dog -> ...
...
| x, y -> $"{x} is not interested in {y}."
Would suffer from the exact same issue though.