[GSoC Proposal] Statically Checked Measurement Units

Cristi Cobzarenco cristi.cobzarenco at gmail.com
Tue Mar 29 15:20:13 PDT 2011


Well they don't _have_ to be the same type as long they're convertible to
one another, and one can make sure they're convertible based on the result
of the double-inclusion. It does make more sense for them to be the same
type, I agree, therefore I'll be sticking to the .mangleof version. Dummy
objects are fine, the only problem is the fact that one has to define the
extra objects (and, when one wants to count objects, you'll need to define a
different type). I was also considering shorthand symbols, since it seems
like a natural addition, I'll have think a bit more on how exactly to do
that, to avoid collisions.
Regarding if this is appropriate for GSoC. It doesn't take me 12 weeks to
write a prototype, sure. But to have a library fit to be part of the
standard library of language takes a lot of laborious testing, going through
use-cases and making sure it is highly usable. Also, there should be an
effort to make sure other libraries make use of units when appropriate (like
Andrei suggested std.datetime) etc. As we all know it takes 90% of the time
to code 10% of the code. I think all of this extra polish, reliability and
usability is very important and takes the extra 11 weeks. It's not the most
glorified kind of work, but I really think it's worth it.

On 29 March 2011 23:40, David Nadlinger <see at klickverbot.at> wrote:

> On 3/29/11 3:49 PM, Cristi Cobzarenco wrote:
>
>> To David:
>> Ok, right now, I got two working versions, one sorting by .mangleof and
>> one performing a double-inclusion test on the tuples. Both work, I can't
>> see any performance increase in the .mangleof one, but if .mangleof
>> returns unique string, I say we use it this way.
>>
>
> To be honest, I still don't see how you are able to get away without
> canonicalization in the first place; would you mind to elaborate on how you
> solve the issue of different ordering of expression yielding types? This is
> not about the algorithm to determine whether two types are semantically
> equivalent, where your algorithm would work fine as well, but about the
> actual D types. If you don't sort them, Quantity!(BaseUnitExp!(Meter, 1),
> BaseUnitExp!(Second, -2)) and Quantity!(BaseUnitExp!(Second, -2),
> BaseUnitExp!(Meter, 1)) would be different types, which is not desirable for
> obvious reasons.
>
>
>  Regarding my string little DSL. I have 3 solutions right now:
>> 1. Drop the DSL altogether, right now my system would work perfectly
>> fine with boost-like tuples (a list of units alternating with exponents):
>> Quantity!(Metre,1,Second,-1) speed = distance/time;
>> While less readable, this doesn't have the disadvantages of the following
>> 2.
>>
>> 2. Use a mixin template to declare the expression parser in the current
>> scope:
>> mixin DeclareExprQuantity!();
>>
>> struct Metre {}
>> struct Second {}
>> struct Kg {}
>>
>> void f() {
>>        ExprQuantity!("Metre/Second * Kg^-1") q = speed / mass;
>> }
>> This works, is readable, but it uses C-preprocessor like behaviour
>> (read: black vodoo) - a library declaring something in your scope isn't
>> very nice.
>>
>> […]
>>
>>
>> The only completely clean alternative would be the abominable:
>> Quantity!( mixin(Expr!("Metre/Second")) ) q;
>>
>
> Get out of my head! Immediately! ;) Just kidding – incidentally I
> considered exactly the same options when designing my current prototype. My
> current approach would be a mix between 1 and 2: I don't think the Boost
> approach of using »dummy« instances of units is any less readable than your
> proposed one when you don't deal with a lot of units. For example, consider
>
> enum widgetCount = quantity!("Widget")(2);
> vs.
> enum widgetCount = 2 * widgets;
>
> This could also be extended to type definitions to avoid having to manually
> write the template instantiation:
>
> Quantity!("meter / second", float) speed;
> vs.
> typeof(1.f * meter / second) speed;
>
> There are situations, though, where using unit strings could considerable
> improve readability, namely when using lots of units with exponents. In
> these cases, a mixin could be used to bring all the types in scope for the
> »parsing template«, similar to the one you suggested. If a user of the
> library things  could use an additional mixin identifier to clarify the
> code, e.g. »mixin UnitStringParser U; […] U.unit!"m/s"«).
>
> But a more attractive solution would exploit the fact that you would mostly
> use units with a lot of exponents when working with a »closed« unit system
> without the need for ad-hoc extensions, like the SI system, which would
> allow you to use unit symbols instead of the full name, which wouldn't need
> to be globally unique and wouldn't pollute the namespace (directly defining
> a type »m« to express meters would probably render the module unusable
> without static imports).
>
> It would essentially work by instantiating a parser template with all the
> named units. Thus, the parser would know all the types and could query them
> for additional properties like short names/symbols, etc. In code:
>
> ---
> module units.si;
> […]
> alias UnitSystem!(Meter, Second, …) Si;
> ---
> module client;
> import units.si;
> auto inductance = 5.0 * Si.u!"m^2 kg/(s^2 A^2)";
> ---
>
> This could also be combined with the mixin parser approach like this:
> ---
> import units.si;
> mixin UnitStringParser!(Si) U;
> ---
>
> But to reiterate my point, I don't think a way to parse unit strings is
> terribly important, at least not if it isn't coupled with other things like
> the ability to add shorthand symbols.
>
> David
>



-- 
(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20110330/8f74647c/attachment-0001.html>


More information about the Digitalmars-d mailing list