www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Upgrading a codebase from 2.065 to 2.066

reply "Brian Schott" <briancschott gmail.com> writes:
I recently upgraded EMSI's internal data processing library[1] so 
that it will be compatible with the upcoming 2.066 release and 
thought it might be useful to share my experience.

1. There was a redundant  property attribute on the (unreleased) 
std.allocator. Really easy to fix.

2. std.metastrings was removed. I deleted the import statement 
and everything worked fine. Apparently the import was unused.

3. The compiler more correctly checked mutable/immutable with 
type tuples and caught a bug in our code. The fix for this was 
also very easy.

4. isNaN is now a template. This broke some templated code that 
would (depending on template instantiations) rely on uint being 
converted to real. The new isFloatingPoint template constraint 
kept this from compiling. I ended up placing a static if around 
our call to isNaN to work around this. Maybe it would be useful 
to add a template specialization for isNaN that checks isNumeric 
&& !isFloatingPoint and always returns false.

5. A change to object.d broke a line of code that used "[]" as 
the "defaultValue" argument to the get() function for AAs. 
Casting "[]" to the expected type worked around this issue.

Once these compile issues were resolved all of the unit tests ran 
without errors.

The only time-consuming part of the process was dealing with a 
linker bug that only seems to be present on Ubuntu machines 
running ld 2.24. I'll file an issue for this soon.

[1] http://dconf.org/2014/talks/crapuchettes.html
Jul 02 2014
next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Jul 02, 2014 at 10:34:35PM +0000, Brian Schott via Digitalmars-d wrote:
 I recently upgraded EMSI's internal data processing library[1] so that
 it will be compatible with the upcoming 2.066 release and thought it
 might be useful to share my experience.

 2. std.metastrings was removed. I deleted the import statement and
 everything worked fine. Apparently the import was unused.

std.metastring has been deprecated for a while now. Any code that depends on it should use std.format instead (the latter has been made CTFE-able). T -- Life is too short to run proprietary software. -- Bdale Garbee
Jul 02 2014
prev sibling next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Wednesday, 2 July 2014 at 22:34:36 UTC, Brian Schott wrote:
 4. isNaN is now a template.

It should really be a normal function with float/double/real overloads instead of a template. That being said, OTOH an uint argument would still lead to an ambiguity error. David
Jul 02 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Brian Schott:

 I recently upgraded EMSI's internal data processing library[1] 
 so that it will be compatible with the upcoming 2.066 release 
 and thought it might be useful to share my experience.

I suggest to update large programs more frequently than adjacent compiler versions, because there is too much changed stuff.
 5. A change to object.d broke a line of code that used "[]" as 
 the "defaultValue" argument to the get() function for AAs. 
 Casting "[]" to the expected type worked around this issue.

Indeed this doesn't compile, but perhaps it should: void main() { int[][int] aa; int[] r = aa.get(0, []); } A current workaround (but it's not DRY, because 'aa' is repeated twice): void main() { import std.traits: ValueType; int[][int] aa; int[] r = aa.get(0, ValueType!(typeof(aa)).init); } Bye, bearophile
Jul 02 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Jul 02, 2014 at 10:50:21PM +0000, bearophile via Digitalmars-d wrote:
 Brian Schott:
 
I recently upgraded EMSI's internal data processing library[1] so
that it will be compatible with the upcoming 2.066 release and
thought it might be useful to share my experience.

I suggest to update large programs more frequently than adjacent compiler versions, because there is too much changed stuff.

This may not be practical if your codebase is production, and relies on the compiler being (relatively) stable. Sometimes things break in a major way on git HEAD in between releases and get fixed later, so you might end up spending unnecessary effort to make your code compile every few git revisions.
5. A change to object.d broke a line of code that used "[]" as the
"defaultValue" argument to the get() function for AAs. Casting "[]"
to the expected type worked around this issue.

Indeed this doesn't compile, but perhaps it should: void main() { int[][int] aa; int[] r = aa.get(0, []); } A current workaround (but it's not DRY, because 'aa' is repeated twice): void main() { import std.traits: ValueType; int[][int] aa; int[] r = aa.get(0, ValueType!(typeof(aa)).init);

You *could* just write this, y'know: int[] r = aa.get(0, aa[0].init); :) Still not completely DRY, but less typing. You don't need to refer to the type of the element in order to get its .init value. T -- Right now I'm having amnesia and deja vu at the same time. I think I've forgotten this before.
Jul 02 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
H. S. Teoh:

 This may not be practical if your codebase is production, and 
 relies on
 the compiler being (relatively) stable. Sometimes things break 
 in a
 major way on git HEAD in between releases and get fixed later, 
 so you
 might end up spending unnecessary effort to make your code 
 compile every
 few git revisions.

I stopped updating my code only at compiler releases because fixing hundreds of things at the same time (of many different kinds) was too much hard for me.
 You don't need to refer to
 the type of the element in order to get its .init value.

Right. So, is it possible and a good idea to fix AA.get so the natural code "get(0, [])" works? Bye, bearophile
Jul 02 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Jul 02, 2014 at 11:20:04PM +0000, bearophile via Digitalmars-d wrote:
 H. S. Teoh:

You don't need to refer to the type of the element in order to get
its .init value.

Right. So, is it possible and a good idea to fix AA.get so the natural code "get(0, [])" works?

I thought that used to work? Why doesn't it work anymore? Is this a regression? T -- Computers shouldn't beep through the keyhole.
Jul 02 2014
prev sibling next sibling parent "Brian Schott" <briancschott gmail.com> writes:
On Wednesday, 2 July 2014 at 23:35:29 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 I thought that used to work? Why doesn't it work anymore? Is 
 this a
 regression?


 T

It used to work, so it is a regression. I've filed it here: https://issues.dlang.org/show_bug.cgi?id=13026
Jul 02 2014
prev sibling next sibling parent "Brian Schott" <briancschott gmail.com> writes:
On Wednesday, 2 July 2014 at 22:34:36 UTC, Brian Schott wrote:
 5. A change to object.d broke a line of code that used "[]" as 
 the "defaultValue" argument to the get() function for AAs. 
 Casting "[]" to the expected type worked around this issue.

This has been fixed in the compiler. A recent change to druntime caused our code to fail to compile in a different way: Error: AA key type YearQuarter should have 'size_t toHash() const nothrow safe' if opEquals defined This turned out to be another case of bad code no longer compiling, and it was very easy to fix.
Jul 07 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 23:41, David Nadlinger via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Wednesday, 2 July 2014 at 22:34:36 UTC, Brian Schott wrote:
 4. isNaN is now a template.

It should really be a normal function with float/double/real overloads instead of a template. That being said, OTOH an uint argument would still lead to an ambiguity error.

I had thought about this initially when I wrote it, but then I came to the conclusion that calling this on anything but an float would be wrong. Iain
Jul 07 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 23:34, Brian Schott via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 4. isNaN is now a template. This broke some templated code that would
 (depending on template instantiations) rely on uint being converted to real.
 The new isFloatingPoint template constraint kept this from compiling. I
 ended up placing a static if around our call to isNaN to work around this.
 Maybe it would be useful to add a template specialization for isNaN that
 checks isNumeric && !isFloatingPoint and always returns false.

I would ask why are you passing integers to isNaN. And I would also give you some heads up on other stuff... https://github.com/D-Programming-Language/phobos/pull/2305
Jul 07 2014
prev sibling next sibling parent "Brian Schott" <briancschott gmail.com> writes:
On Tuesday, 8 July 2014 at 06:02:51 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 I would ask why are you passing integers to isNaN.

We passed T to isNaN, and sometimes T was uint.
Jul 07 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 8 July 2014 07:08, Brian Schott via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Tuesday, 8 July 2014 at 06:02:51 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 I would ask why are you passing integers to isNaN.

We passed T to isNaN, and sometimes T was uint.

Happy now? :o) https://github.com/D-Programming-Language/phobos/pull/2311
Jul 07 2014
prev sibling parent "Dominikus Dittes Scherkl" writes:
On Tuesday, 8 July 2014 at 06:08:58 UTC, Brian Schott wrote:
 On Tuesday, 8 July 2014 at 06:02:51 UTC, Iain Buclaw via 
 Digitalmars-d wrote:
 I would ask why are you passing integers to isNaN.

We passed T to isNaN, and sometimes T was uint.

I would like to have a NaN in any type and be able to call isNaN for any (numeric) type. In fact I work with the following: /// add a property to numeric types that can be used as return value if a result is out of bounds template property T invalid(T) primitive if(isNumeric!T) { static if(isFloat!T) return T.init; else static if(isSigned!T) return T.min; else // unsigned return T.max; } /// returns the save (not invalid) minimum value for the given type template property T smin(T) primitive if(isNumeric!T) { static if(isIntegral!T && isSigned!T) return T.min+1; else return T.min; } /// returns the save (not invalid) maximum value for the given type template property T smax(T) primitive if(isNumeric!T) { static if(isUnsigned!T) return T.max-1u; else return T.max; } /// take any NaN as invalid floatingpoint value, /// T.max as invalid value of unsigned types and /// T.min as invalid value of signed types bool isInvalid(T)(const(T) x) primitive if(isNumeric!T) { static if(isFloat!T) return isNaN(x); else static if(isSigned!T) return x == T.min; else // unsigned return x == T.max; } (btw: primitive is my internal shorthand for "pure safe nogc nothrow") because it allows to define save functions like e.g. a save downcast: /// returns T.invalid if x is outside the target type range T limit(T, U)(const(U) x) primitive if(isNumeric!T && isNumeric!U) { static if(Unqual!T == Unqual!U) // nop return x; else static if(isFloat!T) return cast(T)x; // let D handle this internally else static if(isFloat!U) return (isNaN(x) || x <= cast(U)T.min-1.0f || x >= cast(U)T.max+1.0f) ? T.invalid : cast(T)x; else static if(isSigned!T) { static if(T.sizeof > U.sizeof) // nothing to limit return cast(T)x; else static if(isUnsigned!U) // limit one direction return (x > T.max) ? T.invalid : cast(T)x; else // limit both directions return (x < T.min || x > T.max) ? T.invalid : cast(T)x; } else // unsigned result { static if(isSigned!U) // prohibit negative values if(x < 0) return T.invalid; static if(T.sizeof >= U.sizeof) // no further limit return cast(T)x; else // prohibit also big positive values return (x > T.max) ? T.invalid : cast(T)x; } }
Jul 08 2014