[Issue 9086] New: std.typecons.appendIfNotNull() or a better idea
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Nov 27 18:21:33 PST 2012
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 at puremagic.com
ReportedBy: bearophile_hugs at eml.cc
--- Comment #0 from bearophile_hugs at 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: -------
More information about the Digitalmars-d-bugs
mailing list