<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Oct 9, 2018 at 9:34 PM Eric Wieser <<a href="mailto:wieser.eric%2Bnumpy@gmail.com">wieser.eric+numpy@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="m_-6778046194751305365markdown-here-wrapper" style="font-size:1em;font-family:Helvetica,arial,freesans,clean,sans-serif;color:rgb(34,34,34);background-color:rgb(255,255,255);border:none;line-height:1.2"><p style="margin:1em 0px">One thing that worries me here - in python, <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">range(...)</code> in essence generates a lazy <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">list</code> - so I’d expect <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">ndrange</code> to generate a lazy <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">ndarray</code>. In practice, that means it would be a duck-type defining an <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">__array__</code> method to evaluate it, and only implement methods already present in numpy.</p>
<p style="margin:1em 0px">It’s not clear to me what the datatype of such an array-like would be. Candidates I can think of are:</p>
<ol style="padding-left:2em;margin:1em 0px">
<li style="margin:1em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">[('i0', intp), ('i1', intp), ...]</code>, but this makes tuple coercion a little awkward</li></ol></div></div></blockquote><div>I think this would be the appropriate choice. What about it makes tuple coercion awkward? If you use this as the dtype, you both set and get element as tuples.<br></div><div><br></div><div>In particular, I would say that ndrange() should be a lazy equivalent to the following explicit constructor:</div><div><br></div><div><div style="line-height:19px"><div style=""><div style="line-height:19px"><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px"><span style="color:rgb(0,0,255)">def</span> ndrange(shape):</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px">    dtype = [(<span style="color:rgb(163,21,21)">'i'</span> + <span style="color:rgb(0,0,255)">str</span>(i), np.intp) <span style="color:rgb(0,0,255)">for</span> i <span style="color:rgb(0,0,255)">in</span> <span style="color:rgb(0,0,255)">range</span>(<span style="color:rgb(0,0,255)">len</span>(shape))]</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px">    array = np.empty(shape, dtype)</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px">    <span style="color:rgb(0,0,255)">for</span> indices <span style="color:rgb(0,0,255)">in</span> np.ndindex(*shape):</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px">        array[indices] = indices</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px">    <span style="color:rgb(0,0,255)">return</span> array</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px"><br></div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254)">>>> ndrange((2,)</div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254)"><span style="color:rgb(33,33,33);font-family:monospace;font-size:14px;background-color:rgb(255,255,255)">array([(0,), (1,)], dtype=[('i0', '<i8')])</span><br></div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254)"><span style="color:rgb(33,33,33);font-family:monospace;font-size:14px;background-color:rgb(255,255,255)"><br></span></div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254)"><span style="color:rgb(33,33,33);font-family:monospace;font-size:14px;background-color:rgb(255,255,255)">>>> ndrange((2, 3))</span></div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px"><span style="color:rgb(33,33,33);font-family:monospace;background-color:rgb(255,255,255)">array([[(0, 0), (0, 1), (0, 2)],
       [(1, 0), (1, 1), (1, 2)]], dtype=[('i0', '<i8'), ('i1', '<i8')])</span><br></div><div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px"><span style="color:rgb(33,33,33);font-family:monospace;background-color:rgb(255,255,255)"><br></span></div><div style="line-height:19px">The one deviation in behavior would be that ndrange() iterates over flattened elements rather than the first axes.</div><div style="line-height:19px"><br></div>It is indeed a little awkward to have field names, but given that NumPy creates those automatically when you supply a dtype like 'i8,i8' this is probably a reasonable choice.<div style="font-family:"Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";white-space:pre;background-color:rgb(255,255,254);font-size:14px"><span style="color:rgb(33,33,33);font-family:monospace;background-color:rgb(255,255,255)"><br></span></div></div></div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="m_-6778046194751305365markdown-here-wrapper" style="font-size:1em;font-family:Helvetica,arial,freesans,clean,sans-serif;color:rgb(34,34,34);background-color:rgb(255,255,255);border:none;line-height:1.2"><ol style="padding-left:2em;margin:1em 0px">
<li style="margin:1em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">(intp, (N,))</code> - which collapses into a <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">shape + (3,)</code> array</li>
<li style="margin:1em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">object_</code>.</li>
<li style="margin:1em 0px">Some new <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">np.tuple_</code> dtype, a heterogenous tuple, which is like the structured <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:nowrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline">np.void</code> but without field names. I’m not sure how vectorized element indexing would be spelt though.</li>
</ol>
<p style="margin:1em 0px">Eric</p>
<div title="MDH:T25lIHRoaW5nIHRoYXQgd29ycmllcyBtZSBoZXJlIC0gaW4gcHl0aG9uLCBgcmFuZ2UoLi4uKWAg
aW4gZXNzZW5jZSBnZW5lcmF0ZXMgYSBsYXp5IGBsaXN0YCAtIHNvIEknZCBleHBlY3QgYG5kcmFu
Z2VgIHRvIGdlbmVyYXRlIGEgbGF6eSBgbmRhcnJheWAuIEluIHByYWN0aWNlLCB0aGF0IG1lYW5z
IGl0IHdvdWxkIGJlIGEgZHVjay10eXBlIGRlZmluaW5nIGFuIGBfX2FycmF5X19gIG1ldGhvZCB0
byBldmFsdWF0ZSBpdCwgYW5kIG9ubHkgaW1wbGVtZW50IG1ldGhvZHMgYWxyZWFkeSBwcmVzZW50
IGluIG51bXB5LjxkaXY+PGJyPjwvZGl2PjxkaXY+SXQncyBub3QgY2xlYXIgdG8gbWUgd2hhdCB0
aGUgZGF0YXR5cGUgb2Ygc3VjaCBhbiBhcnJheS1saWtlIHdvdWxkIGJlLiBDYW5kaWRhdGVzIEkg
Y2FuIHRoaW5rIG9mIGFyZTo8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjEuIGBbKCdpMCcsIGlu
dHApLCAoJ2kxJywgaW50cCksIC4uLl1gLCBidXQgdGhpcyBtYWtlcyB0dXBsZSBjb2VyY2lvbiBh
IGxpdHRsZSBhd2t3YXJkPC9kaXY+PGRpdj4yLiBgKGludHAsIChOLCkpYCAtIHdoaWNoIGNvbGxh
cHNlcyBpbnRvIGEgYHNoYXBlJm5ic3A7KyAoMywpYCBhcnJheTwvZGl2PjxkaXY+My4gYG9iamVj
dF9gLjwvZGl2PjxkaXY+NC4gU29tZSBuZXcgYG5wLnR1cGxlX2AgZHR5cGUsIGEgaGV0ZXJvZ2Vu
b3VzIHR1cGxlLCB3aGljaCBpcyBsaWtlIHRoZSBzdHJ1Y3R1cmVkIGBucC52b2lkYCBidXQgd2l0
aG91dCBmaWVsZCBuYW1lcy4gSSdtIG5vdCBzdXJlIGhvdyB2ZWN0b3JpemVkIGVsZW1lbnQgaW5k
ZXhpbmcgd291bGQgYmUgc3BlbHQgdGhvdWdoLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+RXJp
YzwvZGl2Pg==" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div>
</blockquote></div></div>