Le 18/11/14 23:59, Matt Calabrese a écrit :
Cool, thanks for starting this thread.
On Tue, Nov 18, 2014 at 1:40 PM, Nevin Liber
wrote: It's the inversion of control that people just don't like.
Perhaps harsh, but this just sounds like a general dislike of high-order functions, which is somewhat absurd to me. How is it any more problematic from simply dispatching a function over fully known types at compile time, or a high-order function that takes a function object and n arguments, then forwards them along to the function object /without/ visitation? All variant visitation logically does extra is transform the arguments based on their discriminator before passing them along.
I think this is the same complain we have often about future.then respect to await expressions. People want to write their code on line. Even if lambdas provide something better than functions there is yet too much noise. In Haskell there is the do-notation to cover the same intent. Haskell has already a match on types and there is no need for visitors. I hope C++ will add Sum types and Pattern matching soon. Independently of this features, I think that we can have a more generic visitation function that will be quite close to pattern matching on types.
Perhaps to make things more clear, what if instead of type transformations of variant to underlying type they were simply value transformations. In other words, would you have a problem with a high order function that takes a function object and 10 ints, but it incremented each int by 5 before passing each one along to the other function object? Would there be a problem with this? What if instead of incrementing by 5, it cast each argument to float? If people don't have a problem with any of these situations I simply do not see why they'd have a problem with something like apply_visitor.
I haven't :)
Further, visitation of a variant gives you /exactly/ the same overload resolution that you'd get for the underlying type of the variant type(s) being known at compile time (I.E. ordering, template pattern matching, etc.). Because of that, it is exactly as capable as compile-time overload resolution, plain and simple. It has no more or fewer problems in terms of capability with respect to basic overload resolution because that's exactly how it is implemented. I wouldn't consider it lacking unless it is also considered that basic overload resolution is lacking. While /that/ may be true, it doesn't make sense to expect visitation to change that (nor should it, IMO). People understand basic overload resolution so they understand the matching that takes place when doing visitation.
Agreed.
All that said, I do agree with problems of visitation when you do not have a closed set of types, but that simply is not the case with a variant, which is why it can be as powerful as it is in practice. Visitation of a variant really does do exactly what the user wants (and nothing more). It's also telling that the visitation is implemented in essentially the same way that someone would manually implement it if the abstraction were not there.
Anyway, I've heard this argument before, and I just don't understand it. As someone who really does use variants every single day, I have not understood the criticisms at all. It just sounds as though /valid/ criticisms of visitation in something like a class hierarchy are now being erroneously applied to visitation in the context of a discriminated union, which just doesn't really make sense. We're not talking about visitation into a class hierarchy or visitation into an "any."
Visitation in any is more expensive, but I believe it is a better alternative to any_cast, when you know that you can have one of N types.
The discussion in Urbana on n4218
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4218.pdf (variant), which didn't propose visitation, basically amounted to we don't like visitation but we need it unless something better comes along.
It really is a fundamental operation of a discriminated union. As someone who uses variants pretty much as the "default" for run-time polymorphism in day-to-day coding, I have never seen an actual explanation for what someone might consider bad about variant visitation, neither from Bjarne nor anyone else.
While I don't want to speak for Bjarne, I believe he would rather have some form of Pattern Matching < http://www.stroustrup.com/OpenPatternMatching.pdf> and possibly variant as a language feature. That being said, no one has proposed it.
I've read that paper before and will read it again tonight, but briefly IIRC it was concerned with open sets of types. If you applied the approach to variants all you'd get is a less efficient solution than visitation and I simply don't buy the gains.
Again, I'll go back and reread the paper as I don't want to be too critical without it fresh in my mind, but IMO it just did not apply to discriminated unions, which is what we have with a variant.
I don't know where Dr. BS wants to go, but if we have the possibility on the language to define Sum types (variant), pattern matching should be optimized for them. I think Sum types are the missing on the trilogy + Product types (tuple/struct) + Sum types (variant/union) + closures/lambda functions Oh, I forgot, I like also inheritance ;-) Best, Vicente