digitalmars.D.bugs - [Issue 9086] New: std.typecons.appendIfNotNull() or a better idea
- d-bugmail puremagic.com (76/76) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9086
- d-bugmail puremagic.com (7/7) Dec 18 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9086
http://d.puremagic.com/issues/show_bug.cgi?id=9086 Summary: std.typecons.appendIfNotNull() or a better idea Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc --- Comment #0 from bearophile_hugs eml.cc 2012-11-27 18:21:31 PST --- A problem with std.typecons.Nullable is that the D type system is not powerful enough to see this is correct code: import std.typecons; void main() nothrow { alias Nothing = Nullable!int; Nothing[] items; foreach (i; 0 .. 10) items ~= (i % 2) ? Nothing(i) : Nothing(); int[] result; foreach (x; items) if (!x.isNull) result ~= x.get; // Error: x.get is not nothrow } Another problem is that "x.get" verifies the enforcement even in the "then" clause, this is wasted computation, because x was tested already. One common enough use case for Nullable is to create arrays of Nullables and then filter out the null values. Currently code like this can't be nothrow: items.filter!(x => !x.isNull)().map!(x => x.get)() So I have created a little function named appendIfNotNull() that is nothrow: import std.typecons; void appendIfNotNull(T)(ref T[] items, Nullable!T x) pure nothrow { try { if (!x.isNull) items ~= x.get; } catch (Exception e) // enforce() exception. assert(0); } // Demo code -------------------------- import std.stdio, std.algorithm; alias Nothing = Nullable!int; Nothing[] foo(int n) nothrow { typeof(return) result; foreach (i; n .. n + 6) result ~= (i % 2) ? Nothing(i) : Nothing(); return result; } int[] bar() nothrow { typeof(return) numbers; foreach (i; 0 .. 3) foreach (x; foo(i * 10)) numbers.appendIfNotNull(x); return numbers; } void main() { writeln(bar()); foo(1).filter!(x => !x.isNull)().map!(x => x.get)().writeln(); } appendIfNotNull() is nothrow, but it wastes efficiency. So here is a simpler and more efficient implementation for the std.typecons module (because _isNull and _value fields are private): void appendIfNotNull(T)(ref T[] items, Nullable!T x) nothrow { if (!x._isNull) items ~= x._value; } Improvements for appendIfNotNull: - items instead of a T[] should be a range that supports appending. - x should be allowed to be one of both types of Nullables. appendIfNotNull() is not a very generic function, something better can be invented, usable in more cases. More general ideas are welcome. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9086 --- Comment #1 from bearophile_hugs eml.cc 2012-12-18 14:11:54 PST --- See also here for some usage patterns of the Scala Option type: http://blog.tmorris.net/scalaoption-cheat-sheet/ -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 18 2012