Gordon Woodhull | 16 Jul 2012 22:35
Favicon
Gravatar

[boost] conversion review report

Hi Vicente, all,

Profuse apologies for the long delay in writing this report.  

Cheers,
Gordon

Report on Boost Conversion Library Review, August 20-29, 2011. 

I want to thank Vicente Botet Escriba for submitting the Conversion library for review and for his general
good nature in receiving criticism and alternate designs.

The Conversion library presents a general framework for plugging in conversion operations between
arbitrary types, providing a consistent interface for type-to-type conversions.  

The library is unfortunately rejected.  During the review, there were two votes for acceptance and two
against, and some interesting conversation from about a dozen participants.

The major reason the library can't be accepted in its current form is that there was near consensus that
there is no universal conversion domain, especially when the source or destination type might be a string.

Much of the review focused on possible One Definition Rule (ODR) violations, which are a consequence of
having a universal customization point using template specializations or function overloads.  Many
solutions were offered, which will make up the second part of this report, "How to Avoid Universality."

I. Concerns about the library

Conversions Are Not Generic?

While some reviewers didn't see the need for a generic conversion library (and I was a little surprised at
the vehemence of their opinions), I don't see this in itself as a reason to reject the library.  The
library's stated purpose is to provide a common interface for general type <-> type conversions, like
lexical_cast does for string <-> type conversions.  However, it was interesting that seemingly no one
could come up with applications of truly generic conversion, although Jeffrey Lee Hellrung and Antony
Polukhin alluded to their existence.

Also, some reviewers pointed out that you often need to choose what kind of conversion to do, and a generic
library can get in the way here.  Strings are the most obvious example: if you are converting from a string
representing a binary value it would not work to use a decimal converter.  Antony Polukhin pointed out a
more subtle example: "lexical_cast<char>(1) and numeric_cast<char>(1) will produce different
output."  

Jeff Hellrung summed this point up nicely: "I think it's certainly possible for different clients using
the same generic component to want different conversion implementations for a given pair of types, and
that point, Boost.Conversion's universally-defined conversion implementations become useless.  One
wants the conversion operation to be parametrized as well as the types involved in the conversion."

Multi-Client Specialization Concerns

Leaving aside possible ODR violations, which we'll return to in Part II, some reviewers questioned the
scalability of using template specialization and overloads when many clients (i.e. independent
headers) may be customizing the behavior.  Vladimir Batov claimed that a system which allows partial
specializations on both Source and Target can't be made to work generally.  Jeroen Habraken said
SFINAE/enable_if "does make code fragile".  I'm not clear if these conversations were resolved (or
resolvable ;). 

Non-Generic Solutions

Some reviewers objected that conversions should just be defined within individual libraries, but of
course this begs the question (as came up recently on the ML between DateTime and Chrono), "which library
should house the conversions?"

Others (such as Phil Endecott) thought that simple c-style functions such as rgb_to_cmyk() were more
explicit and direct.

Why is this so complex?

Kevlin Henney, initially excited about a general solution to the problem which lexical_cast first set
out, commented on the documentation: "Based on casual reading, it feels a little more complex and
requires a higher-entry level of knowledge than would be appropriate for many of the people who actually
need this functionality."

II. How to Avoid Universality

One of the positive results of this review was a small catalog of alternatives to a universal customization
point involving template specialization or overloaded functions.

a. Avoid the Problem

In the strictest sense, any library which allows either kind of universal customization can be prone to ODR
violations.  But many reviewers particularly thought that a customization point involving two UDTs was
especially dangerous.

To his credit, Vicente was very up-front about the limitations of his design, and attempted to formulate
rules for how the library could be used safely.  In the documentation, he suggests (IIUC) that header-only
libraries could use generic conversions as long as they don't define them, or define them as long as they
don't use them.  

http://tinyurl.com/cmbgyfk

b. Inherited tags

John Bytheway suggested a tag-dispatch system where conversions are tagged with their source library,
and any library which depends on conversions from two libraries would define a tag which inherits from the
tags of both libraries.  Thus ODR violations are avoided at the expense of having to specify an extra tag
(effectively a sort of global conversion domain).

http://lists.boost.org/Archives/boost/2011/08/184836.php

c. Conversion Domains and Overloaded Function Objects

Going on the consensus that there is no universal conversion domain, your humble review manager suggested
a metaprogramming solution that defines conversion domain objects which combine a set of conversions
within an object.

http://lists.boost.org/Archives/boost/2011/08/185259.php

A more general solution would be to create an overloaded polymorphic function object, much like a
polymorphic-source version of Lorenzo Caminiti's OverloadedFunction library
(http://tinyurl.com/72nolyj).  However, I have been warned (by Daveed Vandevoorde) that the rules for
function overloading are too dangerously complicated to implement in a metaprogram.

d. Boost.Dispatch

Matthias Gaunard announced that he is working on a library particularly to 
"solve the problem of specializing a function template for a category of types with best-match selection."

http://lists.boost.org/Archives/boost/2011/08/185286.php

e. Abuse of Unnamed Namespaces

Emil Dotchevski suggested that "It might be possible to abuse unnamed namespaces to avoid violating ODR". 
I'm not clear if this was a serious suggestion as it wasn't spelled out.  :)

f. GIL's solution (?)

Christian Henning wrote: "GIL has such functionality. I like their way of structuring conversion." 
However, I was not able to find a description of this mechanism for the report.

Thanks to everyone who participated in the review!

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Gmane