|
Boost : |
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk