ldionne / dyno

Runtime polymorphism done right
Boost Software License 1.0
971 stars 42 forks source link

Consider supporting method definitions in concepts #4

Closed ldionne closed 6 years ago

ldionne commented 7 years ago

This is really just bells and whistles, but it would be possible to have something like this:

struct Drawable : decltype(te::requires(
  "draw"_s = te::method<void (std::ostream&) const>
)) { };

instead of

struct Drawable : decltype(te::requires(
  "draw"_s = te::function<void (te::T const&, std::ostream&)>
)) { };

Of course, the first is just syntactic sugar for the second, but we could also have some more integration of methods with the rest of the library, so that when you write e.g.

poly.virtual_("draw"_s)(std::cout);

it actually passes the this pointer correctly if "draw"_s was defined as a method. This may or may not be worth the added complexity in both the implementation of the library and for learning the library. I really don't want to obscure what the library does with too many features, since it is dead simple at its heart.

ricejasonf commented 7 years ago

I'd argue that there is nary a case where dyno::T is not in the parameter list. If there is some weird case then simply ignoring the first param should not be a problem.

If that is true then why not make it always first?

Also this would be cool:

poly["draw"_s](std::cout);

On a sort of related note, I have been using different types of keys with Dyno like hana::type to signal events.

ldionne commented 7 years ago

I'd argue that there is nary a case where dyno::T is not in the parameter list. If there is some weird case then simply ignoring the first param should not be a problem.

If that is true then why not make it always first?

Because a function could want to be dispatched on a different argument than the first one, for example:

int operator+(int, MyType&);

On a sort of related note, I have been using different types of keys with Dyno like hana::type to signal events.

Interesting, I hadn't thought of that but it's certainly cool that this works. I expect this should work with arbitrary Hana compile-time Comparables.

ricejasonf commented 7 years ago

Because a function could want to be dispatched on a different argument than the first one, for example:

int operator+(int, MyType&);

Perhaps we are talking about different things. When I look at all of the Dyno examples of concept map implementations as well as every Rust Trait implementation I can find, there is always self at the front of the argument list.

The placeholder AFAICT is there for the storage value AKA self, and the user never calls the function with the signature directly unless they are working with poly directly which is just crazy. :stuck_out_tongue:

Maybe I am missing something. I'll have to play with it some more.

I'd like to see an example if you have time, but I know there is the conference coming up.