$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] An alternative approach to TypeErasure
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-06-24 18:23:08
AMDG
On 06/24/2012 02:53 PM, Pyry Jahkola wrote:
> On 2012-06-24 18:34:13 +0000, Steven Watanabe said:
> 
>> On 06/24/2012 08:13 AM, Dave Abrahams wrote:
>>>
>>> Very interesting.  Does either approach support operator overloading?
>>
>> Yes.  I put quite a bit of effort into making
>> sure that operator overloads would work
>> correctly.
> 
> I started the work on operator overloading, as you might guess when
> seeing the file
> 
>    include/poly/operators.hpp (names in this file will definitely change)
> 
> I didn't get so far that poly::interface would actually recognize these
> callables and create the corresponding operators for itself, but that
> sure is possible.
> 
If you have to create special cases for these
in the core library, you're doing it wrong.
> More importantly, I'm still kind of missing the point of why the feature
> of operator overloading is really needed. In essence: How should binary
> operators behave? Steven's TypeErasure defines binary operators such
> that only when the wrapped types of a and b are the same, can you sum
> them up: "a + b".
> 
> But where would you use this kind of an "any", where only some of the
> instances can be added up, and others cause undefined behavior? Wouldn't
> you actually do the addition on the side where you know the types, and
> not on the type-erased side?
> 
Binary operators like this require you to have
a coherent set of objects.  You can't just
take two random objects from two different
sources and combine them.
There are also a few special cases where binary
operators can have a reasonable default behavior
when the types don't match.  For example,
equality_comparable<> and less_than_comparable<>
can test the stored /types/ first before testing
the value.
> Do we really have a real world use case that would prompt us to
> implement features like operator overloading?
> 
any_iterator.
Also, you're confusing two separate issues.
Operator overloading is a separate issue
from binary methods.  Some operators, like
ostreamable<> or incrementable<>, would
normally only take one any argument.
> * * *
> 
> Before releasing more worms from the can of type-erased operators, I
> must confess that I know still too little about the possible uses for
> type erasure / expression problem / what you name it. What I propose is
> we should look into how e.g. Haskell and Clojure programmers use their
> type classes and protocols.
> 
> For one thing, I could only think of few examples where the interface
> would have mutating functions. (Anybody care to throw in more examples?)
> 
> More typical use cases (that I could think of) are functions which read
> the wrapped type (as const reference), and then either (1) return a
> value, or (2) cause a side effect:
> 
>    std::string(to_html_, self const &);        // (1) "pure" function
>    void(print_, self const &, std::ostream &); // (2) side effect
> 
> Maybe if the whole interface is about wrapping some sort of computation
> or side effect, it might make sense to have some non-const functions too:
> 
>    using progress = interface<
>        std::size_t(total_progress_, self const &),
>        std::size_t(current_progress_, self const &),
>        void(run_for_, self &, std::chrono::microseconds)>;
> 
> Or maybe it's modeling a kind of a container and you can insert items
> into it:
> 
>    using container = interface<
>        void(insert_, self &, std::size_t, content),
>        void(remove_, self &, std::size_t),
>        content &(at_, self &, std::size_t),
>        content const &(at_, self const &)>;
> 
In Christ,
Steven Watanabe