Report not yet implemented feature at runtime

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Report not yet implemented feature at runtime

Samuel Debionne
Hi,
The rational of this proposed feature is the following (pseudo code) :

variant<point_xy, point_xyz, polygon_xy, polygon_xyz> geometries_t;
geometries_t a, b;

bg::within(a, b);

With the present implementation this code would not compile since
within() is not implemented for all the combinations of the bounded
types of the variant (not_implemented uses MPL_ASSERT to report this
error at compile time).

The following proposal introduce an other mechanism to report
incompatible type (or not yet implemented features) at runtime and is
prototyped here :

https://github.com/boostorg/geometry/compare/develop...sdebionne:feature/nyi_runtime_error

The specifications are :

- maintain backward compatibility (default to compile time error)
- specialization on a per algorithm basis and per compile unit (meaning
that some part of the applications may use compile time errors while
other part may use runtime errors)
- should be quite easy to adapt the existing algorithm (see the example
with within)

I can't think of a solution to implement this as a pure extension (e.g.
without modifying the core library). In short, this is what I have in mind :

An algorithm should be identified by an "algorithm tag" (this could be
extended to strategies as well) :

BOOST_GEOMETRY_REGISTER_ALGORITHM(within)

At the dispatch stage, the algorithm inherit from the new
not_implemented<> interface that takes the algorithm tag as first
template parameter :

template <...>
struct within
  : not_implemented<within_tag, Tag1, Tag2>
  {};

Finally, in the code that invokes the algorithm, set whether to use
runtime errors:

// Enable runtime errors
BOOST_GEOMETRY_NYI_RUNTIME_ERROR(within_tag)

try {
  bg::within(a, b);
} catch (bg::not_implemented_runtime_error& ex) {
  std::cerr << ex.what() << " is not yet implemented."
}

Is there any interest in this feature?
_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Samuel Debionne
An alternative to Variant could be type erasure.

Before trying out this solution, has someone already try to use
Boost.TypeErasure to implement, for example, any_point<> ?

More generally, if input types can vary at runtime (for example, if they
depend on user input), is there any recommended solution for
Boost.Geometry user ?


Le 09/03/2015 18:58, Samuel Debionne a écrit :

> Hi,
> The rational of this proposed feature is the following (pseudo code) :
>
> variant<point_xy, point_xyz, polygon_xy, polygon_xyz> geometries_t;
> geometries_t a, b;
>
> bg::within(a, b);
>
> With the present implementation this code would not compile since
> within() is not implemented for all the combinations of the bounded
> types of the variant (not_implemented uses MPL_ASSERT to report this
> error at compile time).
>
> The following proposal introduce an other mechanism to report
> incompatible type (or not yet implemented features) at runtime and is
> prototyped here :
>
> https://github.com/boostorg/geometry/compare/develop...sdebionne:feature/nyi_runtime_error
>
> The specifications are :
>
> - maintain backward compatibility (default to compile time error)
> - specialization on a per algorithm basis and per compile unit (meaning
> that some part of the applications may use compile time errors while
> other part may use runtime errors)
> - should be quite easy to adapt the existing algorithm (see the example
> with within)
>
> I can't think of a solution to implement this as a pure extension (e.g.
> without modifying the core library). In short, this is what I have in mind :
>
> An algorithm should be identified by an "algorithm tag" (this could be
> extended to strategies as well) :
>
> BOOST_GEOMETRY_REGISTER_ALGORITHM(within)
>
> At the dispatch stage, the algorithm inherit from the new
> not_implemented<> interface that takes the algorithm tag as first
> template parameter :
>
> template <...>
> struct within
>   : not_implemented<within_tag, Tag1, Tag2>
>   {};
>
> Finally, in the code that invokes the algorithm, set whether to use
> runtime errors:
>
> // Enable runtime errors
> BOOST_GEOMETRY_NYI_RUNTIME_ERROR(within_tag)
>
> try {
>   bg::within(a, b);
> } catch (bg::not_implemented_runtime_error& ex) {
>   std::cerr << ex.what() << " is not yet implemented."
> }
>
> Is there any interest in this feature?
> _______________________________________________
> Geometry mailing list
> [hidden email]
> http://lists.boost.org/mailman/listinfo.cgi/geometry
>

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Mats Taraldsvik-3

> -----Opprinnelig melding-----
> Fra: Geometry [mailto:[hidden email]] På vegne av
> Samuel Debionne
> Sendt: 13. mars 2015 11:53
> Til: Boost.Geometry library mailing list
> Emne: Re: [geometry] Report not yet implemented feature at runtime
>
> An alternative to Variant could be type erasure.
>
> Before trying out this solution, has someone already try to use
> Boost.TypeErasure to implement, for example, any_point<> ?
>
> More generally, if input types can vary at runtime (for example, if they
> depend on user input), is there any recommended solution for
> Boost.Geometry user ?
>

Just a heads up from a Boost.Geometry user. :)

I think that using type erasure might be a good approach.

Boost.Geometry already uses boost::concepts, which will be adopted into the C++ standard/TS with Concepts Lite.  Andy Prowl proposed(1) virtual concepts, which is a runtime (type erased) concept, which corresponds to boost::type_erasure.

There is a rumour that Andrew Sutton is also working on virtual concepts, like Andy Prowl proposed, so we might get this into a future standard/TS as well.

Therefore, using type erasure with boost::type_erasure might be a sound approach that complements the existing concepts-driven architecture in boost.geometry.

(1) https://groups.google.com/a/isocpp.org/d/topic/std-proposals/4gEt2OBbSQM/discussion 

Regards,
Mats Taraldsvik

>
> Le 09/03/2015 18:58, Samuel Debionne a écrit :
> > Hi,
> > The rational of this proposed feature is the following (pseudo code) :
> >
> > variant<point_xy, point_xyz, polygon_xy, polygon_xyz> geometries_t;
> > geometries_t a, b;
> >
> > bg::within(a, b);
> >
> > With the present implementation this code would not compile since
> > within() is not implemented for all the combinations of the bounded
> > types of the variant (not_implemented uses MPL_ASSERT to report this
> > error at compile time).
> >
> > The following proposal introduce an other mechanism to report
> > incompatible type (or not yet implemented features) at runtime and is
> > prototyped here :
> >
> >
> https://github.com/boostorg/geometry/compare/develop...sdebionne:feat
> u
> > re/nyi_runtime_error
> >
> > The specifications are :
> >
> > - maintain backward compatibility (default to compile time error)
> > - specialization on a per algorithm basis and per compile unit
> > (meaning that some part of the applications may use compile time
> > errors while other part may use runtime errors)
> > - should be quite easy to adapt the existing algorithm (see the
> > example with within)
> >
> > I can't think of a solution to implement this as a pure extension (e.g.
> > without modifying the core library). In short, this is what I have in mind :
> >
> > An algorithm should be identified by an "algorithm tag" (this could be
> > extended to strategies as well) :
> >
> > BOOST_GEOMETRY_REGISTER_ALGORITHM(within)
> >
> > At the dispatch stage, the algorithm inherit from the new
> > not_implemented<> interface that takes the algorithm tag as first
> > template parameter :
> >
> > template <...>
> > struct within
> >   : not_implemented<within_tag, Tag1, Tag2>
> >   {};
> >
> > Finally, in the code that invokes the algorithm, set whether to use
> > runtime errors:
> >
> > // Enable runtime errors
> > BOOST_GEOMETRY_NYI_RUNTIME_ERROR(within_tag)
> >
> > try {
> >   bg::within(a, b);
> > } catch (bg::not_implemented_runtime_error& ex) {
> >   std::cerr << ex.what() << " is not yet implemented."
> > }
> >
> > Is there any interest in this feature?
> > _______________________________________________
> > Geometry mailing list
> > [hidden email]
> > http://lists.boost.org/mailman/listinfo.cgi/geometry
> >
>
> _______________________________________________
> Geometry mailing list
> [hidden email]
> http://lists.boost.org/mailman/listinfo.cgi/geometry
_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Samuel Debionne
> Just a heads up from a Boost.Geometry user. :)
>
> I think that using type erasure might be a good approach.
>
> Boost.Geometry already uses boost::concepts, which will be adopted
> into the C++ standard/TS with Concepts Lite.  Andy Prowl proposed(1)
> virtual concepts, which is a runtime (type erased) concept, which
> corresponds to boost::type_erasure.

Thank you for the head up, interesting read, it seems that Type erasure
and virtual concepts are here to stay.

I don't think it will solve all my problems of input types that vary at
runtime, since a any_geometry<> type would be a mix of
different/incompatible concepts. That may help to reduce the number
instantiated template, having a single point type for all the xy, xyz,
xym xyzm variants. I'm going to give it a shot and report.
_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Samuel Debionne
> That may help to reduce the number of instantiated template, having a
> single point type for all the xy, xyz, xym xyzm variants.

I was thinking out loud (wrongly). What would be actually possible to
implement is, for example, any_point_double_2_cs<>, for 2D points with
double coordinate and cartesian system. Interesting only for use case
where multiple models of the same Concept are used...

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Bruno Lalande
Hi,

Boost.Variant is a high level type erasure library, just like Boost.Any. Just because we currently support variants doesn't mean we shouldn't support Any (or a more specialized equivalent) or any other form of type erasure applied to our library.

I've been thinking for very long about using algorithm tags to identify our algorithms and give them specific characteristics which could then be used in many ways. What you are proposing is one of the possible usages. So yes, the approach could make sense.

Regards
Bruno

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Samuel Debionne
Hi,

> Boost.Variant is a high level type erasure library, just like
> Boost.Any. Just because we currently support variants doesn't mean
> we shouldn't support Any (or a more specialized equivalent) or any
> other form of type erasure applied to our library.

I agree the two are not exclusives and even serve different purposes.
Menelaos has reminded me something you wrote about variant that I would
like to quote here :

> I think Bruno in a private email exchange explained it in a very
> nice way: variants are not geometries. Support for variants in
> Boost.Geometry does not mean that variants are understood as
> geometries, but rather than Boost.Geometry is variant-aware (i.e.,
> it can handle variants).

Variants are not geometries and are "resolved" very early in the
algorithm stages so that the penalty of using type erasure remains low.
In the other hand, any_point would be a geometry and a direct
replacement of an other model. But it would not be able to hold several
types that implement different concepts (while variant can).

> I've been thinking for very long about using algorithm tags to
> identify our algorithms and give them specific characteristics which
> could then be used in many ways. What you are proposing is one of
> the possible usages. So yes, the approach could make sense.

Good to hear that you had a similar idea. What other applications of
algorithm tags do you have in mind ?

In the prototype I mention in the origin post, there is more that just
deciding if a not yet implemented (nyi) algorithm should static assert
or throw. It also requires that every single nyi feature to compile,
that is even for inapplicable type combinations. For that, a fake
implementation should be provided for algorithms but also for
intermediate results (see not_implemented_result_handler). While my
solution works it requires to inspect and fix every algorithm/strategy
implementation. Do you have any idea how to solve this problem with a
less intrusive solution ?

Moreover, I think I was quite lucky to pick the within algorithm as an
example, intersection would have been much more challenging since the
result type depends on the input types. It would be nice if such
algorithm expose a meta function to compute the result type...

Finally, here is a blog post from the MySQL team that covers part of
this topic.

http://mysqlserverteam.com/author/david/

> Note that for some binary GIS functions, some type combinations are
> inapplicable or not supported, and we return false or NULL
> respectively for such cases.
>
> Undefined/inapplicable type combinations for each function are:
>
> overlap: any combination of two argument types of different dimensions
> crosses: any of the two argument types is point or multipoint
> touches: the 1st argument is polygon or multipolygon, AND/OR the 2nd >
argument is point or multipoint

Unfortunately, it does not elaborate on the solution they use to
"filter" these type combinations.

Regards,
Samuel
_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Report not yet implemented feature at runtime

Bruno Lalande
Hi Samuel,

Sorry for the big delay in answering this.

Variants are not geometries and are "resolved" very early in the
algorithm stages so that the penalty of using type erasure remains low.
In the other hand, any_point would be a geometry and a direct
replacement of an other model. But it would not be able to hold several
types that implement different concepts (while variant can).

Yep, I would agree with such a use of Boost.Variant to implement any_point, and yes, unlike variants this one could be considered a geometry as the underlying concept is known at compile-time.
 
> I've been thinking for very long about using algorithm tags to
> identify our algorithms and give them specific characteristics which
> could then be used in many ways. What you are proposing is one of
> the possible usages. So yes, the approach could make sense.

Good to hear that you had a similar idea. What other applications of
algorithm tags do you have in mind ?

Algorithms would declare their characteristics in an aspect-oriented way: arity, which input params are variant-able, what's the default result type, default strategy, which input-params are commutative, and so on. With this + the actual per-type implementation, you would have nothing else to write to spawn an algorithm. All the boiler plate stuff that currently happens in the multi-stage dispatching (variant handling, commutation, handling, etc.) would be generated for you by the Boost.Geometry framework (which of course would be the tricky part to write).
 
In the prototype I mention in the origin post, there is more that just
deciding if a not yet implemented (nyi) algorithm should static assert
or throw. It also requires that every single nyi feature to compile,
that is even for inapplicable type combinations. For that, a fake
implementation should be provided for algorithms but also for
intermediate results (see not_implemented_result_handler). While my
solution works it requires to inspect and fix every algorithm/strategy
implementation. Do you have any idea how to solve this problem with a
less intrusive solution ?

This is why we first need to have algorithms declare themselves in the way I'm describing above. I see this as the building block to many things.
 
Moreover, I think I was quite lucky to pick the within algorithm as an
example, intersection would have been much more challenging since the
result type depends on the input types. It would be nice if such
algorithm expose a meta function to compute the result type...

It's always difficult to choose whether to start from the easiest or the hardest. For variant I chose the former approaches as I was fairly confident there would be no showstopper with the more sophisticated algos. For this one I think whatever solution you come up with should be validated with the most complicated algo before the first commit, just to check feasibility.

Regards
Bruno

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry