www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [GSoC Proposal] Statically Checked Measurement Units

reply Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00235447063854a215049f8cce70
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

First, let me apologize for this very late entry, it's the end of universit=
y
and it's been a very busy period, I hope you will still consider it.

Note this email is best read using a fixed font.

PS: I'm really sorry if this is the wrong mailing list to post and I hope
you'll forgive me if that's the case.

=3D=3D=3D=3D=3D=3D=3D Google Summer of Code Proposal: Statically Checked Un=
its =3D=3D=3D=3D=3D=3D=3D


Abstract
-------------

Measurement units allow to statically check the correctness of assignments
and expressions at virtually no performance cost and very little extra
effort. When it comes to physics the advantages are obvious =96 if you try =
to
assign a force a variable measuring distance, you've most certainly got a
formula wrong somewhere along the way. Also, showing a sensor measurement i=
n
gallons on a litre display that keeps track of the remaining fuel of a plan=
e
(a big no-no) is easily avoidable with this technique. What this translates
is that one more of the many hidden assumptions in source code is made
visible: units naturally complement other contract checking techniques, lik=
e
assertions, invariants and the like. After all the unit that a value is
measured in is part of the contract.

The scope of measurement units is not limited to physics calculations
however and if the feature is properly implemented and is very easy to use,
creating a very domain-specific units helps a great deal with checking
correct code at compile time. Static typing doesn't cut it sometimes:
imagine    two variables counting different things =96 Gadgets and Widgets.
While both values should be ints, one of them should probably not be
assignable to the other. Or imagine a website calculating the number of
downloads per second, but uses a timer that counts milliseconds. When one
thinks about it this way, there are a great many cases where units can help
prevent common errors.

Given D's focus on contract based design and language features supporting
it, I think statically checked measurement units fit very naturally into th=
e
standard library, and the language's metaprogramming features would make it
very clean to implement (as opposed to a similar effort in C++). I think a
system that is closer to the one in F# would be a better idea than the one
provided by Boost.Units:
1. Defining unit systems, like Boost.Units requires is extra effort, so
units for counting Widgets or Gadgets would be awkward to use and we would
lose the safety checks there.
2. Defining dimensions is not strictly necessary, and F# does well without
them.
3. The sort of silent conversion that Boost.Units performs is undesirable i=
n
many cases since it is a recipe for precision disasters, imagine sometimes
accidentally assigning a variable measured in billions of years to a one
measured in picoseconds. Boost.Units would silently convert one to another,
since they measure the same dimension. This probably results into the value
being set to +INF and even if it doesn't, very rarely one actually intends
to perform this conversion.
4. Setting numerical ids to units and dimensions is cumbersome. S

Thus, the requirements for the unit system would be:
1. One line definition of new units.
2. Simple, yet safe and explicit conversion between units.
3. Zero runtime overhead.
4. Minimal extra coding effort to use units.


Interface Overview
---------------------------
A Boost type approach to the library interface would be:

struct Metre     : SomeUnitBaseType!(...) {}
struct Second    : SomeUnitBaseType!(...) {}

typedef DerivedUnit!(MetreType,1,Second,-1) MetresPerSecond;
typedef DerivedUnit!(MetreType,2)           MetersSquared;

Meter           metre, metres;
Second          second, seconds;
MetersPerSecond metersPerSecond;
MetersSquared   meterSquared, metersSquared;

void f() {
Quantity!(metre)           dist1 =3D 3.0 * metres;
Quantity!(meterSquared)    area  =3D dist1 * dist1;
Quantity!(metresPerSecond) speed =3D distance / (2.0*seconds);
}


This is very cumbersome and fails on the one line requirement. I propose
using types for base units and mixins to define derived units. One can use
the typenames of the units in arithmetic operations this way:

struct metre  {}
struct second {}


void f() {
Quantity!("metre")        dist1 =3D quantity!(3.0, "metre");
Quantity!("metre^2")      area  =3D dist1 * dist1;
Quantity!("metre/second") speed =3D dist1 / quantity!(2.0, "second");
}


Conversion between units can be done specifying a single factor with a
proper unit:

template conversion( alias unit : "kilometer/meter" ) {
immutable Quantity!(unit) conversion =3D quantity!(123.0,unit);
}

void f() {
Quantity!("metre")     d1 =3D quantity!(123.0,"metre");
 // convert calls conversion! with the right argument
Quantity!("kilometre") d2 =3D convert!(d1,"kilometre");
}

Also, notice this approach imposes no restriction to the types that define
units, therefore our Widget/Gadget counters could be defined without any
extra work:

class Widget { /* complicated class definition */ }
class Gadget { /* complicated class definition */ }

Quantity!("Widget",int) nWidgets;
Quantity!("Gadget",int) nGadgets;


About Me
------------
I am an undergraduate student at the University of Edinburgh in Scotland
doing a degree in Computer Science and Artificial Intelligence, originally
from Romania where I finished a specialised Computer Science high school
(Colegiul National de Informatica "Tudor Vianu").
My first language is C++ which I started learning when I was 9 and as a
result I have a very good understanding of template metaprogramming. I also
know Haskell and Python well which helps me draw from multiple paradigms
when designing as system. I started learning D about a year ago and I
instantly fell in love with it. The fact that it does away with all the
annoying C backwards compatibility, improves on the features that make C++
unique (the template system, performance, low level memory access etc.) and
adds modern language features (garbage collection, lambda functions etc.)
makes me very optimistic about the project.
In terms of working experience, other than a myriad of personal projects, I
did work for my former high school for a summer, implementing an automated
testing system, and last year I was lead a team that won a software
development competition organised by our computing society. This year I too=
k
part in the Scottish Game Jam where my team ended up in 8th place.


--=20
(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco

--00235447063854a215049f8cce70
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div>First, let me apologize for this very late entry, it&#39;s the end of=
=A0university and it&#39;s been a very busy period, I hope you will still c=
onsider it.</div><div><br></div><div>Note this email is best read using a f=
ixed font.</div>
<div><br></div><div>PS: I&#39;m really sorry if this is the wrong mailing l=
ist to post and I hope you&#39;ll forgive me if that&#39;s the case.</div><=
div><br></div><div>=3D=3D=3D=3D=3D=3D=3D Google Summer of Code Proposal: St=
atically Checked Units =3D=3D=3D=3D=3D=3D=3D</div>
<div><br></div><div><br></div><div>Abstract</div><div>-------------</div><d=
iv><br></div><div>Measurement units allow to statically check the correctne=
ss of assignments and expressions at virtually no performance cost and very=
 little extra effort. When it comes to physics the advantages are obvious =
=96 if you try to assign a force a variable measuring distance, you&#39;ve =
most certainly got a formula wrong somewhere along the way. Also, showing a=
 sensor measurement in gallons on a litre display that keeps track of the r=
emaining fuel of a plane (a big no-no) is easily avoidable with this techni=
que. What this translates is that one more of the many hidden assumptions i=
n source code is made visible: units naturally complement other contract ch=
ecking techniques, like assertions, invariants and the like. After all the =
unit that a value is measured in is part of the contract.</div>
<div><br></div><div>The scope of measurement units is not limited to physic=
s calculations however and if the feature is properly implemented and is ve=
ry easy to use, creating a very domain-specific units helps a great deal wi=
th checking correct code at compile time. Static typing doesn&#39;t cut it =
sometimes: imagine =A0 =A0two variables counting different things =96 Gadge=
ts and Widgets. While both values should be ints, one of them should probab=
ly not be assignable to the other. Or imagine a website calculating the num=
ber of downloads per second, but uses a timer that counts milliseconds. Whe=
n one thinks about it this way, there are a great many cases where units ca=
n help prevent common errors.</div>
<div><br></div><div>Given D&#39;s focus on contract based design and langua=
ge features supporting it, I think statically checked measurement units fit=
 very naturally into the standard library, and the language&#39;s metaprogr=
amming features would make it very clean to implement (as opposed to a simi=
lar effort in C++). I think a system that is closer to the one in F# would =
be a better idea than the one provided by Boost.Units:</div>
<div>1. Defining unit systems, like Boost.Units requires is extra effort, s=
o units for counting Widgets or Gadgets would be awkward to use and we woul=
d lose the safety checks there.</div><div>2. Defining dimensions is not str=
ictly necessary, and F# does well without them.</div>
<div>3. The sort of silent conversion that Boost.Units performs is undesira=
ble in many cases since it is a recipe for precision disasters, imagine som=
etimes accidentally assigning a variable measured in billions of years to a=
 one measured in picoseconds. Boost.Units would silently convert one to ano=
ther, since they measure the same dimension. This probably results into the=
 value being set to +INF and even if it doesn&#39;t, very rarely one actual=
ly intends to perform this conversion.</div>
<div>4. Setting numerical ids to units and dimensions is cumbersome. S</div=
<div><br></div><div>Thus, the requirements for the unit system would be:</=

and explicit conversion between units.</div> <div>3. Zero runtime overhead.</div><div>4. Minimal extra coding effort to = use units.</div><div><br></div><div><br></div><div>Interface Overview</div>= <div>---------------------------</div><div>A Boost type approach to the lib= rary interface would be:</div> <div><br></div><div>struct Metre =A0 =A0 : SomeUnitBaseType!(...) {}</div><= div>struct Second =A0 =A0: SomeUnitBaseType!(...) {}</div><div><br></div><d= iv>typedef DerivedUnit!(MetreType,1,Second,-1) MetresPerSecond;</div><div>t= ypedef DerivedUnit!(MetreType,2) =A0 =A0 =A0 =A0 =A0 MetersSquared;</div> <div><br></div><div>Meter =A0 =A0 =A0 =A0 =A0 metre, metres;</div><div>Seco= nd =A0 =A0 =A0 =A0 =A0second, seconds;</div><div>MetersPerSecond metersPerS= econd;</div><div>MetersSquared =A0 meterSquared, metersSquared;</div><div><= br></div><div>void f() {</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>Quant= ity!(metre) =A0 =A0 =A0 =A0 =A0 dist1 =3D 3.0 * metres;</div><div><span cla= ss=3D"Apple-tab-span" style=3D"white-space:pre"> </span>Quantity!(meterSqua= red) =A0 =A0area =A0=3D dist1 * dist1;=A0</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>Quant= ity!(metresPerSecond) speed =3D distance / (2.0*seconds);</div><div>}</div>= <div><br></div><div><br></div><div>This is very cumbersome and fails on the= one line requirement. I propose using types for base units and mixins to d= efine derived units. One can use the typenames of the units in arithmetic o= perations this way:</div> <div><br></div><div>struct metre =A0{}</div><div>struct second {}</div><div=
<br></div><div><br></div><div>void f() {</div><div><span class=3D"Apple-ta=

=A0 =A0 =A0dist1 =3D quantity!(3.0, &quot;metre&quot;);</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>Quant= ity!(&quot;metre^2&quot;) =A0 =A0 =A0area =A0=3D dist1 * dist1;</div><div><= span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>Quantity!(&= quot;metre/second&quot;) speed =3D dist1 / quantity!(2.0, &quot;second&quot= ;);</div> <div>}</div><div><br></div><div><br></div><div>Conversion between units can= be done specifying a single factor with a proper unit:</div><div><br></div=
<div>template conversion( alias unit : &quot;kilometer/meter&quot; ) {</di=

<div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>immut= able Quantity!(unit) conversion =3D quantity!(123.0,unit);</div><div>}</div=
<div><br></div><div>void f() {</div><div><span class=3D"Apple-tab-span" st=

quantity!(123.0,&quot;metre&quot;);</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span></div=
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>// c=

pple-tab-span" style=3D"white-space:pre"> </span>Quantity!(&quot;kilometre&= quot;) d2 =3D convert!(d1,&quot;kilometre&quot;);</div> <div>}</div><div><br></div><div>Also, notice this approach imposes no restr= iction to the types that define units, therefore our Widget/Gadget counters= could be defined without any extra work:</div><div><br></div><div>class Wi= dget { /* complicated class definition */ }=A0</div> <div>class Gadget { /* complicated class definition */ }</div><div><br></di= v><div>Quantity!(&quot;Widget&quot;,int) nWidgets;</div><div>Quantity!(&quo= t;Gadget&quot;,int) nGadgets;</div><div><br></div><div><br></div><div>About= Me</div> <div>------------</div><div>I am an undergraduate student at the University= of Edinburgh in Scotland doing a degree in Computer Science and Artificial= Intelligence, originally from Romania where I finished a specialised Compu= ter Science high school (Colegiul National de Informatica &quot;Tudor Vianu= &quot;).</div> <div>My first language is C++ which I started learning when I was 9 and as = a result I have a very good understanding of template metaprogramming. I al= so know Haskell and Python well which helps me draw from multiple paradigms= when designing as system. I started learning D about a year ago and I inst= antly fell in love with it. The fact that it does away with all the annoyin= g C backwards compatibility, improves on the features that make C++ unique = (the template system, performance, low level memory access etc.) and adds m= odern language features (garbage collection, lambda functions etc.) makes m= e very optimistic about the project.</div> <div>In terms of working experience, other than a myriad of personal projec= ts, I did work for my former high school for a summer, implementing an auto= mated testing system, and last year I was lead a team that won a software d= evelopment competition organised by our computing society. This year I took= part in the Scottish Game Jam where my team ended up in 8th place.</div> <div><br></div><br>-- <br>(Cristi Cobzarenco)<br>Pofile: <a href=3D"http://= www.google.com/profiles/cristi.cobzarenco">http://www.google.com/profiles/c= risti.cobzarenco</a><br> --00235447063854a215049f8cce70--
Mar 28 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 3/28/11 5:43 PM, Cristi Cobzarenco wrote:
 First, let me apologize for this very late entry, it's the end
 of university and it's been a very busy period, I hope you will still
 consider it.

This is by no means a late proposal – the application period has not even formally opened yet. I was somewhat surprised to see your post, because I had been playing around with a dimensional algebra/unit system implementation for a while before the whole GSoC thing started. I even have an unfinished project proposal for it lying around, but as I thought that I was rather alone with my fascination for unit systems, I decided to finish the Thrift one first. Well, seems like I was wrong… :) A few things that came to my mind while reading your proposal: - The need for numerical ids is not inherent to a dimension-aware model like Boost.Units – it's just needed because there is no way to get a strict total order of types in C++. You will need to find a solution for this in D as well, because you want to make sure that »1.0 * second * metre« is of the same type as »1.0 * metre * second«. - I think that whether disallowing implicit conversion of e.g. millimeters to meters is a good idea has to be decided once the rest of the API has been implemented and one can actually test how the API »feels« – although I'd probably disallow them in my design by default as well, I'm not too sure if this actually works out in practice, or if it just cumbersome to use. Also, I'd like to note that whether to allow this kind of implicit conversions doesn't necessarily depend on whether a system has the notion of dimensions. - Not that I would be too fond of the Boost.Units design, but »convenience« functions for constructing units from strings like in your second example could be implemented for it just as well. - You have probably already thought of this and omitted it for the sake of brevity, but I don't quite see how your current, entirely string-based proposal would work when units and/or conversion factors are defined in a module different from the one the implementations of Quantity/convert/… are in. Contrary to C++, D doesn't have ADL, so I am not sure how a custom base unit would be in scope for Quantity to find, or how a custom conversion template could be found from convert(). Anyway, I am not sure whether I should submit my own units proposal as well, but if you should end up working on this project, I'd be happy to discuss any design or implementation issue you'd like to. David
Mar 28 2011
parent reply David Nadlinger <see klickverbot.at> writes:
I am in a slight dilemma, because although I would love to share my work 
and ideas with you, right now this would automatically weaken my own 
units proposal in comparison to yours. However, as this would be grossly 
against the open source spirit, and the point of GSoC certainly can't be 
to encourage that, I'll just do it anyway.

Regarding IDs: As I wrote in my previous post, the only point of the 
unit IDs in Boost.Units is to provide a strict total order over the set 
of units. If you can achieve it without that (see below), you won't need 
any artificial numbers which you have to manage.

But why would you need to be able to sort the base units in the first 
place? The answer is simple: To define a single type representation for 
each possible unit, i.e. to implement type canonicalization. To 
illustrate this point, consider the following (pseudocode) example:

auto force = 5.0 * newton;
auto distance = 3.0 * meter;
Quantity!(Newton, Meter) torque = force * distance;
torque = distance * force;

Both of the assignments to »torque« should obviously work, because the 
types of »force * distance« and »distance * force« are semantically the 
same. In a naïve implementation, however, the actual types would be 
different because the pairs of base units and exponents would be 
arranged in a different order, so at least one of the assignments would 
lead to type mismatch – because a tuple of units is, well, a tuple and 
not an (unordered) set.

And this is exactly where the strictly ordered IDs enter the scheme. By 
using them to sort the base unit/exponent pairs, you can guarantee that 
quantities semantically equivalent always end up with the same 
»physical« type.

Luckily, there is no need to require the user to manually assign 
sortable, unique IDs to each base type because we can access the mangled 
names of types at compile time, which fulfill these requirements. There 
are probably other feasible approaches as well, but using them worked 
out well for me (you can't rely on .stringof to give unique strings). 
When implementing the type sorting code, you might probably run into 
some difficulties and/or CTFE bugs, feel free to contact me for related 
questions (as I have already wasted enough time on this to get a working 
solution…^^).

Regarding strings: I might not have expressed my doubts clearly, but I 
didn't assume that your proposed system would use strings as internal 
representation at all. What I meant is that I don't see a way how, given 
»Quantity!("Widgets/Gadgets")«, to get the Widget and Gadget types in 
scope inside Quantity. Incidentally, this is exactly the reason for 
which you can't use arbitrary functions/types in the »string lambdas« 
from std.algorithm.

David


On 3/28/11 9:43 PM, Cristi Cobzarenco wrote:
 - I too was playing around with a units project before GSoC, that is why
 I thought doing this project was a good idea. The way I was doing it
 without numerical IDs was simply by having more complicated algorithms
 for equality, multiplications etc. For example, equality would be
 implemented as:
 template UnitTuple(P...) {
    alias P Units;
 }

 template contains( Unit, UT ) {
    /* do a linear search for Unit in UT.Units (since UT is a UnitTuple)
 - O(n)*/
 }

 template includes( UT1, UT2 ) {
    /* check for each Unit in UT1 that it is also in UT2 (using contains)
 - O(n^2) */
 }

 template equals( UT1, UT2 ) {
    immutable bool equals = includes!(UT1,UT2) && includes!(UT2, UT1);
 }
 Granted this means that each check takes O(n^2) where n is the number of
 different units, but it might be worth it - or not. On the small tests
 I've done it didn't seem to increase compile time significantly, but
 more research needs to be done. I think that as long as there aren't
 values with _a lot_ of units (like ten), the extra compile time
 shouldn't be noticeable. The biggest problem I have with adding IDs is
 that one will have to manage systems afterwards or have to deal with
 collisions. Neither one is very nice.

 - You're right, you don't need dimensions for implicit conversions, of
 course. And you're also right about possibly making the decision later
 about implicit conversions. The thing is F#, where units are very
 popular, only has explicit conversions, and I was trying to steer more
 towards that model.

 - I seem not to have been to clear about the way I would like to use
 strings. The names of the units in the strings have to be the type names
 that determine the units. Then one needs a function that would convert a
 string like "Meter/Second" to Division!(Meter, Second), I'm not sure how
 you would do that in C++. Maybe I'm wrong, but I can't see it.

 - I hope it is by now clear that my proposal is not, in fact, string
 based at all. The strings are just there to be able to write derived
 units in infix notation, something boost solves by using dummy objects
 with overloaded operators. The lack of ADL is a problem which I
 completely missed; I have immersed myself in C++ completely lately and
 I've gotten used to specializing templates in different scopes. These
 are the solutions I can come up with, but I will have to think some more:
 1. There is an intrusive way of solving this, by making the conversion
 factors static members of the unit types, but this would not allow, for
 example, having a Widget/Gadget counter the way I intended.
 2. The way they get away with it in F# is to use global conversion
 factors, that one manually uses. That actually is not bad at all. The
 only problem was that I was hoping that conversion between derived units
 could automatically be done using the conversion factors of the
 fundamental units: (meter/second) -> (kilometer/hour) knowing
 meter->kilometer and second->hour.

 Again I will have to think some more about the latter point. And I'll do
 some more tests on the performance of doing linear searches. Is there
 way to get the name of a type (as a string) at compile time (not the
 mangled name you get at runtime)? I wasn't able to find any way to do
 this. My original idea was actually to use the fully qualified typenames
 to create the ordering.

 Thanks a lot for your feedback, it's been very helpful, especially in
 pointing out the lack of ADL. Hope to hear from you again.

Mar 29 2011
parent David Nadlinger <see klickverbot.at> writes:
On 3/29/11 2:33 PM, Cristi Cobzarenco wrote:
 Surely, .mangleof returns unique strings?

which was suggested by other people here on the NG, however, is not unique.
 […] Thanks a lot for your feedback, I feel this
 collaboration will help D in the end, no matter whose proposal gets
 accepted (if any). I am a bit confused regarding your GSoC proposal,
 aren't you a mentor?

No, I'm just hoping to participate in this GSoC as a student as well. To clarify the situation: Having experienced how incredibly useful dimensional analysis is in many areas of science, I have long been interested in possible ways of using unit systems in programming to gain additional type safety. Earlier this year, before a possible application to GSoC was even brought up in the D community, I started to work on a D implementation of an unit system. I finished a working prototype, but didn't have the time yet to implement a flexible unit conversion scheme and, more importantly, extend the documentation and examples so I could put it up for discussion at the D NG. Then, it was announced that Digital Mars would participate in this Google Summer of Code, and surprisingly it didn't take long until someone added an unit system to the ideas page. As I was considering to apply to GSoC anyway, this seemed like a natural fit. However, Andrei also put up the idea of a D implementation of Apache Thrift, which caught my attention as I have been waiting for the opportunity to have an in-depth look on it for quite some time now. As I am equally interested in both topics, and students are allowed to submit a large number of proposals (20?), I decided to just write project proposals for both of them and let Walter/Andrei/… choose which one they like better, if any. I decided to start with the Thrift one, and planned to submit my units proposal later in the application period. After publishing my first draft here at the NG, I also contacted Andrei for his opinion on whether it would make sense to submit a second proposal, given that he seemed quite interested in the Thrift idea. Now, back to topic: I am absolutely sure that collaborating on this project will lead to better results (I mean, that's how open source software works after all), but there is a problem: By the GSoC rules, it's not possible for students to work in teams on a single project. The dilemma I hinted at is that if we start working together right now, we'll probably end up with two almost identical proposals/applications for the same project, which doesn't really seem desirable. Also, I'm increasingly doubtful that an units library would be a good fit for a Summer of Code project in the first place, which is also why I finished my other proposal first: As Don said, I think that while it certainly is a nice demonstration of the metaprogramming capabilities/type system expressiveness of a language, it might not be too useful for the »general public«, compared to other features. Don't get me wrong here, I'm personally very enthusiastic about the idea, and I can imagine many possible ways in which a flexible unit system could be used to avoid bugs or to clarify interfaces. But: The concept isn't new at all – for example, during my research I stumbled over papers dedicated to units in programming languages dating back to 1985 –, but I have yet to see units actually being used in production code. My second concern is the extent of the project: After spending two weekends on it, I have a working prototype of a units library, and, if I understood you correctly, you have one as well. They surely both lack some features and a lot of polish and documentation, but I think it would probably take neither of us three full months of work to get them into a state suitable for inclusion in the Phobos review queue. For these reasons, I really started to wonder if it wouldn't be the better idea to just merge our projects and work on getting the result into shape independent of GSoC when I saw your proposal – even more so since our design/implementation ideas have shown to be quite similar. I don't want to discourage you from applying at all, and I will probably still submit a proposal for it nevertheless, but I think this should be discussed. David
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--0023544706382a7216049f9027bb
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

- I too was playing around with a units project before GSoC, that is why I
thought doing this project was a good idea. The way I was doing it without
numerical IDs was simply by having more complicated algorithms for equality=
,
multiplications etc. For example, equality would be implemented as:
template UnitTuple(P...) {
  alias P Units;
}

template contains( Unit, UT ) {
  /* do a linear search for Unit in UT.Units (since UT is a UnitTuple) -
O(n)*/
}

template includes( UT1, UT2 ) {
  /* check for each Unit in UT1 that it is also in UT2 (using contains) -
O(n^2) */
}

template equals( UT1, UT2 ) {
  immutable bool equals =3D includes!(UT1,UT2) && includes!(UT2, UT1);
}
Granted this means that each check takes O(n^2) where n is the number of
different units, but it might be worth it - or not. On the small tests I've
done it didn't seem to increase compile time significantly, but more
research needs to be done. I think that as long as there aren't values with
_a lot_ of units (like ten), the extra compile time shouldn't be noticeable=
.
The biggest problem I have with adding IDs is that one will have to manage
systems afterwards or have to deal with collisions. Neither one is very
nice.

- You're right, you don't need dimensions for implicit conversions, of
course. And you're also right about possibly making the decision later abou=
t
implicit conversions. The thing is F#, where units are very popular, only
has explicit conversions, and I was trying to steer more towards that model=
.

- I seem not to have been to clear about the way I would like to use
strings. The names of the units in the strings have to be the type names
that determine the units. Then one needs a function that would convert a
string like "Meter/Second" to Division!(Meter, Second), I'm not sure how yo=
u
would do that in C++. Maybe I'm wrong, but I can't see it.

- I hope it is by now clear that my proposal is not, in fact, string based
at all. The strings are just there to be able to write derived units in
infix notation, something boost solves by using dummy objects with
overloaded operators. The lack of ADL is a problem which I completely
missed; I have immersed myself in C++ completely lately and I've gotten use=
d
to specializing templates in different scopes. These are the solutions I ca=
n
come up with, but I will have to think some more:
1. There is an intrusive way of solving this, by making the conversion
factors static members of the unit types, but this would not allow, for
example, having a Widget/Gadget counter the way I intended.
2. The way they get away with it in F# is to use global conversion factors,
that one manually uses. That actually is not bad at all. The only problem
was that I was hoping that conversion between derived units could
automatically be done using the conversion factors of the fundamental units=
:
(meter/second) -> (kilometer/hour) knowing meter->kilometer and
second->hour.

Again I will have to think some more about the latter point. And I'll do
some more tests on the performance of doing linear searches. Is there way t=
o
get the name of a type (as a string) at compile time (not the mangled name
you get at runtime)? I wasn't able to find any way to do this. My original
idea was actually to use the fully qualified typenames to create the
ordering.

Thanks a lot for your feedback, it's been very helpful, especially in
pointing out the lack of ADL. Hope to hear from you again.

On 28 March 2011 20:57, David Nadlinger <see klickverbot.at> wrote:

 On 3/28/11 5:43 PM, Cristi Cobzarenco wrote:

 First, let me apologize for this very late entry, it's the end
 of university and it's been a very busy period, I hope you will still
 consider it.

This is by no means a late proposal =96 the application period has not ev=

 formally opened yet.

 I was somewhat surprised to see your post, because I had been playing
 around with a dimensional algebra/unit system implementation for a while
 before the whole GSoC thing started. I even have an unfinished project
 proposal for it lying around, but as I thought that I was rather alone wi=

 my fascination for unit systems, I decided to finish the Thrift one first=

 Well, seems like I was wrong=85 :)

 A few things that came to my mind while reading your proposal:
  - The need for numerical ids is not inherent to a dimension-aware model
 like Boost.Units =96 it's just needed because there is no way to get a st=

 total order of types in C++. You will need to find a solution for this in=

 as well, because you want to make sure that =BB1.0 * second * metre=AB is=

 same type as =BB1.0 * metre * second=AB.

  - I think that whether disallowing implicit conversion of e.g. millimete=

 to meters is a good idea has to be decided once the rest of the API has b=

 implemented and one can actually test how the API =BBfeels=AB =96 althoug=

 probably disallow them in my design by default as well, I'm not too sure =

 this actually works out in practice, or if it just cumbersome to use. Als=

 I'd like to note that whether to allow this kind of implicit conversions
 doesn't necessarily depend on whether a system has the notion of dimensio=

  - Not that I would be too fond of the Boost.Units design, but
 =BBconvenience=AB functions for constructing units from strings like in y=

 second example could be implemented for it just as well.

  - You have probably already thought of this and omitted it for the sake =

 brevity, but I don't quite see how your current, entirely string-based
 proposal would work when units and/or conversion factors are defined in a
 module different from the one the implementations of Quantity/convert/=85=

 in. Contrary to C++, D doesn't have ADL, so I am not sure how a custom ba=

 unit would be in scope for Quantity to find, or how a custom conversion
 template could be found from convert().

 Anyway, I am not sure whether I should submit my own units proposal as
 well, but if you should end up working on this project, I'd be happy to
 discuss any design or implementation issue you'd like to.

 David

--=20 (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --0023544706382a7216049f9027bb Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8">- = I too was playing around with a units project before GSoC, that is why I th= ought doing this project was a good idea. The way I was doing it without nu= merical IDs was simply by having more complicated algorithms for equality, = multiplications etc. For example, equality would be implemented as:<div> template UnitTuple(P...) {</div><div>=A0=A0alias P Units;</div><div>}</div>= <div><br></div><div>template contains( Unit, UT ) {</div><div>=A0=A0/* do a= linear search for Unit in UT.Units (since UT is a UnitTuple) - O(n)*/</div=
<div>

/* check for each Unit in UT1 that it is also in UT2 (using contains) - O(n= ^2) */</div><div>}</div><div><br></div><div>template equals( UT1, UT2 ) {</= div> <div>=A0=A0immutable bool equals =3D includes!(UT1,UT2) &amp;&amp; includes= !(UT2, UT1);</div><div>}</div><div>Granted this means that each check takes= O(n^2) where n is the number of different units, but it might be worth it = - or not. On the small tests I&#39;ve done it didn&#39;t seem to increase c= ompile time significantly, but more research needs to be done. I think that= as long as there aren&#39;t values with _a lot_ of units (like ten), the e= xtra compile time shouldn&#39;t be noticeable. The biggest problem I have w= ith adding IDs is that one will have to manage systems afterwards or have t= o deal with collisions. Neither one is very nice.</div> <div><br></div><div>- You&#39;re right, you don&#39;t need dimensions for i= mplicit conversions, of course. And you&#39;re also right about possibly ma= king the decision later about implicit conversions. The thing is F#, where = units are very popular, only has explicit conversions, and I was trying to = steer more towards that model.</div> <div><br></div><div>- I seem not to have been to clear about the way I woul= d like to use strings. The names of the units in the strings have to be the= type names that determine the units. Then one needs a function that would = convert a string like &quot;Meter/Second&quot; to Division!(Meter, Second),= I&#39;m not sure how you would do that in C++. Maybe I&#39;m wrong, but I = can&#39;t see it.<br> <div><br></div><div>- I hope it is by now clear that my proposal is not, in= fact, string based at all. The strings are just there to be able to write = derived units in infix notation, something boost solves by using dummy obje= cts with overloaded operators. The lack of ADL is a problem which I complet= ely missed; I have immersed myself in C++ completely lately and I&#39;ve go= tten used to specializing templates in different scopes. These are the solu= tions I can come up with, but I will have to think some more:</div> <div>1. There is an intrusive way of solving this, by making the conversion= factors static members of the unit types, but this would not allow, for ex= ample, having a Widget/Gadget counter the way I intended.</div><div>2. The = way they get away with it in F# is to use global conversion factors, that o= ne manually uses. That actually is not bad at all. The only problem was tha= t I was hoping that conversion between derived units could automatically be= done using the conversion factors of the fundamental units: (meter/second)= -&gt; (kilometer/hour) knowing meter-&gt;kilometer and second-&gt;hour.</d= iv> <div><br></div><div>Again I will have to think some more about the latter p= oint. And I&#39;ll do some more tests on the performance of doing linear se= arches. Is there way to get the name of a type (as a string) at compile tim= e (not the mangled name you get at runtime)? I wasn&#39;t able to find any = way to do this. My original idea was actually to use the fully qualified ty= penames to create the ordering.</div> <div><br></div><div>Thanks a lot for your feedback, it&#39;s been very help= ful, especially in pointing out the lack of ADL. Hope to hear from you agai= n.=A0</div></div><div> <div><br><div class=3D"gmail_quote">On 28 March 2011 20:57, David Nadlinger= <span dir=3D"ltr">&lt;<a href=3D"mailto:see klickverbot.at" target=3D"_bla= nk">see klickverbot.at</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_= quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1= ex"> <div>On 3/28/11 5:43 PM, Cristi Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> First, let me apologize for this very late entry, it&#39;s the end<br> of university and it&#39;s been a very busy period, I hope you will still<b= r> consider it.<br> </blockquote> <br></div> This is by no means a late proposal =96 the application period has not even= formally opened yet.<br> <br> I was somewhat surprised to see your post, because I had been playing aroun= d with a dimensional algebra/unit system implementation for a while before = the whole GSoC thing started. I even have an unfinished project proposal fo= r it lying around, but as I thought that I was rather alone with my fascina= tion for unit systems, I decided to finish the Thrift one first. Well, seem= s like I was wrong=85 :)<br> <br> A few things that came to my mind while reading your proposal:<br> =A0- The need for numerical ids is not inherent to a dimension-aware model = like Boost.Units =96 it&#39;s just needed because there is no way to get a = strict total order of types in C++. You will need to find a solution for th= is in D as well, because you want to make sure that =BB1.0 * second * metre= =AB is of the same type as =BB1.0 * metre * second=AB.<br> <br> =A0- I think that whether disallowing implicit conversion of e.g. millimete= rs to meters is a good idea has to be decided once the rest of the API has = been implemented and one can actually test how the API =BBfeels=AB =96 alth= ough I&#39;d probably disallow them in my design by default as well, I&#39;= m not too sure if this actually works out in practice, or if it just cumber= some to use. Also, I&#39;d like to note that whether to allow this kind of = implicit conversions doesn&#39;t necessarily depend on whether a system has= the notion of dimensions.<br> <br> =A0- Not that I would be too fond of the Boost.Units design, but =BBconveni= ence=AB functions for constructing units from strings like in your second e= xample could be implemented for it just as well.<br> <br> =A0- You have probably already thought of this and omitted it for the sake = of brevity, but I don&#39;t quite see how your current, entirely string-bas= ed proposal would work when units and/or conversion factors are defined in = a module different from the one the implementations of Quantity/convert/=85= are in. Contrary to C++, D doesn&#39;t have ADL, so I am not sure how a cu= stom base unit would be in scope for Quantity to find, or how a custom conv= ersion template could be found from convert().<br> <br> Anyway, I am not sure whether I should submit my own units proposal as well= , but if you should end up working on this project, I&#39;d be happy to dis= cuss any design or implementation issue you&#39;d like to.<br><font color= =3D"#888888"> <br> David<br> </font></blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzaren= co)<br>Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco"= target=3D"_blank">http://www.google.com/profiles/cristi.cobzarenco</a><br> </div></div> --0023544706382a7216049f9027bb--
Mar 28 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/28/11 10:43 AM, Cristi Cobzarenco wrote:
 First, let me apologize for this very late entry, it's the end
 of university and it's been a very busy period, I hope you will still
 consider it.

 Note this email is best read using a fixed font.

 PS: I'm really sorry if this is the wrong mailing list to post and I
 hope you'll forgive me if that's the case.

 ======= Google Summer of Code Proposal: Statically Checked Units =======

This is a good place to discuss pre-submission proposals. To submit, go to http://d-programming-language.org/gsoc2011.html later today. This is a strong draft proposal that I am likely to back up when complete. A few notes: * There is a good overview of existing work, which puts the proponent in the right position to make the best choices for an implementation in D. * Human-readable strings as means to generate types is a fertile direction. One issue is canonicalization, e.g. "meters^2" would be a different type from "meters ^ 2" (and btw that should mimic D's operators, so it should use "^^"), and both are different from the semantically equivalent "meters*meters". I think this is avoidable by a function that brings all strings to a canonical form. This needs to be discussed in the proposal. * The approach to quantities of discrete objects (widgets, gadgets and I hope to see examples with degrees, radians etc.) is very promising. I'm also looking forward to a "Categorical" type - an integer-based quantity that describes a bounded enumeration of objects, for example "CityID". Categorical measures are not supposed to support arithmetic; they simply identify distinct objects in an unrelated space. * In the final proposal the scope of the library should be clarified (e.g. what kinds of units and related idioms will be supported, and what kinds you chose not to support and why). * At best the proposal could define and project a relationship with std.datetime, which defines a few units itself. Wonder whether it's possible to simplify std.datetime by using the future units library. Thanks for your interest, and good luck! Andrei
Mar 28 2011
parent reply spir <denis.spir gmail.com> writes:
On 03/28/2011 10:13 PM, Cristi Cobzarenco wrote:
   - The Categorical type sounds like a great idea. I think they could be
 passed on as a ValueType to a quantity:
 typedef Quantity!(City, BoundedInt!(0,100)) CityID;

 And BoundedInt is just a type implicitly-convertible to and from int, that
 supports assignment and equality and throws on an out-of-bounds assignment.

I would implement something like Categorical in a language that has no enum. But I do not see the point in D. What advantage does it bring? Denis -- _________________ vita es estrany spir.wikidot.com
Mar 28 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/28/11 6:09 PM, spir wrote:
 On 03/28/2011 10:13 PM, Cristi Cobzarenco wrote:
 - The Categorical type sounds like a great idea. I think they could be
 passed on as a ValueType to a quantity:
 typedef Quantity!(City, BoundedInt!(0,100)) CityID;

 And BoundedInt is just a type implicitly-convertible to and from int,
 that
 supports assignment and equality and throws on an out-of-bounds
 assignment.

I would implement something like Categorical in a language that has no enum. But I do not see the point in D. What advantage does it bring? Denis

A categorical type may not have a name for each value (userid, cityid, countryid...) Andrei
Mar 28 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00032557595af659ac049f9092a8
Content-Type: text/plain; charset=ISO-8859-1

Thanks for your answer!

- I agree that using strings to represent units is not a particularly good
idea. Since many people have noted related things, I seem not to have been
particularly clear about the way I intend to use strings. Let me try to
explain it in detail:

There is a type that determines the unit:
struct Meter {}

Then every quantity is parametrised with two aliases:
Quantity!(UnitList, ValueType)

UnitList represents a list of pairs (UnitType,Exponent), where UnitType is a
typename (like Meter) and Exponent is a static rational type. Therefore, the
following would be a valid quantity type:
Quantity!( UnitList!( UnitPair!(Meter,1) ), double )

The strings are parsed at compile time and converted (using mixins) into the
UnitList. For example:
ParseUnitString!("meters/second") -> UnitListDivison!( UnitList!(
UnitPair!(Meter,1) ), UnitList!( UnitPair!(Second,1) ) ) -> UnitList(
UnitPair!(Meter,1), UnitPair!(Second,-1) ).

Therefore there is no need to convert all strings to a cannonical form, they
are all converted to an alias tuple (UnitList). To check whether two
UnitList's are the same, one can check double-inclusion. What do you think,
does this make sense.

 - The Categorical type sounds like a great idea. I think they could be
passed on as a ValueType to a quantity:
typedef Quantity!(City, BoundedInt!(0,100)) CityID;

And BoundedInt is just a type implicitly-convertible to and from int, that
supports assignment and equality and throws on an out-of-bounds assignment.

What do you think?





On 28 March 2011 21:53, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org>wrote:

 On 3/28/11 10:43 AM, Cristi Cobzarenco wrote:

 First, let me apologize for this very late entry, it's the end
 of university and it's been a very busy period, I hope you will still
 consider it.

 Note this email is best read using a fixed font.

 PS: I'm really sorry if this is the wrong mailing list to post and I
 hope you'll forgive me if that's the case.

 ======= Google Summer of Code Proposal: Statically Checked Units =======

This is a good place to discuss pre-submission proposals. To submit, go to http://d-programming-language.org/gsoc2011.html later today. This is a strong draft proposal that I am likely to back up when complete. A few notes: * There is a good overview of existing work, which puts the proponent in the right position to make the best choices for an implementation in D. * Human-readable strings as means to generate types is a fertile direction. One issue is canonicalization, e.g. "meters^2" would be a different type from "meters ^ 2" (and btw that should mimic D's operators, so it should use "^^"), and both are different from the semantically equivalent "meters*meters". I think this is avoidable by a function that brings all strings to a canonical form. This needs to be discussed in the proposal. * The approach to quantities of discrete objects (widgets, gadgets and I hope to see examples with degrees, radians etc.) is very promising. I'm also looking forward to a "Categorical" type - an integer-based quantity that describes a bounded enumeration of objects, for example "CityID". Categorical measures are not supposed to support arithmetic; they simply identify distinct objects in an unrelated space. * In the final proposal the scope of the library should be clarified (e.g. what kinds of units and related idioms will be supported, and what kinds you chose not to support and why). * At best the proposal could define and project a relationship with std.datetime, which defines a few units itself. Wonder whether it's possible to simplify std.datetime by using the future units library. Thanks for your interest, and good luck! Andrei

-- (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --00032557595af659ac049f9092a8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Thanks for your answer!<div><br></div><div>- I agree that using strings to = represent units is not a particularly good idea. Since many people have not= ed related things, I seem not to have been particularly clear about the way= I intend to use strings. Let me try to explain it in detail:</div> <div><br></div><div>There is a type that determines the unit:</div><div>str= uct Meter {}</div><div><br></div><div>Then every quantity is parametrised w= ith two aliases:</div><div>Quantity!(UnitList, ValueType)</div><div><br> </div><div>UnitList represents a list of pairs (UnitType,Exponent), where U= nitType is a typename (like Meter) and Exponent is a static rational type. = Therefore, the following would be a valid quantity type:</div><div>Quantity= !( UnitList!( UnitPair!(Meter,1) ), double )</div> <div><br></div><div>The strings are parsed at compile time and converted (u= sing mixins) into the UnitList. For example:</div><div>ParseUnitString!(&qu= ot;meters/second&quot;) -&gt; UnitListDivison!( UnitList!( UnitPair!(Meter,= 1) ), UnitList!( UnitPair!(Second,1) ) ) -&gt; UnitList( UnitPair!(Meter,1)= , UnitPair!(Second,-1) ).</div> <div><br></div><div>Therefore there is no need to convert all strings to a = cannonical form, they are all converted to an alias tuple (UnitList). To ch= eck whether two UnitList&#39;s are the same, one can check double-inclusion= . What do you think, does this make sense.</div> <div><br></div><div>=A0- The Categorical type sounds like a great idea. I t= hink they could be passed on as a ValueType to a quantity:</div><div>typede= f Quantity!(City, BoundedInt!(0,100)) CityID;</div><div><br></div><div>And = BoundedInt is just a type implicitly-convertible to and from int, that supp= orts assignment and equality and throws on an out-of-bounds assignment.</di= v> <div><br></div><div>What do you think?</div><div><br></div><div><br></div><= div><br></div><div><br><br><div class=3D"gmail_quote">On 28 March 2011 21:5= 3, Andrei Alexandrescu <span dir=3D"ltr">&lt;<a href=3D"mailto:SeeWebsiteFo= rEmail erdani.org">SeeWebsiteForEmail erdani.org</a>&gt;</span> wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;"><div class=3D"im">On 3/28/11 10:43 AM, Cris= ti Cobzarenco wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div class=3D"im"> First, let me apologize for this very late entry, it&#39;s the end<br> of university and it&#39;s been a very busy period, I hope you will still<b= r> consider it.<br> <br></div><div class=3D"im"> Note this email is best read using a fixed font.<br> <br> PS: I&#39;m really sorry if this is the wrong mailing list to post and I<br=

<br> =3D=3D=3D=3D=3D=3D=3D Google Summer of Code Proposal: Statically Checked Un= its =3D=3D=3D=3D=3D=3D=3D<br> </div></blockquote> [snip]<br> <br> This is a good place to discuss pre-submission proposals. To submit, go to = <a href=3D"http://d-programming-language.org/gsoc2011.html" target=3D"_blan= k">http://d-programming-language.org/gsoc2011.html</a> later today.<br> <br> This is a strong draft proposal that I am likely to back up when complete. = A few notes:<br> <br> * There is a good overview of existing work, which puts the proponent in th= e right position to make the best choices for an implementation in D.<br> <br> * Human-readable strings as means to generate types is a fertile direction.= One issue is canonicalization, e.g. &quot;meters^2&quot; would be a differ= ent type from &quot;meters ^ 2&quot; (and btw that should mimic D&#39;s ope= rators, so it should use &quot;^^&quot;), and both are different from the s= emantically equivalent &quot;meters*meters&quot;. I think this is avoidable= by a function that brings all strings to a canonical form. This needs to b= e discussed in the proposal.<br> <br> * The approach to quantities of discrete objects (widgets, gadgets and I ho= pe to see examples with degrees, radians etc.) is very promising. I&#39;m a= lso looking forward to a &quot;Categorical&quot; type - an integer-based qu= antity that describes a bounded enumeration of objects, for example &quot;C= ityID&quot;. Categorical measures are not supposed to support arithmetic; t= hey simply identify distinct objects in an unrelated space.<br> <br> * In the final proposal the scope of the library should be clarified (e.g. = what kinds of units and related idioms will be supported, and what kinds yo= u chose not to support and why).<br> <br> * At best the proposal could define and project a relationship with std.dat= etime, which defines a few units itself. Wonder whether it&#39;s possible t= o simplify std.datetime by using the future units library.<br> <br> <br> Thanks for your interest, and good luck!<br><font color=3D"#888888"> <br> Andrei<br> </font></blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzaren= co)<br>Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco"=
http://www.google.com/profiles/cristi.cobzarenco</a><br>

--00032557595af659ac049f9092a8--
Mar 28 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Cristi Cobzarenco wrote:
 Again I will have to think some more about the latter point. And I'll do
 some more tests on the performance of doing linear searches. Is there way to
 get the name of a type (as a string) at compile time (not the mangled name
 you get at runtime)? I wasn't able to find any way to do this. My original
 idea was actually to use the fully qualified typenames to create the
 ordering.

T.stringof where T is some type gives you the name of the type at compile time. Jens
Mar 28 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-03-28 12:53, Andrei Alexandrescu wrote:
 * At best the proposal could define and project a relationship with
 std.datetime, which defines a few units itself. Wonder whether it's
 possible to simplify std.datetime by using the future units library.

Well, I can't say what's possible before we actually have a proposed units module, but I doubt that there's much in std.datetime which could be simplified by having a units library. The units portion of it is a fairly small piece. There are functions templatized on time units, but that's all so generic that it's not exactly much code. So, it'll be interesting to see how a units module might relate to it, but I question that it would really do much to simplify it. - Jonathan M Davis
Mar 28 2011
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Cristi Cobzarenco wrote:
 First, let me apologize for this very late entry, it's the end 
 of university and it's been a very busy period, I hope you will still 
 consider it.
 
 Note this email is best read using a fixed font.
 
 PS: I'm really sorry if this is the wrong mailing list to post and I 
 hope you'll forgive me if that's the case.
 
 ======= Google Summer of Code Proposal: Statically Checked Units =======
 
 
 Abstract
 -------------
 
 Measurement units allow to statically check the correctness of 
 assignments and expressions at virtually no performance cost and very 
 little extra effort. When it comes to physics the advantages are obvious 
  if you try to assign a force a variable measuring distance, you've 
 most certainly got a formula wrong somewhere along the way. Also, 
 showing a sensor measurement in gallons on a litre display that keeps 
 track of the remaining fuel of a plane (a big no-no) is easily avoidable 
 with this technique. What this translates is that one more of the many 
 hidden assumptions in source code is made visible: units naturally 
 complement other contract checking techniques, like assertions, 
 invariants and the like. After all the unit that a value is measured in 
 is part of the contract.

This is one of those features that gets proposed frequently in multiple languages. It's a great example for metaprogramming. But, are there examples of this idea being seriously *used* in production code in ANY language? (For example, does anybody actually use Boost.Unit?)
Mar 29 2011
next sibling parent reply Don <nospam nospam.com> writes:
Cristi Cobzarenco wrote:
 To Don:
 That is a very good point and I agree that one shouldn't implement 
 features just because they're popular. There don't seem to be many (if 
 any projects) using Boost.Units and only a few that use the feature in F#.
 But, I think the reason Boost.Units isn't use hasn't got much to do with 
 the idea as much as it does with the implementation. Using units in 
 Boost is very cumbersome. Adding new units (measuring different 
 dimensions) on-the-fly is virtually impossible. I think that that 
 Boost.Units misses the point of units. They should be a natural 
 extension of the type system of a language, not something so limited to 
 the area of natural sciences. D is a new language and we should be 
 pushing the envelope, just because the Boost failed (if it did, it may 
 very well kick-off later) doesn't mean we shouldn't do it. Since it is 
 such a new feature, I think we should talk about its potential rather 
 than its acceptance.
 When it comes to F#, I think the reason there aren't many projects using 
 units is because there aren't many projects in F# period. It is a very 
 popular feature in the F# community (judging by blog posts and the like) 
 and people are still trying to figure out exactly how to use it. I feel 
 that in F#, it has the potential to become very widely used once people 
 agree on some conventions and good practices.
 As I said in the abstract, I think the feature fits snugly with other 
 mechanisms in D and seems to be a natural part of a contract-based 
 design, so D programmers should have a predisposition (that C++ 
 programmers might not have) of adopting such a feature.
 
 I really hope this doesn't come off as rude; as I said, you make a very 
 good point, one that needs answering. I guess what I'm saying can be 
 summed up as: it is a new feature; there have been mistakes; it has a 
 lot of potential and we can make it better. I'd be curious to hear what 
 you think.

I'm a physicist and most of my programming involves quantities which have units. Yet, I can't really imagine myself using a units library. A few observations from my own code: * For each dimension, choose a unit, and use it throughout the code. For example, my code always uses mm because it's a natural size for the work I do. Mixing (say) cm and m is always a design mistake. Scaling should happen only at input and output, not in internal calculations. (So my feeling is, that the value of a units library would come from keeping track of dimension rather than scale). * Most errors involving units can, in my experience, easily be flushed out with a couple of unit tests. This is particularly true of scale errors. The important use cases would be situations where that isn't true. * Arrays are very important. Although an example may have force = mass * accelaration, in real code mass won't be a double, it'll be an array of doubles.
 Since it is
 such a new feature, I think we should talk about its potential rather
 than its acceptance.

I'm really glad you've said that. It's important to be clear that doing a perfect job on this project does not necessarily mean that we end up with a widely used library. You might be right that the implementations have held back widespread use -- I just see a significant risk that we end up with an elegant, well written library that never gets used. If the author is aware of that risk, it's OK. If not, it would be a very depressing thing to discover after the project was completed.
Mar 29 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/29/2011 07:36 AM, Don wrote:
 I'm a physicist and most of my programming involves quantities which
 have units. Yet, I can't really imagine myself using a units library. A
 few observations from my own code:
 * For each dimension, choose a unit, and use it throughout the code. For
 example, my code always uses mm because it's a natural size for the work
 I do. Mixing (say) cm and m is always a design mistake. Scaling should
 happen only at input and output, not in internal calculations. (So my
 feeling is, that the value of a units library would come from keeping
 track of dimension rather than scale).

Many of my bugs involving numeric code is that I mix scalars with units, not units of different scale. Andrei
Mar 29 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/29/2011 03: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.
 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.

 3. Abandon using types as units and just use strings all the way. This
 doesn't guarantee unit name uniqueness and a misspelled unit name is a new
 unit. One could use an algorithm to convert all strings to a cannonical form
 (like Andrei suggested) and then use string equality for unit equality.

 What do you think, I'm personally quite divided:
 1. I like that this is simple and it works. It make writing derived units
 unnatural though.
 2. I actually like this one, despite the obvious ugliness. It's just one
 extra line at the beginning of your code and you can the use arithmetic
 operations and use type-uniqueness to guarantee unit-uniqueness.
 3. This is a bit dangerous. It works very well as long as there isn't more
 than one system of units. I still like it a bit.

Have you considered 0. Derived units are declared? After all, relative to the size of an app, and the amount of work it represents, declaring actually used derived units is very a small burden. This means instead of: struct meter {} struct second {} auto dist = Quantity!"meter"(3.0); auto time = Quantity!"second"(2.0); auto speed = Quantity!"meter/second"(dist/time); auto surface = Quantity!"meter2"(dist*dist); one would write: struct meter {} struct second {} alias FractionUnit!(meter,second) meterPerSecond; alias PowerUnit!(meter,2) squareMeter; auto dist = Quantity!meter(3.0); auto time = Quantity!second(2.0); auto speed = Quantity!meterPerSecond(dist/time); auto surface = Quantity!squareMeter(dist*dist); This means you use struct templates as unit-id factories, for user's convenience. The constructor would then generate the metadata needed for unit-type checking, strored on the struct itself (this is far more easily using such struct templates than by parsing a string). In addition to the 2 struct templates above, there should be struct ProductUnit(Units...) {...} (accepting n base units); and I guess that's all, isn't it? The only drawback is that very complicated derived units need be constructed step by step. But this can also be seen as an advantage. An alternative may be to have a single, but more sophisticated and more difficult to use, struct template. I find several advantages to this approach: * Simplicity (also of implementation, I guess). * Unit identifiers are structs all along (both in code and in semantics). * No string mixin black voodoo. I guess even if this is not ideal, you could start with something similar, because it looks easier and cleaner (to me). A similar system may be used for units of diff scales in the same dimension: alias ScaleUnit!(mm,1_000_000) km; By the way, have you considered unit-less (pseudo-)magnitudes (I mean ratios, including %). I would have one declared and exported as constant. then, alias ScaleUnit!(voidUnit,0.001) perthousand;
 To Don:
 * Choosing one unit and using it is still a very good idea. As I said there
 are to be no implicit conversions, so this system would ensure you don't, by
 mistake, adhere to this convention. Also, if somebody else uses your library
 maybe they assume everything is in meters when in fact you use milimeters.
 Sure they should check the documentation, but it's better if they get a nice
 error message "Inferred unit Meter doesn't match expected Milimeter", or
 something like that.

I agree with this. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 29 2011
prev sibling parent reply David Nadlinger <see klickverbot.at> writes:
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
Mar 29 2011
parent reply David Nadlinger <see klickverbot.at> writes:
On 3/30/11 12:20 AM, Cristi Cobzarenco wrote:
 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.

But how would you make them _implicitly_ convertible then? David
Mar 29 2011
parent David Nadlinger <see klickverbot.at> writes:
On 3/30/11 11:21 AM, Cristi Cobzarenco wrote:
 Seems right to me, am I missing something?

opAssign isn't taken into consideration when initializing variables or passing values to functions. An example probably says more than thousand words: --- struct Test { ref Test opAssign(int i) { value = i; return this; } int value; } void foo(Test t) {} void main() { // Neither of the following two lines compiles, IIRC: Test t = 4; // (1) foo(4); // (2) } --- You can make case (1) work by defining a static opCall taking an int, which will be called due to property syntax, but I can't think of any solution for (2). David
Mar 30 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 03/29/2011 02:06 AM, Don wrote:
 Cristi Cobzarenco wrote:
 First, let me apologize for this very late entry, it's the end of
 university and it's been a very busy period, I hope you will still
 consider it.

 Note this email is best read using a fixed font.

 PS: I'm really sorry if this is the wrong mailing list to post and I
 hope you'll forgive me if that's the case.

 ======= Google Summer of Code Proposal: Statically Checked Units =======


 Abstract
 -------------

 Measurement units allow to statically check the correctness of
 assignments and expressions at virtually no performance cost and very
 little extra effort. When it comes to physics the advantages are
 obvious  if you try to assign a force a variable measuring distance,
 you've most certainly got a formula wrong somewhere along the way.
 Also, showing a sensor measurement in gallons on a litre display that
 keeps track of the remaining fuel of a plane (a big no-no) is easily
 avoidable with this technique. What this translates is that one more
 of the many hidden assumptions in source code is made visible: units
 naturally complement other contract checking techniques, like
 assertions, invariants and the like. After all the unit that a value
 is measured in is part of the contract.

This is one of those features that gets proposed frequently in multiple languages. It's a great example for metaprogramming. But, are there examples of this idea being seriously *used* in production code in ANY language? (For example, does anybody actually use Boost.Unit?)

At work we use C++ enums for categorical types to great effect. The way it works is: enum UserId { min = 0, max = 1 << 31 }; enum AppId { min = 0, max = 1 << 31 }; then we express data in terms of UserID, AppId instead of an integral type, and we cast to it when we read it off the wire or the database. The beauty of it is that you can never pass by mistake an AppId instead of a UserId of vice versa, or even a raw int as one without explicitly stating intent. It's saved us a lot of bugs (I know because I found some when converting raw ints to enums) and presumably potential bugs. If we used quantities probably a similar benefit would emerge from using dimensional analysis. I know that in my machine learning code it's very difficult to spot bugs because "it's all numbers". If I used a sort of a double "enum" that could only be a probability, I'm sure I'd save myself a ton of bugs. Andrei
Mar 29 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/29/11 2:17 PM, spir wrote:
 On 03/29/2011 04:45 PM, Andrei Alexandrescu wrote:
 Waow, this is a great explanation of expected benefits of units, I guess.
 Also, isn't this precisely the power of true typedefs?

Typedefs would not allow defining categorical types (e.g. no arithmetic). Fortunately there are already means in the language for defining such types. Andrei
Mar 29 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 03/29/2011 04:45 PM, Andrei Alexandrescu wrote:
 On 03/29/2011 02:06 AM, Don wrote:
 Cristi Cobzarenco wrote:
 First, let me apologize for this very late entry, it's the end of
 university and it's been a very busy period, I hope you will still
 consider it.

 Note this email is best read using a fixed font.

 PS: I'm really sorry if this is the wrong mailing list to post and I
 hope you'll forgive me if that's the case.

 ======= Google Summer of Code Proposal: Statically Checked Units =======


 Abstract
 -------------

 Measurement units allow to statically check the correctness of
 assignments and expressions at virtually no performance cost and very
 little extra effort. When it comes to physics the advantages are
 obvious – if you try to assign a force a variable measuring distance,
 you've most certainly got a formula wrong somewhere along the way.
 Also, showing a sensor measurement in gallons on a litre display that
 keeps track of the remaining fuel of a plane (a big no-no) is easily
 avoidable with this technique. What this translates is that one more
 of the many hidden assumptions in source code is made visible: units
 naturally complement other contract checking techniques, like
 assertions, invariants and the like. After all the unit that a value
 is measured in is part of the contract.

This is one of those features that gets proposed frequently in multiple languages. It's a great example for metaprogramming. But, are there examples of this idea being seriously *used* in production code in ANY language? (For example, does anybody actually use Boost.Unit?)

At work we use C++ enums for categorical types to great effect. The way it works is: enum UserId { min = 0, max = 1 << 31 }; enum AppId { min = 0, max = 1 << 31 }; then we express data in terms of UserID, AppId instead of an integral type, and we cast to it when we read it off the wire or the database. The beauty of it is that you can never pass by mistake an AppId instead of a UserId of vice versa, or even a raw int as one without explicitly stating intent. It's saved us a lot of bugs (I know because I found some when converting raw ints to enums) and presumably potential bugs. If we used quantities probably a similar benefit would emerge from using dimensional analysis. I know that in my machine learning code it's very difficult to spot bugs because "it's all numbers". If I used a sort of a double "enum" that could only be a probability, I'm sure I'd save myself a ton of bugs.

Waow, this is a great explanation of expected benefits of units, I guess. Also, isn't this precisely the power of true typedefs? Denis -- _________________ vita es estrany spir.wikidot.com
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00235429cf3008edd5049f9bb386
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

To Don:
That is a very good point and I agree that one shouldn't implement features
just because they're popular. There don't seem to be many (if any projects)
using Boost.Units and only a few that use the feature in F#.
But, I think the reason Boost.Units isn't use hasn't got much to do with th=
e
idea as much as it does with the implementation. Using units in Boost is
very cumbersome. Adding new units (measuring different dimensions)
on-the-fly is virtually impossible. I think that that Boost.Units misses th=
e
point of units. They should be a natural extension of the type system of a
language, not something so limited to the area of natural sciences. D is a
new language and we should be pushing the envelope, just because the Boost
failed (if it did, it may very well kick-off later) doesn't mean we
shouldn't do it. Since it is such a new feature, I think we should talk
about its potential rather than its acceptance.
When it comes to F#, I think the reason there aren't many projects using
units is because there aren't many projects in F# period. It is a very
popular feature in the F# community (judging by blog posts and the like) an=
d
people are still trying to figure out exactly how to use it. I feel that in
F#, it has the potential to become very widely used once people agree on
some conventions and good practices.
As I said in the abstract, I think the feature fits snugly with other
mechanisms in D and seems to be a natural part of a contract-based design,
so D programmers should have a predisposition (that C++ programmers might
not have) of adopting such a feature.

I really hope this doesn't come off as rude; as I said, you make a very goo=
d
point, one that needs answering. I guess what I'm saying can be summed up
as: it is a new feature; there have been mistakes; it has a lot of potentia=
l
and we can make it better. I'd be curious to hear what you think.

To spir:
Calling the string representation a small domain specific language is
perfect. It is just that, a way of writing arithmetic expressions between
types - something we couldn't do inside D grammar. It's much like the lambd=
a
definitions in functional. I too am queasy about using strings to represent
code, but I think that small DSLs that save effort and improve readability
is one place where it's OK.
Parsing the expressions at compile time will be fun, thankfully one only
needs a stack to do that (Djikstra's shunting yard algorithm) which very is
to implement in the functional-style metaprogramming land.

To David:
Using T.stringof, we can define a total order on types, based on their
typenames. I'm still thinking about conversion.

To Andrei and Jens:
std.datetime won't be simplified _that_ much, but it will probably require
some work so that it uses the same unit system as the future units library.
I would, of course, take care of this as well.

On 29 March 2011 09:06, Don <nospam nospam.com> wrote:

 Cristi Cobzarenco wrote:

 First, let me apologize for this very late entry, it's the end of
 university and it's been a very busy period, I hope you will still consi=


 it.

 Note this email is best read using a fixed font.

 PS: I'm really sorry if this is the wrong mailing list to post and I hop=


 you'll forgive me if that's the case.


 =3D=3D=3D=3D=3D=3D=3D Google Summer of Code Proposal: Statically Checked=


 Abstract
 -------------

 Measurement units allow to statically check the correctness of assignmen=


 and expressions at virtually no performance cost and very little extra
 effort. When it comes to physics the advantages are obvious =96 if you t=


 assign a force a variable measuring distance, you've most certainly got =


 formula wrong somewhere along the way. Also, showing a sensor measuremen=


 gallons on a litre display that keeps track of the remaining fuel of a p=


 (a big no-no) is easily avoidable with this technique. What this transla=


 is that one more of the many hidden assumptions in source code is made
 visible: units naturally complement other contract checking techniques, =


 assertions, invariants and the like. After all the unit that a value is
 measured in is part of the contract.

This is one of those features that gets proposed frequently in multiple languages. It's a great example for metaprogramming. But, are there examp=

 of this idea being seriously *used* in production code in ANY language?
 (For example, does anybody actually use Boost.Unit?)

--=20 (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --00235429cf3008edd5049f9bb386 Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable To Don:<div>That is a very good point and I agree that one shouldn&#39;t im= plement features just because they&#39;re popular. There don&#39;t seem to = be many (if any projects) using Boost.Units and only a few that use the fea= ture in F#.</div> <div>But, I think the reason Boost.Units isn&#39;t use hasn&#39;t got much = to do with the idea as much as it does with the implementation. Using units= in Boost is very cumbersome. Adding new units (measuring different dimensi= ons) on-the-fly is virtually impossible. I think that that Boost.Units miss= es the point of units. They should be a natural extension of the type syste= m of a language, not something so limited to the area of natural sciences. = D is a new language and we should be pushing the envelope, just because the= Boost failed (if it did, it may very well kick-off later) doesn&#39;t mean= we shouldn&#39;t do it. Since it is such a new feature, I think we should = talk about its potential rather than its acceptance.</div> <div>When it comes to F#, I think the reason there aren&#39;t many projects= using units is because there aren&#39;t many projects in F# period. It is = a very popular feature in the F# community (judging by blog posts and the l= ike) and people are still trying to figure out exactly how to use it. I fee= l that in F#, it has the potential to become very widely used once people a= gree on some conventions and good practices.</div> <div>As I said in the abstract, I think the feature fits snugly with other = mechanisms in D and seems to be a natural part of a contract-based design, = so D programmers should have a predisposition (that C++ programmers might n= ot have) of adopting such a feature.</div> <div><br></div><div>I really hope this doesn&#39;t come off as rude; as I s= aid, you make a very good point, one that needs answering. I guess what I&#= 39;m saying can be summed up as: it is a new feature; there have been mista= kes; it has a lot of potential and we can make it better. I&#39;d be curiou= s to hear what you think.</div> <div><br></div><div>To spir:</div><div>Calling the string representation a = small domain specific language is perfect. It is just that, a way of writin= g arithmetic expressions between types - something we couldn&#39;t do insid= e D grammar. It&#39;s much like the lambda definitions in functional. I too= am queasy about using strings to represent code, but I think that small DS= Ls that save effort and improve readability is one place where it&#39;s OK.= </div> <div>Parsing the expressions at compile time will be fun, thankfully one on= ly needs a stack to do that (Djikstra&#39;s shunting yard algorithm) which = very is to implement in the functional-style metaprogramming land.</div> <div><br></div><div>To David:</div><div>Using T.stringof, we can define a t= otal order on types, based on their typenames. I&#39;m still thinking about= conversion.</div><div><br></div><div>To Andrei and Jens:</div><div>std.dat= etime won&#39;t be simplified _that_ much, but it will probably require som= e work so that it uses the same unit system as the future units library. I = would, of course, take care of this as well.</div> <div><br><div class=3D"gmail_quote">On 29 March 2011 09:06, Don <span dir= =3D"ltr">&lt;<a href=3D"mailto:nospam nospam.com" target=3D"_blank">nospam = nospam.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style= =3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Cristi Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"><div> First, let me apologize for this very late entry, it&#39;s the end of unive= rsity and it&#39;s been a very busy period, I hope you will still consider = it.<br> <br> Note this email is best read using a fixed font.<br> <br></div> PS: I&#39;m really sorry if this is the wrong mailing list to post and I ho= pe you&#39;ll forgive me if that&#39;s the case.<div><br> <br> =3D=3D=3D=3D=3D=3D=3D Google Summer of Code Proposal: Statically Checked Un= its =3D=3D=3D=3D=3D=3D=3D<br> <br> <br></div><div> Abstract<br> -------------<br> <br> Measurement units allow to statically check the correctness of assignments = and expressions at virtually no performance cost and very little extra effo= rt. When it comes to physics the advantages are obvious =96 if you try to a= ssign a force a variable measuring distance, you&#39;ve most certainly got = a formula wrong somewhere along the way. Also, showing a sensor measurement= in gallons on a litre display that keeps track of the remaining fuel of a = plane (a big no-no) is easily avoidable with this technique. What this tran= slates is that one more of the many hidden assumptions in source code is ma= de visible: units naturally complement other contract checking techniques, = like assertions, invariants and the like. After all the unit that a value i= s measured in is part of the contract.<br> </div></blockquote> <br> This is one of those features that gets proposed frequently in multiple lan= guages. It&#39;s a great example for metaprogramming. But, are there exampl= es of this idea being seriously *used* in production code in ANY language?<= br> (For example, does anybody actually use Boost.Unit?)<br> </blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzarenco)<br>= Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco" target= =3D"_blank">http://www.google.com/profiles/cristi.cobzarenco</a><br> </div> --00235429cf3008edd5049f9bb386--
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--0016364ee744a0f026049f9e432d
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Surely, .mangleof returns unique strings? Thanks for your offer, but in my
prototype I already have sorting and operators working. You're right, again=
,
about the scope of the types, I have a few ideas on how to work around that=
,
but I don't like any of them too much, I'll play around with them and tell
you more. Thanks a lot for your feedback, I feel this collaboration will
help D in the end, no matter whose proposal gets accepted (if any). I am a
bit confused regarding your GSoC proposal, aren't you a mentor?

On 29 March 2011 13:51, David Nadlinger <see klickverbot.at> wrote:

 I am in a slight dilemma, because although I would love to share my work
 and ideas with you, right now this would automatically weaken my own unit=

 proposal in comparison to yours. However, as this would be grossly agains=

 the open source spirit, and the point of GSoC certainly can't be to
 encourage that, I'll just do it anyway.

 Regarding IDs: As I wrote in my previous post, the only point of the unit
 IDs in Boost.Units is to provide a strict total order over the set of uni=

 If you can achieve it without that (see below), you won't need any
 artificial numbers which you have to manage.

 But why would you need to be able to sort the base units in the first
 place? The answer is simple: To define a single type representation for e=

 possible unit, i.e. to implement type canonicalization. To illustrate thi=

 point, consider the following (pseudocode) example:

 auto force =3D 5.0 * newton;
 auto distance =3D 3.0 * meter;
 Quantity!(Newton, Meter) torque =3D force * distance;
 torque =3D distance * force;

 Both of the assignments to =BBtorque=AB should obviously work, because th=

 types of =BBforce * distance=AB and =BBdistance * force=AB are semantical=

 same. In a na=EFve implementation, however, the actual types would be
 different because the pairs of base units and exponents would be arranged=

 a different order, so at least one of the assignments would lead to type
 mismatch =96 because a tuple of units is, well, a tuple and not an (unord=

 set.

 And this is exactly where the strictly ordered IDs enter the scheme. By
 using them to sort the base unit/exponent pairs, you can guarantee that
 quantities semantically equivalent always end up with the same =BBphysica=

 type.

 Luckily, there is no need to require the user to manually assign sortable=

 unique IDs to each base type because we can access the mangled names of
 types at compile time, which fulfill these requirements. There are probab=

 other feasible approaches as well, but using them worked out well for me
 (you can't rely on .stringof to give unique strings). When implementing t=

 type sorting code, you might probably run into some difficulties and/or C=

 bugs, feel free to contact me for related questions (as I have already
 wasted enough time on this to get a working solution=85^^).

 Regarding strings: I might not have expressed my doubts clearly, but I
 didn't assume that your proposed system would use strings as internal
 representation at all. What I meant is that I don't see a way how, given
 =BBQuantity!("Widgets/Gadgets")=AB, to get the Widget and Gadget types in=

 inside Quantity. Incidentally, this is exactly the reason for which you
 can't use arbitrary functions/types in the =BBstring lambdas=AB from
 std.algorithm.

 David



 On 3/28/11 9:43 PM, Cristi Cobzarenco wrote:

 - I too was playing around with a units project before GSoC, that is why
 I thought doing this project was a good idea. The way I was doing it
 without numerical IDs was simply by having more complicated algorithms
 for equality, multiplications etc. For example, equality would be
 implemented as:
 template UnitTuple(P...) {
   alias P Units;
 }

 template contains( Unit, UT ) {
   /* do a linear search for Unit in UT.Units (since UT is a UnitTuple)
 - O(n)*/
 }

 template includes( UT1, UT2 ) {
   /* check for each Unit in UT1 that it is also in UT2 (using contains)
 - O(n^2) */
 }

 template equals( UT1, UT2 ) {
   immutable bool equals =3D includes!(UT1,UT2) && includes!(UT2, UT1);
 }
 Granted this means that each check takes O(n^2) where n is the number of
 different units, but it might be worth it - or not. On the small tests
 I've done it didn't seem to increase compile time significantly, but
 more research needs to be done. I think that as long as there aren't
 values with _a lot_ of units (like ten), the extra compile time
 shouldn't be noticeable. The biggest problem I have with adding IDs is
 that one will have to manage systems afterwards or have to deal with
 collisions. Neither one is very nice.

 - You're right, you don't need dimensions for implicit conversions, of
 course. And you're also right about possibly making the decision later
 about implicit conversions. The thing is F#, where units are very
 popular, only has explicit conversions, and I was trying to steer more
 towards that model.

 - I seem not to have been to clear about the way I would like to use
 strings. The names of the units in the strings have to be the type names
 that determine the units. Then one needs a function that would convert a
 string like "Meter/Second" to Division!(Meter, Second), I'm not sure how
 you would do that in C++. Maybe I'm wrong, but I can't see it.

 - I hope it is by now clear that my proposal is not, in fact, string
 based at all. The strings are just there to be able to write derived

 units in infix notation, something boost solves by using dummy objects
 with overloaded operators. The lack of ADL is a problem which I
 completely missed; I have immersed myself in C++ completely lately and
 I've gotten used to specializing templates in different scopes. These
 are the solutions I can come up with, but I will have to think some more=


 1. There is an intrusive way of solving this, by making the conversion
 factors static members of the unit types, but this would not allow, for
 example, having a Widget/Gadget counter the way I intended.
 2. The way they get away with it in F# is to use global conversion
 factors, that one manually uses. That actually is not bad at all. The
 only problem was that I was hoping that conversion between derived units
 could automatically be done using the conversion factors of the
 fundamental units: (meter/second) -> (kilometer/hour) knowing
 meter->kilometer and second->hour.

 Again I will have to think some more about the latter point. And I'll do
 some more tests on the performance of doing linear searches. Is there
 way to get the name of a type (as a string) at compile time (not the

 mangled name you get at runtime)? I wasn't able to find any way to do
 this. My original idea was actually to use the fully qualified typenames
 to create the ordering.

 Thanks a lot for your feedback, it's been very helpful, especially in
 pointing out the lack of ADL. Hope to hear from you again.


--=20 (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --0016364ee744a0f026049f9e432d Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Surely, .mangleof returns unique strings? Thanks for your offer, but in my = prototype I already have sorting and operators working. You&#39;re right, a= gain, about the scope of the types, I have a few ideas on how to work aroun= d that, but I don&#39;t like any of them too much, I&#39;ll play around wit= h them and tell you more. Thanks a lot for your feedback, I feel this colla= boration will help D in the end, no matter whose proposal gets accepted (if= any). I am a bit confused regarding your GSoC proposal, aren&#39;t you a m= entor?<div> <div><br><div class=3D"gmail_quote">On 29 March 2011 13:51, David Nadlinger= <span dir=3D"ltr">&lt;<a href=3D"mailto:see klickverbot.at">see klickverbo= t.at</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma= rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> I am in a slight dilemma, because although I would love to share my work an= d ideas with you, right now this would automatically weaken my own units pr= oposal in comparison to yours. However, as this would be grossly against th= e open source spirit, and the point of GSoC certainly can&#39;t be to encou= rage that, I&#39;ll just do it anyway.<br> <br> Regarding IDs: As I wrote in my previous post, the only point of the unit I= Ds in Boost.Units is to provide a strict total order over the set of units.= If you can achieve it without that (see below), you won&#39;t need any art= ificial numbers which you have to manage.<br> <br> But why would you need to be able to sort the base units in the first place= ? The answer is simple: To define a single type representation for each pos= sible unit, i.e. to implement type canonicalization. To illustrate this poi= nt, consider the following (pseudocode) example:<br> <br> auto force =3D 5.0 * newton;<br> auto distance =3D 3.0 * meter;<br> Quantity!(Newton, Meter) torque =3D force * distance;<br> torque =3D distance * force;<br> <br> Both of the assignments to =BBtorque=AB should obviously work, because the = types of =BBforce * distance=AB and =BBdistance * force=AB are semantically= the same. In a na=EFve implementation, however, the actual types would be = different because the pairs of base units and exponents would be arranged i= n a different order, so at least one of the assignments would lead to type = mismatch =96 because a tuple of units is, well, a tuple and not an (unorder= ed) set.<br> <br> And this is exactly where the strictly ordered IDs enter the scheme. By usi= ng them to sort the base unit/exponent pairs, you can guarantee that quanti= ties semantically equivalent always end up with the same =BBphysical=AB typ= e.<br> <br> Luckily, there is no need to require the user to manually assign sortable, = unique IDs to each base type because we can access the mangled names of typ= es at compile time, which fulfill these requirements. There are probably ot= her feasible approaches as well, but using them worked out well for me (you= can&#39;t rely on .stringof to give unique strings). When implementing the= type sorting code, you might probably run into some difficulties and/or CT= FE bugs, feel free to contact me for related questions (as I have already w= asted enough time on this to get a working solution=85^^).<br> <br> Regarding strings: I might not have expressed my doubts clearly, but I didn= &#39;t assume that your proposed system would use strings as internal repre= sentation at all. What I meant is that I don&#39;t see a way how, given =BB= Quantity!(&quot;Widgets/Gadgets&quot;)=AB, to get the Widget and Gadget typ= es in scope inside Quantity. Incidentally, this is exactly the reason for w= hich you can&#39;t use arbitrary functions/types in the =BBstring lambdas= =AB from std.algorithm.<br> <br> David<div class=3D"im"><br> <br> <br> On 3/28/11 9:43 PM, Cristi Cobzarenco wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div><div></div><div class=3D"h5"> - I too was playing around with a units project before GSoC, that is why<br=

without numerical IDs was simply by having more complicated algorithms<br> for equality, multiplications etc. For example, equality would be<br> implemented as:<br> template UnitTuple(P...) {<br> =A0 alias P Units;<br> }<br> <br> template contains( Unit, UT ) {<br> =A0 /* do a linear search for Unit in UT.Units (since UT is a UnitTuple)<b= r> - O(n)*/<br> }<br> <br> template includes( UT1, UT2 ) {<br> =A0 /* check for each Unit in UT1 that it is also in UT2 (using contains)<= br> - O(n^2) */<br> }<br> <br> template equals( UT1, UT2 ) {<br> =A0 immutable bool equals =3D includes!(UT1,UT2) &amp;&amp; includes!(UT2,= UT1);<br> }<br> Granted this means that each check takes O(n^2) where n is the number of<br=

I&#39;ve done it didn&#39;t seem to increase compile time significantly, bu= t<br> more research needs to be done. I think that as long as there aren&#39;t<br=

shouldn&#39;t be noticeable. The biggest problem I have with adding IDs is<= br> that one will have to manage systems afterwards or have to deal with<br> collisions. Neither one is very nice.<br> <br> - You&#39;re right, you don&#39;t need dimensions for implicit conversions,= of<br> course. And you&#39;re also right about possibly making the decision later<= br> about implicit conversions. The thing is F#, where units are very<br> popular, only has explicit conversions, and I was trying to steer more<br> towards that model.<br> <br> - I seem not to have been to clear about the way I would like to use<br> strings. The names of the units in the strings have to be the type names<br=


ot sure how<br> you would do that in C++. Maybe I&#39;m wrong, but I can&#39;t see it.<br> <br> - I hope it is by now clear that my proposal is not, in fact, string<br></d= iv></div> based at all. The strings are just there to be able to write derived<div cl= ass=3D"im"><br> units in infix notation, something boost solves by using dummy objects<br> with overloaded operators. The lack of ADL is a problem which I<br> completely missed; I have immersed myself in C++ completely lately and<br> I&#39;ve gotten used to specializing templates in different scopes. These<b= r> are the solutions I can come up with, but I will have to think some more:<b= r> 1. There is an intrusive way of solving this, by making the conversion<br> factors static members of the unit types, but this would not allow, for<br> example, having a Widget/Gadget counter the way I intended.<br> 2. The way they get away with it in F# is to use global conversion<br> factors, that one manually uses. That actually is not bad at all. The<br> only problem was that I was hoping that conversion between derived units<br=

fundamental units: (meter/second) -&gt; (kilometer/hour) knowing<br> meter-&gt;kilometer and second-&gt;hour.<br> <br></div><div class=3D"im"> Again I will have to think some more about the latter point. And I&#39;ll d= o<br> some more tests on the performance of doing linear searches. Is there<br></= div> way to get the name of a type (as a string) at compile time (not the<div cl= ass=3D"im"><br> mangled name you get at runtime)? I wasn&#39;t able to find any way to do<b= r> this. My original idea was actually to use the fully qualified typenames<br=

<br></div><div class=3D"im"> Thanks a lot for your feedback, it&#39;s been very helpful, especially in<b= r> pointing out the lack of ADL. Hope to hear from you again.<br> </div></blockquote> </blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzarenco)<br>= Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco">http:/= /www.google.com/profiles/cristi.cobzarenco</a><br> </div></div> --0016364ee744a0f026049f9e432d--
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--0016364ee7448f3a20049f9f547f
Content-Type: text/plain; charset=ISO-8859-1

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.
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.

3. Abandon using types as units and just use strings all the way. This
doesn't guarantee unit name uniqueness and a misspelled unit name is a new
unit. One could use an algorithm to convert all strings to a cannonical form
(like Andrei suggested) and then use string equality for unit equality.

What do you think, I'm personally quite divided:
1. I like that this is simple and it works. It make writing derived units
unnatural though.
2. I actually like this one, despite the obvious ugliness. It's just one
extra line at the beginning of your code and you can the use arithmetic
operations and use type-uniqueness to guarantee unit-uniqueness.
3. This is a bit dangerous. It works very well as long as there isn't more
than one system of units. I still like it a bit.

The only completely clean alternative would be the abominable:
Quantity!( mixin(Expr!("Metre/Second")) ) q;



To Don:
* Choosing one unit and using it is still a very good idea. As I said there
are to be no implicit conversions, so this system would ensure you don't, by
mistake, adhere to this convention. Also, if somebody else uses your library
maybe they assume everything is in meters when in fact you use milimeters.
Sure they should check the documentation, but it's better if they get a nice
error message "Inferred unit Meter doesn't match expected Milimeter", or
something like that.
* True, scale errors can be figured out easily, multiplying something with
an acceleration instead of velocity, or forgetting to multiply acceleration
by a timestep isn't as easily checked. Multiplying instead of dividing in a
formula, or forgetting to divide by a normalisation constant are other
things you may forget, and are caught instantly by unit checking.
* Arrays & vectors are very important, I agree. The Quantity! type is
parametrised both by a unit and a value type, therefore, if one wants a
vector whose components are of the same unit, using "Quantity!(Metre,
Vector!(double))" would work. Vector!(Quantity!(Metre,double)) would also
work. As long as the value type has arithmetic operations defined everything
works out. Same goes for arrays.

There is a risk that it never gets used, sure. But I think that units will
become commonplace, some time in the future, so while it won't get wide
acceptance very soon, at some point people will be looking on Wikipedia for
"Languages supporting measurement units" and it will be good for D to show
up there.




On 29 March 2011 14:36, Don <nospam nospam.com> wrote:

 Cristi Cobzarenco wrote:

 To Don:
 That is a very good point and I agree that one shouldn't implement
 features just because they're popular. There don't seem to be many (if any
 projects) using Boost.Units and only a few that use the feature in F#.
 But, I think the reason Boost.Units isn't use hasn't got much to do with
 the idea as much as it does with the implementation. Using units in Boost is
 very cumbersome. Adding new units (measuring different dimensions)
 on-the-fly is virtually impossible. I think that that Boost.Units misses the
 point of units. They should be a natural extension of the type system of a
 language, not something so limited to the area of natural sciences. D is a
 new language and we should be pushing the envelope, just because the Boost
 failed (if it did, it may very well kick-off later) doesn't mean we
 shouldn't do it. Since it is such a new feature, I think we should talk
 about its potential rather than its acceptance.
 When it comes to F#, I think the reason there aren't many projects using
 units is because there aren't many projects in F# period. It is a very
 popular feature in the F# community (judging by blog posts and the like) and
 people are still trying to figure out exactly how to use it. I feel that in
 F#, it has the potential to become very widely used once people agree on
 some conventions and good practices.
 As I said in the abstract, I think the feature fits snugly with other
 mechanisms in D and seems to be a natural part of a contract-based design,
 so D programmers should have a predisposition (that C++ programmers might
 not have) of adopting such a feature.

 I really hope this doesn't come off as rude; as I said, you make a very
 good point, one that needs answering. I guess what I'm saying can be summed
 up as: it is a new feature; there have been mistakes; it has a lot of
 potential and we can make it better. I'd be curious to hear what you think.

I'm a physicist and most of my programming involves quantities which have units. Yet, I can't really imagine myself using a units library. A few observations from my own code: * For each dimension, choose a unit, and use it throughout the code. For example, my code always uses mm because it's a natural size for the work I do. Mixing (say) cm and m is always a design mistake. Scaling should happen only at input and output, not in internal calculations. (So my feeling is, that the value of a units library would come from keeping track of dimension rather than scale). * Most errors involving units can, in my experience, easily be flushed out with a couple of unit tests. This is particularly true of scale errors. The important use cases would be situations where that isn't true. * Arrays are very important. Although an example may have force = mass * accelaration, in real code mass won't be a double, it'll be an array of doubles.
 Since it is
 such a new feature, I think we should talk about its potential rather
 than its acceptance.

I'm really glad you've said that. It's important to be clear that doing a perfect job on this project does not necessarily mean that we end up with a widely used library. You might be right that the implementations have held back widespread use -- I just see a significant risk that we end up with an elegant, well written library that never gets used. If the author is aware of that risk, it's OK. If not, it would be a very depressing thing to discover after the project was completed.

-- (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --0016364ee7448f3a20049f9f547f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div>To David:</div>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&#39;t see any performance increase in the .mangleof one, but i= f .mangleof returns unique string, I say we use it this way.<div> Regarding my string little DSL. I have 3 solutions right now:</div><div>1. = Drop the DSL altogether, right now my system would work perfectly fine with= boost-like tuples (a list of units alternating with exponents):</div><div> Quantity!(Metre,1,Second,-1) speed =3D distance/time;</div><div>While less = readable, this doesn&#39;t have the disadvantages of the following 2.</div>= <div><br></div><div>2. Use a mixin template to declare the expression parse= r in the current scope:</div> <div>mixin DeclareExprQuantity!();</div><div><br></div><div>struct Metre {}= </div><div>struct Second {}</div><div>struct Kg {}</div><div><br></div><div=
void f() {</div><div>=A0=A0 =A0 =A0 ExprQuantity!(&quot;Metre/Second * Kg^=

<div>}</div><div>This works, is readable, but it uses C-preprocessor like b= ehaviour (read: black vodoo) - a library declaring something in your scope = isn&#39;t very nice.<br><br></div><div>3. Abandon using types as units and = just use strings all the way. This doesn&#39;t guarantee unit name uniquene= ss and a misspelled unit name is a new unit. One could use an algorithm to = convert all strings to a cannonical form (like Andrei suggested) and then u= se string equality for unit equality.</div> <div><br></div><div>What do you think, I&#39;m personally quite divided:</d= iv><div>1. I like that this is simple and it works. It make writing derived= units unnatural though.</div><div>2. I actually like this one, despite the= obvious ugliness. It&#39;s just one extra line at the beginning of your co= de and you can the use arithmetic operations and use type-uniqueness to gua= rantee unit-uniqueness.</div> <div>3. This is a bit dangerous. It works very well as long as there isn&#3= 9;t more than one system of units. I still like it a bit.</div><div><br></d= iv><div>The only completely clean alternative would be the=A0abominable:</d= iv> <div>Quantity!( mixin(Expr!(&quot;Metre/Second&quot;)) ) q;</div><div><br><= /div><div><br></div><div><br></div><div>To Don:</div><div>* Choosing one un= it and using it is still a very good idea. As I said there are to be no imp= licit conversions, so this system would ensure you don&#39;t, by mistake, a= dhere to this convention. Also, if somebody else uses your library maybe th= ey assume everything is in meters when in fact you use milimeters. Sure the= y should check the documentation, but it&#39;s better if they get a nice er= ror message &quot;Inferred unit Meter doesn&#39;t match expected Milimeter&= quot;, or something like that.</div> <div>* True, scale errors can be figured out easily, multiplying something = with an acceleration instead of velocity, or forgetting to multiply acceler= ation by a timestep isn&#39;t as easily checked. Multiplying instead of div= iding in a formula, or forgetting to divide by a normalisation constant are= other things you may forget, and are caught instantly by unit checking.</d= iv> <div>* Arrays &amp; vectors are very important, I agree. The Quantity! type= is parametrised both by a unit and a value type, therefore, if one wants a= vector whose components are of the same unit, using &quot;Quantity!(Metre,= Vector!(double))&quot; would work. Vector!(Quantity!(Metre,double)) would = also work. As long as the value type has arithmetic operations defined ever= ything works out. Same goes for arrays.</div> <div><br></div><div>There is a risk that it never gets used, sure. But I th= ink that units will become commonplace, some time in the future, so while i= t won&#39;t get wide acceptance very soon, at some point people will be loo= king on Wikipedia for &quot;Languages supporting measurement units&quot; an= d it will be good for D to show up there.</div> <div><br></div><div><br></div><div><br></div><div><br><div class=3D"gmail_q= uote">On 29 March 2011 14:36, Don <span dir=3D"ltr">&lt;<a href=3D"mailto:n= ospam nospam.com">nospam nospam.com</a>&gt;</span> wrote:<br><blockquote cl= ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p= adding-left:1ex;"> <div class=3D"im">Cristi Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> To Don:<br> That is a very good point and I agree that one shouldn&#39;t implement feat= ures just because they&#39;re popular. There don&#39;t seem to be many (if = any projects) using Boost.Units and only a few that use the feature in F#.<= br> But, I think the reason Boost.Units isn&#39;t use hasn&#39;t got much to do= with the idea as much as it does with the implementation. Using units in B= oost is very cumbersome. Adding new units (measuring different dimensions) = on-the-fly is virtually impossible. I think that that Boost.Units misses th= e point of units. They should be a natural extension of the type system of = a language, not something so limited to the area of natural sciences. D is = a new language and we should be pushing the envelope, just because the Boos= t failed (if it did, it may very well kick-off later) doesn&#39;t mean we s= houldn&#39;t do it. Since it is such a new feature, I think we should talk = about its potential rather than its acceptance.<br> When it comes to F#, I think the reason there aren&#39;t many projects usin= g units is because there aren&#39;t many projects in F# period. It is a ver= y popular feature in the F# community (judging by blog posts and the like) = and people are still trying to figure out exactly how to use it. I feel tha= t in F#, it has the potential to become very widely used once people agree = on some conventions and good practices.<br> As I said in the abstract, I think the feature fits snugly with other mecha= nisms in D and seems to be a natural part of a contract-based design, so D = programmers should have a predisposition (that C++ programmers might not ha= ve) of adopting such a feature.<br> <br> I really hope this doesn&#39;t come off as rude; as I said, you make a very= good point, one that needs answering. I guess what I&#39;m saying can be s= ummed up as: it is a new feature; there have been mistakes; it has a lot of= potential and we can make it better. I&#39;d be curious to hear what you t= hink.<br> </blockquote> <br></div> I&#39;m a physicist and most of my programming involves quantities which ha= ve units. Yet, I can&#39;t really imagine myself using a units library. A f= ew observations from my own code:<br> * For each dimension, choose a unit, and use it throughout the code. For ex= ample, my code always uses mm because it&#39;s a natural size for the work = I do. Mixing (say) cm and m is always a design mistake. Scaling should happ= en only at input and output, not in internal calculations. (So my feeling i= s, that the value of a units library would come from keeping track of dimen= sion rather than scale).<br> * Most errors involving units can, in my experience, easily be flushed out = with a couple of unit tests. This is particularly true of scale errors. The= important use cases would be situations where that isn&#39;t true.<br> * Arrays are very important. Although an example may have force =3D mass * = accelaration, in real code mass won&#39;t be a double, it&#39;ll be an arra= y of doubles.<div class=3D"im"><br> <br> &gt; Since it is<br> &gt; such a new feature, I think we should talk about its potential rather<= br> &gt; than its acceptance.<br> <br></div> I&#39;m really glad you&#39;ve said that. It&#39;s important to be clear th= at doing a perfect job on this project does not necessarily mean that we en= d up with a widely used library. You might be right that the implementation= s have held back widespread use -- I just see a significant risk that we en= d up with an elegant, well written library that never gets used.<br> If the author is aware of that risk, it&#39;s OK. If not, it would be a ver= y depressing thing to discover after the project was completed.<br> <br> </blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzarenco)<br>= Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco">http:/= /www.google.com/profiles/cristi.cobzarenco</a><br> </div> --0016364ee7448f3a20049f9f547f--
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--0023544713d8d16c2c049fa676fe
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

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 throug=
h
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 (lik=
e
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 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 y=

 solve the issue of different ordering of expression yielding types? This =

 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 =

 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 =3D distance/time;
 While less readable, this doesn't have the disadvantages of the followin=


 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 =3D 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.

 [=85]


 The only completely clean alternative would be the abominable:
 Quantity!( mixin(Expr!("Metre/Second")) ) q;

Get out of my head! Immediately! ;) Just kidding =96 incidentally I considered exactly the same options when designing my current prototype. =

 current approach would be a mix between 1 and 2: I don't think the Boost
 approach of using =BBdummy=AB instances of units is any less readable tha=

 proposed one when you don't deal with a lot of units. For example, consid=

 enum widgetCount =3D quantity!("Widget")(2);
 vs.
 enum widgetCount =3D 2 * widgets;

 This could also be extended to type definitions to avoid having to manual=

 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 th=

 =BBparsing template=AB, similar to the one you suggested. If a user of th=

 library things  could use an additional mixin identifier to clarify the
 code, e.g. =BBmixin UnitStringParser U; [=85] U.unit!"m/s"=AB).

 But a more attractive solution would exploit the fact that you would most=

 use units with a lot of exponents when working with a =BBclosed=AB unit s=

 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 ne=

 to be globally unique and wouldn't pollute the namespace (directly defini=

 a type =BBm=AB to express meters would probably render the module unusabl=

 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 th=

 for additional properties like short names/symbols, etc. In code:

 ---
 module units.si;
 [=85]
 alias UnitSystem!(Meter, Second, =85) Si;
 ---
 module client;
 import units.si;
 auto inductance =3D 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 li=

 the ability to add shorthand symbols.

 David

--=20 (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --0023544713d8d16c2c049fa676fe Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Well they don&#39;t _have_ to be the same type as long they&#39;re converti= ble to one another, and one can make sure they&#39;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&#39;ll be sticking to the .mangleof ver= sion. 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&#39;ll = need to define a different type). I was also considering shorthand symbols,= since it seems like a natural addition, I&#39;ll have think a bit more on = how exactly to do that, to avoid collisions.<div> Regarding if this is appropriate for GSoC. It doesn&#39;t take me 12 weeks = to write a prototype, sure. But to have a library fit to be part of the sta= ndard library of language takes a lot of laborious testing, going through u= se-cases and making sure it is highly usable. Also, there should be an effo= rt to make sure other libraries make use of units when appropriate (like An= drei suggested std.datetime) etc. As we all know it takes 90% of the time t= o code 10% of the code. I think all of this extra polish, reliability and u= sability is very important and takes the extra 11 weeks. It&#39;s not the m= ost glorified kind of work, but I really think it&#39;s worth it.<br> <br><div class=3D"gmail_quote">On 29 March 2011 23:40, David Nadlinger <spa= n dir=3D"ltr">&lt;<a href=3D"mailto:see klickverbot.at">see klickverbot.at<= /a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:= 0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On 3/29/11 3:49 PM, Cristi Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> To David:<br> Ok, right now, I got two working versions, one sorting by .mangleof and<br> one performing a double-inclusion test on the tuples. Both work, I can&#39;= t<br> see any performance increase in the .mangleof one, but if .mangleof<br> returns unique string, I say we use it this way.<br> </blockquote> <br></div> To be honest, I still don&#39;t see how you are able to get away without ca= nonicalization in the first place; would you mind to elaborate on how you s= olve the issue of different ordering of expression yielding types? This is = not about the algorithm to determine whether two types are semantically equ= ivalent, where your algorithm would work fine as well, but about the actual= D types. If you don&#39;t sort them, Quantity!(BaseUnitExp!(Meter, 1), Bas= eUnitExp!(Second, -2)) and Quantity!(BaseUnitExp!(Second, -2), BaseUnitExp!= (Meter, 1)) would be different types, which is not desirable for obvious re= asons.<br> <br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"><div class=3D"im"> Regarding my string little DSL. I have 3 solutions right now:<br> 1. Drop the DSL altogether, right now my system would work perfectly<br> fine with boost-like tuples (a list of units alternating with exponents):<b= r> Quantity!(Metre,1,Second,-1) speed =3D distance/time;<br> While less readable, this doesn&#39;t have the disadvantages of the followi= ng 2.<br> <br> 2. Use a mixin template to declare the expression parser in the current<br> scope:<br> mixin DeclareExprQuantity!();<br> <br> struct Metre {}<br> struct Second {}<br> struct Kg {}<br> <br> void f() {<br> =A0 =A0 =A0 =A0ExprQuantity!(&quot;Metre/Second * Kg^-1&quot;) q =3D speed= / mass;<br> }<br> This works, is readable, but it uses C-preprocessor like behaviour<br> (read: black vodoo) - a library declaring something in your scope isn&#39;t= <br> very nice.<br> <br></div> [=85]<div class=3D"im"><br> <br> The only completely clean alternative would be the abominable:<br> Quantity!( mixin(Expr!(&quot;Metre/Second&quot;)) ) q;<br> </div></blockquote> <br> Get out of my head! Immediately! ;) Just kidding =96 incidentally I conside= red exactly the same options when designing my current prototype. My curren= t approach would be a mix between 1 and 2: I don&#39;t think the Boost appr= oach of using =BBdummy=AB instances of units is any less readable than your= proposed one when you don&#39;t deal with a lot of units. For example, con= sider<br> <br> enum widgetCount =3D quantity!(&quot;Widget&quot;)(2);<br> vs.<br> enum widgetCount =3D 2 * widgets;<br> <br> This could also be extended to type definitions to avoid having to manually= write the template instantiation:<br> <br> Quantity!(&quot;meter / second&quot;, float) speed;<br> vs.<br> typeof(1.f * meter / second) speed;<br> <br> There are situations, though, where using unit strings could considerable i= mprove readability, namely when using lots of units with exponents. In thes= e cases, a mixin could be used to bring all the types in scope for the =BBp= arsing template=AB, similar to the one you suggested. If a user of the libr= ary things =A0could use an additional mixin identifier to clarify the code,= e.g. =BBmixin UnitStringParser U; [=85] U.unit!&quot;m/s&quot;=AB).<br> <br> But a more attractive solution would exploit the fact that you would mostly= use units with a lot of exponents when working with a =BBclosed=AB unit sy= stem without the need for ad-hoc extensions, like the SI system, which woul= d allow you to use unit symbols instead of the full name, which wouldn&#39;= t need to be globally unique and wouldn&#39;t pollute the namespace (direct= ly defining a type =BBm=AB to express meters would probably render the modu= le unusable without static imports).<br> <br> It would essentially work by instantiating a parser template with all the n= amed units. Thus, the parser would know all the types and could query them = for additional properties like short names/symbols, etc. In code:<br> <br> ---<br> module <a href=3D"http://units.si" target=3D"_blank">units.si</a>;<br> [=85]<br> alias UnitSystem!(Meter, Second, =85) Si;<br> ---<br> module client;<br> import <a href=3D"http://units.si" target=3D"_blank">units.si</a>;<br> auto inductance =3D 5.0 * Si.u!&quot;m^2 kg/(s^2 A^2)&quot;;<br> ---<br> <br> This could also be combined with the mixin parser approach like this:<br> ---<br> import <a href=3D"http://units.si" target=3D"_blank">units.si</a>;<br> mixin UnitStringParser!(Si) U;<br> ---<br> <br> But to reiterate my point, I don&#39;t think a way to parse unit strings is= terribly important, at least not if it isn&#39;t coupled with other things= like the ability to add shorthand symbols.<br><font color=3D"#888888"> <br> David<br> </font></blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzaren= co)<br>Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco"=
http://www.google.com/profiles/cristi.cobzarenco</a><br>

--0023544713d8d16c2c049fa676fe--
Mar 29 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00235429cf301d87e6049fafb27c
Content-Type: text/plain; charset=ISO-8859-1

By making the operators on quantity templates:
ref Quantity opAssign(U)( Quantity!(U) u2 ) {
static assert( SameUnit!(U,Unit) );
this.value = u2.value;
return this;
}

Same for addition, subtraction and equality. Multiplication and division
will have to have a different return type.
Seems right to me, am I missing something?

On 30 March 2011 00:39, David Nadlinger <see klickverbot.at> wrote:

 On 3/30/11 12:20 AM, Cristi Cobzarenco wrote:

 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.

But how would you make them _implicitly_ convertible then? David

-- (Cristi Cobzarenco) Pofile: http://www.google.com/profiles/cristi.cobzarenco --00235429cf301d87e6049fafb27c Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable By making the operators on quantity templates:<div><div>ref Quantity opAssi= gn(U)( Quantity!(U) u2 ) {</div><div><span class=3D"Apple-tab-span" style= =3D"white-space:pre"> </span>static assert( SameUnit!(U,Unit) );</div><div>= <span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>this.value= =3D u2.value;</div> <div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>retur= n this;</div><div>}</div><div><br></div><div>Same for addition, subtraction= and equality. Multiplication and division will have to have a different re= turn type.</div> <div>Seems right to me, am I missing something?</div><br><div class=3D"gmai= l_quote">On 30 March 2011 00:39, David Nadlinger <span dir=3D"ltr">&lt;<a h= ref=3D"mailto:see klickverbot.at">see klickverbot.at</a>&gt;</span> wrote:<= br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;"><div class=3D"im">On 3/30/11 12:20 AM, Cris= ti Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Well they don&#39;t _have_ to be the same type as long they&#39;re converti= ble<br> to one another, and one can make sure they&#39;re convertible based on the<= br> result of the double-inclusion.<br> </blockquote> <br></div> But how would you make them _implicitly_ convertible then?<br><font color= =3D"#888888"> <br> David<br> </font></blockquote></div><br><br clear=3D"all"><br>-- <br>(Cristi Cobzaren= co)<br>Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco"=
http://www.google.com/profiles/cristi.cobzarenco</a><br>

--00235429cf301d87e6049fafb27c--
Mar 30 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Maybe OT, but here's some hackish wizardry you can do with classes:

class Test
{
    int value;

    this(int x)
    {
        value = x;
    }
}

ref Test foo(Test t ...)
{
    return tuple(t)[0];
}

void main()
{
    auto result = foo(4);
    assert(result.value == 4);
}

The Tuple is used to trick DMD into escaping the local `t` reference.
This won't work with structs. And `t` should be constructed on the
stack, but it seems the destructor gets called only after the exit
from main. The docs do say that construction of classes in variadic
arguments depend on the implementation.

I asked on the newsgroups whether Typesafe Variadic Functions
automatically calling a constructor was a good thing at all. Read
about this feature here under "Typesafe Variadic Functions":
http://www.digitalmars.com/d/2.0/function.html
Mar 30 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00504502cd47372e02049fb3f837
Content-Type: text/plain; charset=ISO-8859-1

Yeah, you're right (case (1) also works with a template ctor as well - in
C++ this would allow for implicit conversions as well, that's why I thought
about using it this way). As I said, I had already abandoned this approach
and decided on using .mangleof sorting anyway for elegance. I think my
proposal write-up is almost ready, will submit it today or tomorrow.



(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco


On 30 March 2011 15:26, David Nadlinger <see klickverbot.at> wrote:

 On 3/30/11 11:21 AM, Cristi Cobzarenco wrote:

 Seems right to me, am I missing something?

opAssign isn't taken into consideration when initializing variables or passing values to functions. An example probably says more than thousand words: --- struct Test { ref Test opAssign(int i) { value = i; return this; } int value; } void foo(Test t) {} void main() { // Neither of the following two lines compiles, IIRC: Test t = 4; // (1) foo(4); // (2) } --- You can make case (1) work by defining a static opCall taking an int, which will be called due to property syntax, but I can't think of any solution for (2). David

--00504502cd47372e02049fb3f837 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Yeah, you&#39;re right (case (1) also works with a template ctor as well - = in C++ this would allow for implicit conversions as well, that&#39;s why I = thought about using it this way). As I said, I had already abandoned this a= pproach and decided on using .mangleof sorting anyway for elegance. I think= my proposal write-up is almost ready, will submit it today or tomorrow.<di= v> <br></div><div><br></div><div><br clear=3D"all">(Cristi Cobzarenco)<br>Pofi= le: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco">http://www= .google.com/profiles/cristi.cobzarenco</a><br> <br><br><div class=3D"gmail_quote">On 30 March 2011 15:26, David Nadlinger = <span dir=3D"ltr">&lt;<a href=3D"mailto:see klickverbot.at">see klickverbot= .at</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar= gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"im">On 3/30/11 11:21 AM, Cristi Cobzarenco wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Seems right to me, am I missing something?<br> </blockquote> <br></div> opAssign isn&#39;t taken into consideration when initializing variables or = passing values to functions. An example probably says more than thousand wo= rds:<br> <br> ---<br> struct Test {<br> =A0ref Test opAssign(int i) {<br> =A0 =A0value =3D i;<br> =A0 =A0return this;<br> =A0}<br> =A0int value;<br> }<br> <br> void foo(Test t) {}<br> <br> void main() {<br> =A0 =A0// Neither of the following two lines compiles, IIRC:<br> =A0 =A0Test t =3D 4; // (1)<br> =A0 =A0foo(4); // (2)<br> }<br> ---<br> <br> You can make case (1) work by defining a static opCall taking an int, which= will be called due to property syntax, but I can&#39;t think of any soluti= on for (2).<br><font color=3D"#888888"> <br> David<br> </font></blockquote></div><br></div> --00504502cd47372e02049fb3f837--
Mar 30 2011
prev sibling next sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--0015174c0daa3c1679049fb47c7e
Content-Type: text/plain; charset=ISO-8859-1

Hmmm, the only problem with this is that we would have to require the
library users to do this to their functions. Thanks for the suggestion but
I'll stick with .mangleof sorting.
(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco


On 30 March 2011 16:49, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 Maybe OT, but here's some hackish wizardry you can do with classes:

 class Test
 {
    int value;

    this(int x)
    {
        value = x;
    }
 }

 ref Test foo(Test t ...)
 {
    return tuple(t)[0];
 }

 void main()
 {
    auto result = foo(4);
    assert(result.value == 4);
 }

 The Tuple is used to trick DMD into escaping the local `t` reference.
 This won't work with structs. And `t` should be constructed on the
 stack, but it seems the destructor gets called only after the exit
 from main. The docs do say that construction of classes in variadic
 arguments depend on the implementation.

 I asked on the newsgroups whether Typesafe Variadic Functions
 automatically calling a constructor was a good thing at all. Read
 about this feature here under "Typesafe Variadic Functions":
 http://www.digitalmars.com/d/2.0/function.html

--0015174c0daa3c1679049fb47c7e Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hmmm, the only problem with this is that we would have to require the libra= ry users to do this to their functions. Thanks for the suggestion but I&#39= ;ll stick with .mangleof sorting.<div>(Cristi Cobzarenco)<br>Pofile: <a hre= f=3D"http://www.google.com/profiles/cristi.cobzarenco">http://www.google.co= m/profiles/cristi.cobzarenco</a><br> <br><br><div class=3D"gmail_quote">On 30 March 2011 16:49, Andrej Mitrovic = <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com">andrej.= mitrovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quo= te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;= "> Maybe OT, but here&#39;s some hackish wizardry you can do with classes:<br> <br> class Test<br> {<br> =A0 =A0int value;<br> <br> =A0 =A0this(int x)<br> =A0 =A0{<br> =A0 =A0 =A0 =A0value =3D x;<br> =A0 =A0}<br> }<br> <br> ref Test foo(Test t ...)<br> {<br> =A0 =A0return tuple(t)[0];<br> }<br> <br> void main()<br> {<br> =A0 =A0auto result =3D foo(4);<br> =A0 =A0assert(result.value =3D=3D 4);<br> }<br> <br> The Tuple is used to trick DMD into escaping the local `t` reference.<br> This won&#39;t work with structs. And `t` should be constructed on the<br> stack, but it seems the destructor gets called only after the exit<br> from main. The docs do say that construction of classes in variadic<br> arguments depend on the implementation.<br> <br> I asked on the newsgroups whether Typesafe Variadic Functions<br> automatically calling a constructor was a good thing at all. Read<br> about this feature here under &quot;Typesafe Variadic Functions&quot;:<br> <a href=3D"http://www.digitalmars.com/d/2.0/function.html" target=3D"_blank= ">http://www.digitalmars.com/d/2.0/function.html</a><br> </blockquote></div><br></div> --0015174c0daa3c1679049fb47c7e--
Mar 30 2011
prev sibling parent Cristi Cobzarenco <cristi.cobzarenco gmail.com> writes:
--00235447063821e5e4049fdc92b2
Content-Type: text/plain; charset=ISO-8859-1

Ok, my proposal is up, I'm looking forward to feedback.

*fingers crossed*
(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco


On 30 March 2011 17:03, Cristi Cobzarenco <cristi.cobzarenco gmail.com>wrote:

 Hmmm, the only problem with this is that we would have to require the
 library users to do this to their functions. Thanks for the suggestion but
 I'll stick with .mangleof sorting.
 (Cristi Cobzarenco)
 Pofile: http://www.google.com/profiles/cristi.cobzarenco


 On 30 March 2011 16:49, Andrej Mitrovic <andrej.mitrovich gmail.com>wrote:

 Maybe OT, but here's some hackish wizardry you can do with classes:

 class Test
 {
    int value;

    this(int x)
    {
        value = x;
    }
 }

 ref Test foo(Test t ...)
 {
    return tuple(t)[0];
 }

 void main()
 {
    auto result = foo(4);
    assert(result.value == 4);
 }

 The Tuple is used to trick DMD into escaping the local `t` reference.
 This won't work with structs. And `t` should be constructed on the
 stack, but it seems the destructor gets called only after the exit
 from main. The docs do say that construction of classes in variadic
 arguments depend on the implementation.

 I asked on the newsgroups whether Typesafe Variadic Functions
 automatically calling a constructor was a good thing at all. Read
 about this feature here under "Typesafe Variadic Functions":
 http://www.digitalmars.com/d/2.0/function.html


--00235447063821e5e4049fdc92b2 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Ok, my proposal is up, I&#39;m looking forward to feedback.<div><br></div><= div>*fingers crossed*<br clear=3D"all">(Cristi Cobzarenco)<br>Pofile: <a hr= ef=3D"http://www.google.com/profiles/cristi.cobzarenco">http://www.google.c= om/profiles/cristi.cobzarenco</a><br> <br><br><div class=3D"gmail_quote">On 30 March 2011 17:03, Cristi Cobzarenc= o <span dir=3D"ltr">&lt;<a href=3D"mailto:cristi.cobzarenco gmail.com">cris= ti.cobzarenco gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail= _quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:= 1ex;"> Hmmm, the only problem with this is that we would have to require the libra= ry users to do this to their functions. Thanks for the suggestion but I&#39= ;ll stick with .mangleof sorting.<div><div class=3D"im">(Cristi Cobzarenco)= <br> Pofile: <a href=3D"http://www.google.com/profiles/cristi.cobzarenco" target= =3D"_blank">http://www.google.com/profiles/cristi.cobzarenco</a><br> <br><br></div><div><div></div><div class=3D"h5"><div class=3D"gmail_quote">= On 30 March 2011 16:49, Andrej Mitrovic <span dir=3D"ltr">&lt;<a href=3D"ma= ilto:andrej.mitrovich gmail.com" target=3D"_blank">andrej.mitrovich gmail.c= om</a>&gt;</span> wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> Maybe OT, but here&#39;s some hackish wizardry you can do with classes:<br> <br> class Test<br> {<br> =A0 =A0int value;<br> <br> =A0 =A0this(int x)<br> =A0 =A0{<br> =A0 =A0 =A0 =A0value =3D x;<br> =A0 =A0}<br> }<br> <br> ref Test foo(Test t ...)<br> {<br> =A0 =A0return tuple(t)[0];<br> }<br> <br> void main()<br> {<br> =A0 =A0auto result =3D foo(4);<br> =A0 =A0assert(result.value =3D=3D 4);<br> }<br> <br> The Tuple is used to trick DMD into escaping the local `t` reference.<br> This won&#39;t work with structs. And `t` should be constructed on the<br> stack, but it seems the destructor gets called only after the exit<br> from main. The docs do say that construction of classes in variadic<br> arguments depend on the implementation.<br> <br> I asked on the newsgroups whether Typesafe Variadic Functions<br> automatically calling a constructor was a good thing at all. Read<br> about this feature here under &quot;Typesafe Variadic Functions&quot;:<br> <a href=3D"http://www.digitalmars.com/d/2.0/function.html" target=3D"_blank= ">http://www.digitalmars.com/d/2.0/function.html</a><br> </blockquote></div><br></div></div></div> </blockquote></div><br></div> --00235447063821e5e4049fdc92b2--
Apr 01 2011