## digitalmars.D - More Phobos testing

• bearophile (63/63) Jan 26 2011 Now and then I try to use the std.algorithm/std.range parts of Phobos2 t...
• spir (22/37) Jan 26 2011 Why? zip is imo clearly a "sequential" function; belongs where it is.
bearophile <bearophileHUGS lycos.com> writes:
```Now and then I try to use the std.algorithm/std.range parts of Phobos2 to see
how they are going and developing.

Here I have found Python3 code to compute the Pascal triangle:
http://code.activestate.com/recipes/577542-pascals-triangle/

-------------------

Code adapted for Python2:

def pascal_triangle(n):
r = [[1]]
for _ in xrange(n - 1):
r.append(map(sum, zip([0]+r[-1], r[-1]+[0])))
return r

print pascal_triangle(5)

-------------------

A similar algorithm translated to D2:

import std.array, std.stdio, std.algorithm, std.range;

auto pascalTriangle(int n) {
auto r = [[1]];
foreach (_; 0 .. n-1)
r ~= array(map!q{a[0] + a[1]}(zip([0]~r[\$-1], r[\$-1]~[0])));
return r;
}

void main() {
writeln(pascalTriangle(5));
}

-------------------

Some notes on the D2 version:

1) In Python I am used to think of higher order functions like map, filter, and
zip as similar things. But in Phobos zip is in std.range while map is in
std.algorithm. I think this different placement is bad.

-------------------

2) The Python version performs a sum() on tuples. But in D2 tuples, even ones
that have an uniform type, aren't iterable, this doesn't work:

import std.stdio, std.typecons;
void main() {
auto t1 = tuple(1, 2, 3, 4);
foreach (x; t1)
writeln(x);
}

Once tuples of uniform type are iterable, and sum()
(http://d.puremagic.com/issues/show_bug.cgi?id=4725 ) is implemented, the
middle line of code becomes simpler to read:

r ~= array(map!sum(zip([0]~r[\$-1], r[\$-1]~[0])));

I am aware that this works, but this is static foreach, so this is something
different:
foreach (x; t.tupleof)

This is closer to what I'm asking for, but it's not good enough yet:
foreach (x; [t.tupleof])

I have added an enhancement request on this:
http://d.puremagic.com/issues/show_bug.cgi?id=5489

-------------------

3) I like API orthogonality because it allows you to write code like this, that
creates a linked list instead of an array out of the lazy map iterable:

But in my Python3 and D2 code I write often enough:
array(map!(...)(...))

So I may suggest an amap() the returns an array, it helps remove some
parenthesys clutter:
r ~= amap!q{a[0] + a[1]}(zip([0]~r[\$-1], r[\$-1]~[0]));

r ~= amap!sum(zip([0] ~ r[\$-1], r[\$-1] ~ [0]));

-------------------

4) In the Python2 version if I print using the pretty print module:

from pprint import pprint
pprint(pascal_triangle(5), width=20)

The triangle gets visualized like this:

[[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1]]

A function like pprint() will be useful in std.string of Phobos2 too, to give a
more readable printing. It's useful to print 2D arrays, arrays of dicts, etc,
in a more readable way.

Bye,
bearophile
```
Jan 26 2011
spir <denis.spir gmail.com> writes:
```On 01/26/2011 01:56 PM, bearophile wrote:
Now and then I try to use the std.algorithm/std.range parts of Phobos2 to see
how they are going and developing.

Here I have found Python3 code to compute the Pascal triangle:
[...]
Some notes on the D2 version:

1) In Python I am used to think of higher order functions like map, filter,
and zip as similar things. But in Phobos zip is in std.range while map is in
std.algorithm. I think this different placement is bad.

Why? zip is imo clearly a "sequential" function; belongs where it is.
An alternative may be to have a more type-oriented organisation of Phobos:
then, all algorithms oerating on ranges (many) would be placed in std.range.

4) In the Python2 version if I print using the pretty print module:

from pprint import pprint
pprint(pascal_triangle(5), width=20)

The triangle gets visualized like this:

[[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1]]

A function like pprint() will be useful in std.string of Phobos2 too, to give
a more readable printing. It's useful to print 2D arrays, arrays of dicts, etc,
in a more readable way.

Agreed. I very often write and use tree-like output.
As an alternative, I would even like a recursive treeView func/method on all
aggregate types (arrays, AAs, strucs & classes). Producing eg:

aPoint:
tag: "foo"
color:
r: 11
g: 22
b: 33
position:
x: 1
y: 2
with optional separators ',' & delimitors () [] {}.

Denis
--
_________________
vita es estrany
spir.wikidot.com
```
Jan 26 2011