Summary: Unpacking from dynamic array, lazy ranges
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD

--- Comment #0 from 2011-07-26 06:52:19 PDT ---
This is a spinoff of Issue 6365  (AutoTupleDeclaration).

Issue 6365 is about syntax sugar to unpack tuples, but unpacking dynamic arrays
or lazy ranges too is handy and commonly useful, because in D most arrays are
not fixed-sized, and many functions return a lazy range, like lazy splitting,
regular expression matches, etc.

The 'lengths don't match' exception is already present in D and I think it's
acceptable (when the lengths are statically known there is no need to test
lengths at run time, so this exception throwing is not present, so it's nothrow

int[] array = [1, 2, 3];
int[2] a2 = array[];


Some usage examples, assign from a dynamic array, in D2:

import std.string;
void main() {
    auto s = " foo bar ";
    auto ss = s.split();
    auto sa = ss[0];
    auto sb = ss[1];

In Python2.6:

>>> sa, sb = " foo bar ".split()
>>> sa
>>> sb


import std.string;
void main() {
    auto s = " foo bar ";
    auto (sa, sb) = s.split();


>From lazy range, D2:

import std.algorithm, std.conv, std.string;
void main() {
    string s = " 15 27";

    // splitter doesn't work yet for this
    // (here it doesn't strip the leading space)
    //auto xy = map!(to!int)(splitter(s));

    auto xy = map!(to!int)(split(s));
    int x = xy[0];
    int y = xy[1];

In Python:

>>> x, y = map(int, " 15 27".split())
>>> x
>>> y
>>> from itertools import imap
>>> x, y = imap(int, " 15 27".split())
>>> x
>>> y


import std.algorithm, std.conv, std.string;
void main() {
    string s = " 15 27";
    (int x, int y) = map!(to!int)(splitter(s));


>From a lazy range, another example. See:

D2 code:

import std.stdio, std.regex, std.string, std.conv, std.range;
int[] rangeExpand(string txt) {
    int[] result;
    foreach (r; std.string.split(txt, ",")) {
        auto m = array(match(r, r"^(-?\d+)(-?(-?\d+))?$").captures);
        if (m[2].empty)
            result ~= to!int(m[1]);
            result ~= array(iota(to!int(m[1]), to!int(m[3])+1));
    return result;


import re
def rangeexpand(txt):
    lst = []
    for rng in txt.split(','):
        start,end = re.match('^(-?\d+)(?:-(-?\d+))?$', rng).groups()
        if end:
    return lst

Proposed (just the important line), from dynamic array:

auto (start,end) = array(match(r, r"^(-?\d+)(-?(-?\d+))?$").captures);

Or better, from the range of regex captures:

auto (start,end) = match(r, r"^(-?\d+)(-?(-?\d+))?$").captures;

Similar unpacking from Python list (that is a dynamic array) or from lazy
iterable is quite common in scripting-style Python code.

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to