|
Boost : |
Subject: [boost] [interest] Type Aspects and compile-time constraints
From: Beren Minor (beren.minor+boost_at_[hidden])
Date: 2012-02-08 17:44:44
Hi everyone,
I would like to introduce a project I'm working on and a mechanism
that emerged from the projects needs and, as far as I could feel, may
be useful in a general case. By lack of words (let say), I named this
Type Aspects, as an analogy to Type Traits.
The project I'm working on, for quite a while now, is about creating a
statically, strongly typed, compile-time checked and heavily
simplified interface to OpenGL. I know that "Boost.OpenGL" is a
subject that has been discussed many times on this list and that every
time the outcome of the discussion is that Boost is not going to
support a mere wrapper around some existing API. Well, I perfectly
understand this and I'm not looking for the possibility to have this
included in Boost. The project itself and its functional goal isn't
actually the subject of my post, but it is a good introduction to type
aspects, as it is what led me writting this as a general supporting
mechanism.
So, to introduce the idea, if some people do not know OpenGL, it is a
typical C API, full of enumerations (well not even enumerations,
integers preprocessor constants), loosely typed, and full of bloated
function names with fixed number of parameters of various flavors.
Obviously, every single function call takes an average of two of those
constants as parameters. And obviously most combinations of values are
leading to undefined operations, whithout having anyone complaining
about anything, except a black window on your screen and a poor-man
error code whenever there is one. Probably the most hideous nightmare
you could ever have to use as a programmer.
That was my observation. So I decided to take all these constants,
that any OpenGL programmer is usually giving directly to feed the
function calls, as parameters, to take all these functions, wrapp them
all, rename related functions to use nice C++ overloading... but above
all, convert these constants as types. This way I was able to write
compile time constraints, checking the combination of constants
provided to these functions.
The goal was (and I must admit that it's working pretty much fine),
that I would certainly be able to write the constraints described in
the OpenGL specifications in term of templated C++ type constraints,
making good use of static assertions with nice messages referring to
the spec itself, and of metaprogramming techniques to achieve this.
Then it appeared, after struggling a while trying to abstract all the
data in use in OpenGL, that I could extract some fundamental
properties of all these types and that the constraints described in
the specifications would be experessed as simple and clear constraints
on these properties. That's what I defined as Type Aspects.
Let say OpenGL is able to handle 10 different type of textures. These
types are different by the way color components are packed together,
by their order, by their precision or numeric type (floating point or
integral). All these are aspects of the texture type. Some OpenGL
function might then be used to load data to a given texture, but
depending on the texture type, it will only accept a certain type of
source data. For example, integral textures only accept integral data,
whereas floating point textures accept any data. This would be
implemented as a simple constraint checking that the "Numeric" aspect
of the source data type is compatible with the "Numeric" aspect of the
texture type.
Moreover, this also allows the user to provide a limited set of these
aspects that he desires to have, and not others that he doesn't care
of, and the compiler would be able to resolve the more relevant type
to use depending on the use case.
Type Aspects, as I defined it for the use in my projects, are like
axises describing a type, every axis taking a value in a given set of
possible values. This is not limited: as these values are types as
well, they can also have aspects and be described. As an example
that's what I did to describe the "Numeric" aspects of OpenGL data.
Numeric aspect takes a value in a given set of predefined numeric
archetypes. Every single archetype then has some values the three
aspects describing a number type: its signness (signed, unsigned,
any), its integralness (floating, fixed point, integral, boolean,
any), and its width (number of bits/bytes, any).
Well to conclude, I can see that this is certainly not related to
OpenGL anymore and that this is a general mechanism that can be used
to describe types and create relationships between types. I don't know
if it is a subject that already has been discussed or if there's
anything like that in Boost already (I don't think so but I don't know
all the Boost libraries by heart). Do you see any interest in this
kind of thing? Do you think that this could be something that worth
working on deeper?
TL;DR:
1. OpenGL sucks, I implemented compile-time constraints wrapping the
functions calls.
2. Thinking about compile-time constraints made me qualify the types
in use with a general mechanism describing the type's "aspects".
3. Aspects are axises and a given set of predefined values on these
axises using which a type and its properties can be described.
4. Constraints can then be easily written as MPL checks on aspects
axises and values as long as type aspects are formalized.
5. Does it already exist? Is that interesing? Should I try to go
deeper in the abstraction?
Kind regards,
-- Beren Minor
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk