
Steven wrote:
To the extent possible, the library should rely only on compile time accessors, IMO. This does not preclude having the points also provide runtime accessors
for users. It might work to allow either compile time access or runtime access and
if either one is not given, fall back to implementing it in terms of the other.
The problem is that doing so makes the isotropic programming style I alluded to in my reply to Bruno less workable. The isotropic style is pervasive in my library, and defines it, to a great extent. This style is a BKM for geometric programming that we have developed, and the library is the means of propagating the BKM throughout the developer community. I can't be expected provide runtime parameters on all API for the user's convenience then implement flow control in every case to convert the runtime parameter into compile time constants and different instantiations of template functions guarded by flow control. Particularly since I frequently use the isotropic data type as the index into an array, it seems silly to instantiate a different function for every index value. Moreover, I have defined a rich language of isotropic types, conversions and behaviors which isn't compatible with compile time parameters because the constant has to be a built in type and not an object. This breaks down the type safety of the parameter and waters down the usefulness of the isotropic objects, since they can't be used as template parameters. The following does not compile (I wish it did): const orientation_2d horizontal_constant; template <orientation2d orient> coordinate get(const point& pt) { return coord_[orient.to_int()]; } coordinate value = get<horizontal_constant>(my_point); because orient has to be a built in type. If you throw away the isotropic types: direction_1d, orientation_2d, direction_2d, orientation_3d, direction_3d, winding_direction then you lose the type safety and the rich language of behaviors provided by the library. What good are these types if they can't be used in the accessor? We both have the same intent of improving programming practices through library development. The way people code geometry typically looks like: if(condition) point.x() = value; else point.y() = value; You are advocating a style: if(condition) point.get<0>() = value; else point.get<1>() = value; and I am advocating: point.get(condition) = value; I agree that compile time access is better than having two completely different functions. However, it leads the developer back to using flow control instead of data to control the behavior of their code, increased code bloat (in the user's code) and reduced code quality. Isotropy is somewhat unique to geometry because the exploitation of geometric symmetry to refactor code doesn't really translate to all other domains. In general, you are probably right that compile time accessors should be preferred, but for geometry, isotropic style should be preferred. We should think about what best accomplishes our goals rather than base decisions on a meme. I realize that my library is somewhat unique among geometry libraries in that others don't use isotropy or do to a lesser and less formalized extent. That uniqueness is what makes the library good. Isotropy is a huge improvement in geometric programming over the common practice. That is why the interface requires the user to access coordinates with the isotropic (runtime) type-safe parameter; it encouraging the user to adopt the best practice. That improvement is what we are trying to get into the hands of geometry library users by submitting the library to boost. Thanks, Luke