October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to language_fan | "language_fan" <foo@bar.com.invalid> wrote in message news:hacm6o$2en$2@digitalmars.com... > Mon, 05 Oct 2009 11:41:52 +0000, language_fan wrote: >> >> There have been several existing implementations of SI unit libraries for D. By Oskar Linde et al. The checking can be built statically without any runtime performance penalty. > > The only problem with these was that there was no way to signal the location of the type error in the client code, it always reported the location of the (static) assert in the library, which is pretty much useless. Yea, that's been a problem for a *lot* of stuff... Although I think it might be fixed now... I could swear there was a patch on bugzilla for that that I had grabbed and made a custom-build of DMD with, and then saw that a newer version of DMD had incorporated it... But in my current sleepless stupor I might be confusing it with something else... |
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote: > I've been thinking it might be nice to have both. Compile-time for obvious reasons but then also run-time ones that could do conversions: > > auto velocity = convert(meter/second)(distance / time); // Actual runtime-conversion I'm pretty sure Boost.Units already does this, although in general it's probably better to stick with SI units in your code and only perform conversions on input/output. -- Rainer Deyke - rainerd@eldwood.com |
October 05, 2009 unit libraries, was Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to language_fan | language_fan wrote: > The only problem with these was that there was no way to signal the location of the type error in the client code, it always reported the location of the (static) assert in the library, which is pretty much useless. That's a compiler problem, no? I don't think this is a big deal either way. Unit errors should be exceedingly rare. The purpose of a unit library not to track down unit errors, but to formally prove that correct code is correct. -- Rainer Deyke - rainerd@eldwood.com |
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky Wrote: > "Justin Johansson" <no@spam.com> wrote in message news:ha4qpi$189h$1@digitalmars.com... > > For the interest of newsgroups readers, I dropped in at the Cafe the other > > day and > > the barista had this to say > > > > http://cafe.elharo.com/programming/imagine-theres-no-null/ > > > > Disclaimer: YMMV > > > > Cheers > > > > This is gonna sound trivial (and probably is), but it's been bugging the hell out of me: > > What is the meaning of the "+ Looney Tunes" added to the title of this sub-thread? I don't see a connection...? Good question. Next question? :-) Okay, Nick, this is the twist (warped as it may be). For starters I'm guessing that you are somewhat younger than me. (Walter said once that D seems to attract a lot of the younger crowd; myself, I'm Walter's vintage.) I grew up watching a lot of Marx Brothers movies (and, btw, I'm continually surprised by just how many people, mostly younger, have never heard of the Marx Brothers, so just in case you are a member of said set, here's his bio: http://en.wikipedia.org/wiki/Groucho_Marx ). Groucho Marx was the absolute master of wisecracks; IMHO, few comedians have ever come close to matching his undeniable ability to make fast-talking wit out of the even the most subtle of connections. Alan Alda (in M*A*S*H) often played out Groucho, much to my delight. I also grew up with eyes glued to every Bugs Bunny cartoon that I could watch and every Looney Tune that accompanied the same. ( http://en.wikipedia.org/wiki/Looney_Tunes ) So now, having mentioned Marx, Alda and Bunny, this explains where my sense of humour comes from. Now the title of the Elliotte Rusty Harold article, http://cafe.elharo.com/programming/imagine-theres-no-null/ , that started this thread was a play on words from the title of the song "Imagine there’s no Heaven" by John Lennon, and acknowledged by ERH at the end of the article. (Also so happens that The Beatles along with Pink Floyd are some of my favourite bands.) ( Lyrics to Imagine written up here - http://www.slymarketing.com/2007/10/imagine-there-is-no-heaven/ ) So at the time I was thinking, "Hey, that's a good controversial story line to throw in for a bit of Fudd** on the D newsgroup" and, come to think of it (still saying to myself), it's probably a bit of a Looney Tune. Now having said all that, several possible interpretations are left open for the amusement of readers. ** Fudd. Acronym Definition FUDD Functional Description Document FUDD Fear Uncertainty Doubt and Disinformation Also Google on (exactly and typed below) define:fudd to get further connection with Looney Tunes Cheers -- Justin Johansson |
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote: > Scala has a powerful type system that allows to implement such things in a good enough way: > > http://www.michaelnygard.com/blog/2009/05/units_of_measure_in_scala.html So does D: =============================================== // by Oskar Linde Aug 2006 // This is just a quick hack to test // IFTI operators opMul and opDel import std.stdio; import std.math; import std.string; version = unicode; struct SiQuantity(T,int e1, int e2, int e3, int e4, int e5, int e6, int e7) { T value = 0; alias T ValueType; const exp1 = e1; const exp2 = e2; const exp3 = e3; const exp4 = e4; const exp5 = e5; const exp6 = e6; const exp7 = e7; static assert(SiQuantity.sizeof == ValueType.sizeof); template AddDimensions(int mul, U) { static assert(is(U.ValueType == ValueType) || is(U == ValueType), "incompatible value types"); static if (is(U == ValueType)) alias SiQuantity AddDimensions; else alias SiQuantity!(T,exp1+mul*U.exp1,exp2+mul*U.exp2, exp3+mul*U.exp3,exp4+mul*U.exp4, exp5+mul*U.exp5,exp6+mul*U.exp6, exp7+U.exp7) AddDimensions; } SiQuantity opAddAssign(SiQuantity rhs) { value += rhs.value; return this; } SiQuantity opSubAssign(SiQuantity rhs) { value -= rhs.value; return this; } const { SiQuantity opAdd(SiQuantity rhs) { SiQuantity ret; ret.value = value + rhs.value; return ret; } SiQuantity opSub(SiQuantity rhs) { SiQuantity ret; ret.value = value - rhs.value; return ret; } SiQuantity opNeg() { SiQuantity ret; ret.value = -value; return ret; } SiQuantity opPos() { typeof(return) ret; ret.value = value; return ret; } int opCmp(SiQuantity rhs) { if (value > rhs.value) return 1; if (value < rhs.value) return -1; return 0; // BUG: NaN } AddDimensions!(+1,Rhs) opMul(Rhs)(Rhs rhs) { AddDimensions!(+1,Rhs) ret; static if (is(Rhs : T)) ret.value = value * rhs; else ret.value = value * rhs.value; return ret; } AddDimensions!(-1,Rhs) opDiv(Rhs)(Rhs rhs) { AddDimensions!(-1,Rhs) ret; static if (is(Rhs : T)) ret.value = value / rhs; else ret.value = value / rhs.value; return ret; } SiQuantity opMul_r(T lhs) { SiQuantity ret; ret.value = lhs * value; return ret; } SiQuantity!(T,-e1,-e2,-e3,-e4,-e5,-e6,-e7) opDiv_r(T lhs) { SiQuantity!(T,-e1,-e2,-e3,-e4,-e5,-e6,-e7) ret; ret.value = lhs / value; return ret; } string toString() { string prefix = ""; T multiplier = 1; T value = this.value; string unit; static if (is(typeof(UnitName!(SiQuantity)))) unit = UnitName!(SiQuantity); else { value *= pow(cast(real)1e3,cast(uint)e2); // convert kg -> g // Take mass (e2) first to handle kg->g prefix issue if (e2 != 0) unit ~= format("·g^%s",e2); if (e1 != 0) unit ~= format("·m^%s",e1); if (e3 != 0) unit ~= format("·s^%s",e3); if (e4 != 0) unit ~= format("·A^%s",e4); if (e5 != 0) unit ~= format("·K^%s",e5); if (e6 != 0) unit ~= format("·mol^%s",e6); if (e7 != 0) unit ~= format("·cd^%s",e7); if (unit) unit = unit[2..$].split("^1").join(""); } if (value >= 1e24) { prefix = "Y"; multiplier = 1e24; } else if (value >= 1e21) { prefix = "Z"; multiplier = 1e21; } else if (value >= 1e18) { prefix = "E"; multiplier = 1e18; } else if (value >= 1e15) { prefix = "P"; multiplier = 1e15; } else if (value >= 1e12) { prefix = "T"; multiplier = 1e12; } else if (value >= 1e9) { prefix = "G"; multiplier = 1e9; } else if (value >= 1e6) { prefix = "M"; multiplier = 1e6; } else if (value >= 1e3) { prefix = "k"; multiplier = 1e3; } else if (value >= 1) { } else if (value >= 1e-3) { prefix = "m"; multiplier = 1e-3; } else if (value >= 1e-6) { version(unicode) prefix = "µ"; else prefix = "u"; multiplier = 1e-6; } else if (value >= 1e-9) { prefix = "n"; multiplier = 1e-9; } else if (value >= 1e-12) { prefix = "p"; multiplier = 1e-12; } else if (value >= 1e-15) { prefix = "f"; multiplier = 1e-15; } else if (value >= 1e-18) { prefix = "a"; multiplier = 1e-18; } else if (value >= 1e-21) { prefix = "z"; multiplier = 1e-21; } else if (value >= 1e-24) { prefix = "y"; multiplier = 1e-24; } return format("%.3s %s%s",value/multiplier, prefix, unit); } } } //length meter m //mass kilogram kg //time second s //electric current ampere A //thermodynamic temperature kelvin K //amount of substance mole mol //luminous intensity candela cd // Si base quantities alias SiQuantity!(real,1,0,0,0,0,0,0) Length; alias SiQuantity!(real,0,1,0,0,0,0,0) Mass; alias SiQuantity!(real,0,0,1,0,0,0,0) Time; alias SiQuantity!(real,0,0,0,1,0,0,0) Current; alias SiQuantity!(real,0,0,0,0,1,0,0) Temperature; alias SiQuantity!(real,0,0,0,0,0,1,0) AmountOfSubstance; alias SiQuantity!(real,0,0,0,0,0,0,1) Intensity; alias SiQuantity!(real,0,0,0,0,0,0,0) UnitLess; // Derived quantities alias typeof(Length*Length) Area; alias typeof(Length*Area) Volume; alias typeof(Mass/Volume) Density; alias typeof(Length*Mass/Time/Time) Force; alias typeof(1/Time) Frequency; alias typeof(Force/Area) Pressure; alias typeof(Force*Length) Energy; alias typeof(Energy/Time) Power; alias typeof(Time*Current) Charge; alias typeof(Power/Current) Voltage; alias typeof(Charge/Voltage) Capacitance; alias typeof(Voltage/Current) Resistance; alias typeof(1/Resistance) Conductance; alias typeof(Voltage*Time) MagneticFlux; alias typeof(MagneticFlux/Area) MagneticFluxDensity; alias typeof(MagneticFlux/Current) Inductance; alias typeof(Intensity*UnitLess) LuminousFlux; alias typeof(LuminousFlux/Area) Illuminance; // SI fundamental units const Length meter = {1}; const Mass kilogram = {1}; const Time second = {1}; const Current ampere = {1}; const Temperature kelvin = {1}; const AmountOfSubstance mole = {1}; const Intensity candela = {1}; // Derived units const Frequency hertz = {1}; const Force newton = {1}; const Pressure pascal = {1}; const Energy joule = {1}; const Power watt = {1}; const Charge coulomb = {1}; const Voltage volt = {1}; const Capacitance farad = {1}; const Resistance ohm = {1}; const Conductance siemens = {1}; const MagneticFlux weber = {1}; const MagneticFluxDensity tesla = {1}; const Inductance henry = {1}; const LuminousFlux lumen = {1}; const Illuminance lux = {1}; template UnitName(U:Frequency) { const UnitName = "Hz"; } template UnitName(U:Force) { const UnitName = "N"; } template UnitName(U:Pressure) { const UnitName = "Pa"; } template UnitName(U:Energy) { const UnitName = "J"; } template UnitName(U:Power) { const UnitName = "W"; } template UnitName(U:Charge) { const UnitName = "C"; } template UnitName(U:Voltage) { const UnitName = "V"; } template UnitName(U:Capacitance){ const UnitName = "F"; } version(unicode) { template UnitName(U:Resistance) { const UnitName = "?"; } } else { template UnitName(U:Resistance) { const UnitNAme = "ohm"; } } template UnitName(U:Conductance){ const UnitName = "S"; } template UnitName(U:MagneticFlux){ const UnitName = "Wb"; } template UnitName(U:MagneticFluxDensity) { const UnitName = "T"; } template UnitName(U:Inductance) { const UnitName = "H"; } void main() { Area a = 25 * meter * meter; Length l = 10 * 1e3 * meter; Volume vol = a * l; Mass m = 100 * kilogram; assert(!is(typeof(vol / m) == Density)); //Density density = vol / m; // dimension error -> syntax error Density density = m / vol; writefln("The volume is %s",vol.toString); writefln("The mass is %s",m.toString); writefln("The density is %s",density.toString); writef("\nElectrical example:\n\n"); Voltage v = 5 * volt; Resistance r = 1 * 1e3 * ohm; Current i = v/r; Time ti = 1 * second; Power w = v*v/r; Energy e = w * ti; // One wishes the .toString was unnecessary... writefln("A current of ",i.toString); writefln("through a voltage of ",v.toString); writefln("requires a resistance of ",r.toString); writefln("and produces ",w.toString," of heat."); writefln("Total energy used in ",ti.toString," is ",e.toString); writef("\nCapacitor time curve:\n\n"); Capacitance C = 0.47 * 1e-6 * farad; // Capacitance Voltage V0 = 5 * volt; // Starting voltage Resistance R = 4.7 * 1e3 * ohm; // Resistance for (Time t; t < 51 * 1e-3 * second; t += 1e-3 * second) { Voltage Vt = V0 * exp((-t / (R*C)).value); writefln("at %5s the voltage is %s",t.toString,Vt.toString); } } |
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rainer Deyke | Rainer Deyke wrote:
> Boost.Units (C++) checks units at compile time. There is no reason why
> D could not use the same approach.
Oskar's code I posted does it at compile time.
|
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote:
> Denis Koroskin:
>
>> I don't see any reason why if (someComplexNumber) { ... } should be a
> valid code, it hardly makes any sense for me.<
>
> In general I think adding a boolean-evaluation standard method to D can be positive and handy and not that bug-prone.
> But complex numbers are FP, so you usually test if they are close to zero (test of exactly zero can be useful to know if a value was not changed, etc). So I agree with you that for complex numbers such boolarn-eveluation method isn't very useful.
> Once D has such operator, it can be defined for library complex numbers too, but probably it will not be used often.
> It's useful if you want to write generic code, so if in a templated function you use if(x){... it will work with integers, double, complex values, etc, without special casing.
>
I'm not buying that. What kind of function would that be? I can't imagine a need for this.
|
October 05, 2009 Re: null references redux + Looney Tunes | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | downs:
> I'm not buying that. What kind of function would that be? I can't imagine a need for this.
I don't know, sorry.
But I'd like to have such method to define my collections as false when they are empty, this is really handy. And it may be useful to make nullable values false.
Bye,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation