www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18374] New: Add range functions to Nullable

https://issues.dlang.org/show_bug.cgi?id=18374

          Issue ID: 18374
           Summary: Add range functions to Nullable
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: the.mail.of.mi2 gmail.com

I suggest to add the range functions to the Nullable, so that it can be treated
as either empty or one element long range.

Treating Nullable as a range will by very handy in my opinion - it could be
mapped, filtered, joined and processed with all the other algorithms without
checking the presence explicitely. Let's say that I am regularly receiving from
somewhere (for example via user input or network) structures with optional data
stored in Nullable. I want to process the optional data in some way if they are
present.

Similar solution is present in Scala, where functions such as map, filter etc.
can be applied to options in the same way as to lists.

Structure and range:
--------------------------------------------------
struct Data
{
    string requiredData;
    Nullable!string optionalData;
}

InputRange!Data toProcess;

void process(string optionalData) { /*...*/ }

/* Current solution: */
toProcess.map!(x => x.optionalData)
    .filter!(x => x.isNull)
    .each!process;

/* Nullable as a range solution: */
toProcess.each!(x => x.optionalData.each!process);
--------------------------------------------------

In fact every time I do "if(nullable.isNull) nullable.get.whatever()",
i could do "nullable.each!whatever" or similar. I think there are more
significant gains possible, but I thought only of this simple example now.

It could be discussed, but I believe that Nullable could be both a
bidirectional and random access range.

What could range methods do:

front/back:
Asserts not nullified and calls get() (the same as other ranges throw
AssertError if front(0 is called on empty range).

popFront/popBack:
Removing the front element and moving to the next one actually is equal to
nullifying in this case.

empty:
Aliased do isNull.

save:
Defined only if the underlying type is copiable. Returns the new nullable with
a copy of underlying element or empty nullable if this one was null.

length:
Return 0 or 1 depending on if the range is null.

opIndex:
Throws if isNull or index > 0. Otherwise returns an underlying element.

--
Feb 05 2018