Boost logo

Boost :

Subject: Re: [boost] Formal Review Request: TypeErasure
From: Dave Abrahams (dave_at_[hidden])
Date: 2012-06-18 23:39:30


on Mon Jun 18 2012, "Hite, Christopher" <Christopher.Hite-AT-partner.commerzbank.com> wrote:

> Dave Abrahams wrote:
>> > I completely agree with using functors for simple interfaces.
>>
>> By "functors" do you mean runtime-polymorphic function objects?
>
> Not sure they're polymorphic (as in fusion polymorphic - taking
> different parameters). Is there a shorter term "[const?] callable
> (with a particular signature) and copyable."?
> http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/ReadHandler.html
>
> "Deferred Callable Object"
> http://www.boost.org/doc/libs/1_49_0/libs/fusion/doc/html/fusion/functional/concepts/def_callable.html

Sorry, I don't follow any of this. When you say "functors," what do you
mean?

That word has a formal meaning in computer science that is probably not
what you mean, and an informal meaning in C++ (just another word for
"function object") that doesn't /seem/ to be what you mean.
 
>> > Consider this big monster object with this interface. It's not
>> > movable/copyable (maybe it has its own threads).
>> > I think you'd find something like this acceptable.
>> >
>> > struct monster : noncopyable{
>> > typedef signal<void ()>::slot_type slot;
>> >
>> > connection subscribeA(slot);
>> > connection subscribeB(slot);
>> > connection subscribeC(slot);
>> > ...
>> > };
>
>> If it's not movable/copyable it has already failed the test. The
>> idea is to construct a world of values, and this is not one.
>
> What "test"?

I mean, it's not relevant to the argument I'm making about the
feasibility of coding entirely with type-erased value semantics in lieu
of traditional OOP polymorphism.

> You mean for any.

No

> Well you could use any<...,_self&> with it. I'm going to assume your
> "idea" is meant generally for all/most C++.

All non-legacy.

> Let's just say you've got to write a little monster like the one
> above.

I don't need to.

> It's got threads, io_service, mutexes, signal2, containers, sockets,
> etc inside it that don't like being moved/copied and don't need to be.
> What would you do Dave?

I wouldn't write a monster in the first place.

> Would you prefer to put all of monster's guts in a shared_ptr-ed
> pimple so monster can be copied?
>
> This is an honest question. I may be a couple steps behind on best
> practices of C++. I'd probably give the user of monster an object he
> can't move/copy. Is that generally bad? Do you think all objects be
> copy/movable?

I think it's 99.9% reasonable to make all objects movable, and maybe 75%
reasonable to make all objects copyable. You can do either or both of
these, the difference is a matter of degree: just how uncompromising do
you have to be to build a world that makes sense?

>> Didn't we say this was about new code? If you've got legacy stuff
>> like this you do what you have to do.
>
> This scenario could happen to you in the future. How would you write
> monster? At a later point how would you achieve polymorphism of two
> impls of monster?

I wouldn't do it.

>> > Would you do something like this?
>> >
>> > typedef function< connection (slot)> S;
>> > typedef tuple<S,S,S> deleted_monster;
>> >
>> > template<T>
>> > deleted_monster make_ deleted_monster (T&); // uses names ABC
>> >
>> > I think the use case for value based interface for a fat interface
>> > doesn't come up much.
>
>> I don't understand what point you're trying to make.
>
> I'm trying to figure out if you prefer extremely functionally oriented
> code.

I often do.

> Why expose member functions at all? We could just give the user a
> collection of free type-deleted functors.

Because that, by itself, wouldn't achieve runtime polymorphism. You'd
still need to bind the "type-deleted functors" (by which I presume you
mean e.g. std::function) to the object somehow.

> For any copyable object I could take all the member functions, bind
> them with the object, type-delete and return them in a tuple or a
> fusion::map with name tags.
>
> The user can then take any subset of those functions to be an interface.
>
> I think Haskall programmers think like this:
> http://www.haskell.org/haskellwiki/OOP_vs_type_classes#Packing_data_.26_functions_together:_use_.28records_of.29_closures
> Seeing as how C++11 has gotten functional with lambda expressions and
> perfect function forwarding, maybe I need to go check out Haskell.

I recommend it, for mind expansion value if nothing else.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk