Dear OCamlers, In 1994, Barton and Nackman in their book 'Scientific Engineering in C++' [1] demonstrated how one could encode the rules of Dimensional Analysis [2] into the C++ type system enabling compile-time checking (no runtime-cost) of the plausibility (at least up to the dimensional correctness) of computations. In 2004, Abrahams & Gurtovy in 'C++ Template Metaprogramming' [3] showed the Barton Nackman technique to be elegantly implementable using compile time type sequences encoding integer constants. At the end of this post, I provide a complete listing of their example program [4]. The key properties of the system (as I see it) are: - Encoding of integers as types; - Compile time manipulation of sequences of these integer encodings to deduce/produce new derived types. Now, it is not immediately obvious to me how to approach this problem in OCaml. It irks me some that I can't immediately produce a yet more elegant OCaml program for this problem and leaves me feeling like C++ has "got something over on us" here ;) My question therefore is: Does anyone have suggestions/pointers on how to approach automatic dimensional analysis via the OCaml type system? Best, -- Shayne Fletcher [1] John J. Barton and Lee R. Nackman. Scientific and Engineering C++: an Introduction with Advanced Techniques and Examples. Reading, MA: Addison Wesley. ISBN 0-201-53393-6. 1994. [2] Wikipedia http://en.wikipedia.org/wiki/Dimensional_analysis [3] David Abrahams and Aleksey Gurtovy C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond (C++ in Depth Series), Addison-Wesley Professional. ISBN:0321227255. 2004. [4] Code listing: //"c:/program files (x86)/Microsoft Visual Studio 10.0/vc/vcvarsall.bat" x64 //cl /Fedimension.exe /EHsc /I d:/boost_1_55_0 dimension.cpp #include #include #include #include #include #include #include typedef boost::mpl::vector_c mass; typedef boost::mpl::vector_c length; typedef boost::mpl::vector_c time; typedef boost::mpl::vector_c charge; typedef boost::mpl::vector_c temperature; typedef boost::mpl::vector_c intensity; typedef boost::mpl::vector_c angle; typedef boost::mpl::vector_c velocity; // l/t typedef boost::mpl::vector_c acceleration; // l/(t2) typedef boost::mpl::vector_c momentum; // ml/t typedef boost::mpl::vector_c force; // ml/(t2) typedef boost::mpl::vector_c scalar; template class quantity { public: explicit quantity (T val) : val (val) {} template quantity (quantity const& other) : val (other.value ()) { BOOST_MPL_ASSERT( (boost::mpl::equal)); } T value () const { return val; } private: T val; }; template quantity operator + (quantity x, quantity y ) { return quantity(x.value () + y.value ()); } template quantity operator - (quantity x, quantity y ) { return quantity(x.value () - y.value ()); } template quantity < T , typename boost::mpl::transform< D1, D2, boost::mpl::plus< boost::mpl::placeholders::_1 , boost::mpl::placeholders::_2> >::type > operator* (quantity x, quantity y) { typedef typename boost::mpl::transform< D1, D2, boost::mpl::plus< boost::mpl::placeholders::_1 , boost::mpl::placeholders::_2> >::type D; return quantity (x.value () * y.value ()); } template quantity < T , typename boost::mpl::transform< D1, D2, boost::mpl::minus< boost::mpl::placeholders::_1 , boost::mpl::placeholders::_2> >::type > operator/ (quantity x, quantity y) { typedef typename boost::mpl::transform< D1, D2, boost::mpl::minus< boost::mpl::placeholders::_1 , boost::mpl::placeholders::_2> >::type D; return quantity (x.value () / y.value ()); } // -- test #include #include #include int main () { quantity m (5.0f); quantity a(9.8f); quantity f = m * a; quantity m2 = f / a; assert ((std::abs ((m2 - m).value ())) <= std::numeric_limits::epsilon ()); return 0; }