digitalmars.D - Ad hoc ranges
- Tomek =?ISO-8859-2?Q?Sowi=F1ski?= (22/22) Jan 20 2011 Doing my own deeds, I often found myself in need of writing up a range j...
- bearophile (4/5) Jan 20 2011 I am not sure, but I think Andrei has deprecated the "lazy" attribute.
- Tomek =?ISO-8859-2?Q?Sowi=F1ski?= (5/6) Jan 20 2011 Yes, but AFAIR in favor of implicit conversions of expressions to parame...
- Jonathan M Davis (13/18) Jan 20 2011 In general or on a specific function? I'm pretty sure that lazy isn't go...
- Jonathan M Davis (10/44) Jan 20 2011 What types of stuff do you need ad-hoc ranges for? What's the use case? ...
- Tomek =?ISO-8859-2?Q?Sowi=F1ski?= (20/33) Jan 21 2011 tly
- Andrei Alexandrescu (5/22) Jan 21 2011 How about a singleton range - a range with exactly one element. It could...
- Tomek =?ISO-8859-2?Q?Sowi=F1ski?= (24/38) Jan 21 2011 libraries ported to D but preserving
- Andrei Alexandrescu (5/24) Jan 21 2011 I think the challenge here is to figure out where to store the state.
- Tomek =?ISO-8859-2?Q?Sowi=F1ski?= (19/53) Jan 22 2011 or libraries ported to D but preserving
Doing my own deeds, I often found myself in need of writing up a range just to e.g. feed it into an algorithm. Problem is, defining even the simplest range -- one-pass forward -- is verbose enough to render this (correct) approach unprofitable. This is how I went about the problem: auto range(T, Whatever)(lazy bool _empty, lazy Whatever _popFront, lazy T _front) { struct AdHocRange { property bool empty() { return _empty(); } void popFront() { _popFront(); } property T front() { return _front(); } } return AdHocRange(); } --- example --- try { ... } catch(Throwable t) { auto r = range(t is null, t = t.next, t); // process exception chain... } I don't know a terser way to get a full-fledged range. It comes at a cost, though. Lazy parameters are just sugar over delegates, so it's not exactly Usain Bolt**... And you can't return it because by bug or by design lazy parameters (unlike vanilla delegates) don't work like closures. Still, even with the overhead and limitations the idiom is remarkably useful, especially in face of range-unfriendly libraries from outside D realm. Enjoy. -- Tomek ** Of course, there exists a somewhat more verbose compile-time variant of the idiom I presented.
Jan 20 2011
Tomek Sowiński:auto range(T, Whatever)(lazy bool _empty, lazy Whatever _popFront, lazy T _front) {I am not sure, but I think Andrei has deprecated the "lazy" attribute. Bye, bearophile
Jan 20 2011
bearophile napisa=B3:I am not sure, but I think Andrei has deprecated the "lazy" attribute.Yes, but AFAIR in favor of implicit conversions of expressions to parameter= less delegates, which strengthens my little idiom. --=20 Tomek
Jan 20 2011
On Thursday, January 20, 2011 16:19:54 bearophile wrote:Tomek Sowi=F1ski:Tauto range(T, Whatever)(lazy bool _empty, lazy Whatever _popFront, lazy=In general or on a specific function? I'm pretty sure that lazy isn't going= =20 anywhere as far as the language goes. It's used on enforce, and Andrei hasn= 't=20 wanted to make enforce take a non-lazy attribute. Also, for cases like the = unit=20 testing functions that I've been working on to get into Phobos, the loss of= lazy=20 would be pretty devastating. You could still do the, but it would be much=20 uglier. =2D Jonathan M Davis_front) {=20 I am not sure, but I think Andrei has deprecated the "lazy" attribute.
Jan 20 2011
On Thursday, January 20, 2011 16:12:58 Tomek Sowi=C5=84ski wrote:Doing my own deeds, I often found myself in need of writing up a range ju=stto e.g. feed it into an algorithm. Problem is, defining even the simplest range -- one-pass forward -- is verbose enough to render this (correct) approach unprofitable. =20 This is how I went about the problem: =20 auto range(T, Whatever)(lazy bool _empty, lazy Whatever _popFront, lazy T _front) { struct AdHocRange { property bool empty() { return _empty(); } void popFront() { _popFront(); } property T front() { return _front(); } } return AdHocRange(); } =20 --- example --- =20 try { ... } catch(Throwable t) { auto r =3D range(t is null, t =3D t.next, t); =20 // process exception chain... } =20 I don't know a terser way to get a full-fledged range. It comes at a cost, though. Lazy parameters are just sugar over delegates, so it's not exactly Usain Bolt**... And you can't return it because by bug or by design lazy parameters (unlike vanilla delegates) don't work like closures. Still, even with the overhead and limitations the idiom is remarkably useful, especially in face of range-unfriendly libraries from outside D realm. =20 Enjoy.What types of stuff do you need ad-hoc ranges for? What's the use case? I'v= e=20 never actually needed such a thing. I'm curious. If it's really something t= hat's=20 likely to be generally useful, then a function similar to what you're sugge= sting=20 probably should be added to std.range. =2D Jonathan M Davis
Jan 20 2011
Jonathan M Davis napisa=B3:st,I don't know a terser way to get a full-fledged range. It comes at a co=tlythough. Lazy parameters are just sugar over delegates, so it's not exac='ve=20Usain Bolt**... And you can't return it because by bug or by design lazy parameters (unlike vanilla delegates) don't work like closures. Still, even with the overhead and limitations the idiom is remarkably useful, especially in face of range-unfriendly libraries from outside D realm. =20 Enjoy. =20=20 What types of stuff do you need ad-hoc ranges for? What's the use case? I=never actually needed such a thing. I'm curious. If it's really something=that's=20likely to be generally useful, then a function similar to what you're sug=gesting=20probably should be added to std.range.Like I said, anything that doesn't bother to expose range-interfaced iterat= ors and is not performance critical is considered a target for ad hoc range= s. Working with non-D libraries, or libraries ported to D but preserving mo= ther-language idioms. Tasks like traversing a tree of GUI widgets, or busin= ess specific objects where defining proper ranges rarely happens and is use= -case driven in practice. I expect they could be of some use in unittesting= as mock input. Vaguely related: educational -- ad hoc ranges read almost l= ike a for loop so the learning curve for ranges in general is eased off. Adding them to Phobos is an interesting idea. We need to evaluate their wor= th, though. Everybody: if you could write up a one-liner like range(empty, popFront, fr= ont), what would you use it for? --=20 Tomek
Jan 21 2011
On 1/21/11 3:15 PM, Tomek Sowiński wrote:Jonathan M Davis napisał:How about a singleton range - a range with exactly one element. It could be done with repeat(x, 1) but let's try it with your function as a warm-up exercise. AndreiLike I said, anything that doesn't bother to expose range-interfaced iterators and is not performance critical is considered a target for ad hoc ranges. Working with non-D libraries, or libraries ported to D but preserving mother-language idioms. Tasks like traversing a tree of GUI widgets, or business specific objects where defining proper ranges rarely happens and is use-case driven in practice. I expect they could be of some use in unittesting as mock input. Vaguely related: educational -- ad hoc ranges read almost like a for loop so the learning curve for ranges in general is eased off. Adding them to Phobos is an interesting idea. We need to evaluate their worth, though. Everybody: if you could write up a one-liner like range(empty, popFront, front), what would you use it for?I don't know a terser way to get a full-fledged range. It comes at a cost, though. Lazy parameters are just sugar over delegates, so it's not exactly Usain Bolt**... And you can't return it because by bug or by design lazy parameters (unlike vanilla delegates) don't work like closures. Still, even with the overhead and limitations the idiom is remarkably useful, especially in face of range-unfriendly libraries from outside D realm. Enjoy.What types of stuff do you need ad-hoc ranges for? What's the use case? I've never actually needed such a thing. I'm curious. If it's really something that's likely to be generally useful, then a function similar to what you're suggesting probably should be added to std.range.
Jan 21 2011
Andrei Alexandrescu napisa=B3:erators and is not performance critical isLike I said, anything that doesn't bother to expose range-interfaced it=libraries ported to D but preservingconsidered a target for ad hoc ranges. Working with non-D libraries, or=business specific objects where definingmother-language idioms. Tasks like traversing a tree of GUI widgets, or=ct they could be of some use in unittestingproper ranges rarely happens and is use-case driven in practice. I expe=t like a for loop so the learning curve foras mock input. Vaguely related: educational -- ad hoc ranges read almos=worth, though.ranges in general is eased off. Adding them to Phobos is an interesting idea. We need to evaluate their=, front), what would you use it for? =20Everybody: if you could write up a one-liner like range(empty, popFront==20 How about a singleton range - a range with exactly one element. It could==20be done with repeat(x, 1) but let's try it with your function as a=20 warm-up exercise.If x is nullable, range(x, x=3Dnull, x); it destroys x, though. Otherwise t= he state must be held separately on the stack. bool empty; auto r =3D range(empty, empty=3Dtrue, x); So repeat(x, 1) wins this one. I think such nuggets can better be expressed= as a degenerate case of existing facilities. I envision ad hoc ranges at p= laces where no iteration is defined and a one-off range struct doesn't pay.= Like database-backed entities which don't conform to any clear-cut data st= ructure, but if you squint you see it's sort of a tree, and you may just be= able to e.g. walk through children recursively fetching only active ones f= rom DB, traverse columns of interest, and dump their content to a grid comp= onent which takes an arbitrary range of values. And all this can be wrapped= in std.parallelism to overlap DB round trips. --=20 Tomek
Jan 21 2011
On 1/21/11 7:35 PM, Tomek Sowiński wrote:Andrei Alexandrescu napisał:I think the challenge here is to figure out where to store the state. The idiom makes it difficult for the delegates to communicate state to one another. AndreiIf x is nullable, range(x, x=null, x); it destroys x, though. Otherwise the state must be held separately on the stack. bool empty; auto r = range(empty, empty=true, x); So repeat(x, 1) wins this one. I think such nuggets can better be expressed as a degenerate case of existing facilities. I envision ad hoc ranges at places where no iteration is defined and a one-off range struct doesn't pay. Like database-backed entities which don't conform to any clear-cut data structure, but if you squint you see it's sort of a tree, and you may just be able to e.g. walk through children recursively fetching only active ones from DB, traverse columns of interest, and dump their content to a grid component which takes an arbitrary range of values. And all this can be wrapped in std.parallelism to overlap DB round trips.Like I said, anything that doesn't bother to expose range-interfaced iterators and is not performance critical is considered a target for ad hoc ranges. Working with non-D libraries, or libraries ported to D but preserving mother-language idioms. Tasks like traversing a tree of GUI widgets, or business specific objects where defining proper ranges rarely happens and is use-case driven in practice. I expect they could be of some use in unittesting as mock input. Vaguely related: educational -- ad hoc ranges read almost like a for loop so the learning curve for ranges in general is eased off. Adding them to Phobos is an interesting idea. We need to evaluate their worth, though. Everybody: if you could write up a one-liner like range(empty, popFront, front), what would you use it for?How about a singleton range - a range with exactly one element. It could be done with repeat(x, 1) but let's try it with your function as a warm-up exercise.
Jan 21 2011
Andrei Alexandrescu napisa=B3:On 1/21/11 7:35 PM, Tomek Sowi=F1ski wrote:iterators and is not performance critical isAndrei Alexandrescu napisa=B3:Like I said, anything that doesn't bother to expose range-interfaced =or libraries ported to D but preservingconsidered a target for ad hoc ranges. Working with non-D libraries, =or business specific objects where definingmother-language idioms. Tasks like traversing a tree of GUI widgets, =pect they could be of some use in unittestingproper ranges rarely happens and is use-case driven in practice. I ex=ost like a for loop so the learning curve foras mock input. Vaguely related: educational -- ad hoc ranges read alm=ir worth, though.ranges in general is eased off. Adding them to Phobos is an interesting idea. We need to evaluate the=nt, front), what would you use it for?Everybody: if you could write up a one-liner like range(empty, popFro=ldHow about a singleton range - a range with exactly one element. It cou=se the state must be held separately on thebe done with repeat(x, 1) but let's try it with your function as a warm-up exercise.If x is nullable, range(x, x=3Dnull, x); it destroys x, though. Otherwi=ssed as a degenerate case of existingstack. bool empty; auto r =3D range(empty, empty=3Dtrue, x); So repeat(x, 1) wins this one. I think such nuggets can better be expre=fined and a one-off range struct doesn'tfacilities. I envision ad hoc ranges at places where no iteration is de=data structure, but if you squint you seepay. Like database-backed entities which don't conform to any clear-cut=dren recursively fetching only active onesit's sort of a tree, and you may just be able to e.g. walk through chil=component which takes an arbitrary range offrom DB, traverse columns of interest, and dump their content to a grid=und trips.values. And all this can be wrapped in std.parallelism to overlap DB ro==20 I think the challenge here is to figure out where to store the state.=20 The idiom makes it difficult for the delegates to communicate state to=20 one another.On the stack, for loops do it for years. --=20 Tomek
Jan 22 2011