digitalmars.D.learn - std.algorithm.map with side-effects
- Joseph Rushton Wakeling via Digitalmars-d-learn (28/28) Dec 05 2014 Here's a little experiment I was trying out earlier today in order to tr...
- bearophile (10/14) Dec 05 2014 Lazy higher order functions like map/filter should be used only
- Joseph Rushton Wakeling via Digitalmars-d-learn (8/16) Dec 05 2014 Ah, I see. That function would only be called on consumption of the res...
- bearophile (7/9) Dec 05 2014 I think two different persons implemented something like "each".
- evenex (12/12) Dec 05 2014 map won't actually compute anything until you start asking for
Here's a little experiment I was trying out earlier today in order to try and convert foreach-style code to using UFCS of ranges: ////////////////////////////////////////////// import std.algorithm, std.range, std.stdio; void main() { size_t s = 0; void essify(size_t n) { writeln("n = ", n); ++s; } auto filteredRange = iota(0, 10).filter!(a => (a % 2)); filteredRange.map!(a => essify(a)); writeln(s); foreach (n; filteredRange) { essify(n); } writeln(s); } ////////////////////////////////////////////// I'd assumed the two uses of filteredRange would produce equivalent results, but in fact the transformation using map does nothing -- the writeln statement inside the essify() function never gets triggered, suggesting the function body is never executed. Can anyone advise why, and whether there's a nice range iteration option to ensure that this function gets called using each element of the filteredRange?
Dec 05 2014
Joseph Rushton Wakeling:Can anyone advise why,map is lazy, like most other ranges.and whether there's a nice range iteration option to ensure that this function gets called using each element of the filteredRange?Lazy higher order functions like map/filter should be used only with pure functions. There are bugs/troubles in using them on impure code. There was a proposal for a "each" function to terminate a range chain with something effectful, but I think it has gone nowhere. This means you have to use a foreach on a range. Bye, bearophile
Dec 05 2014
On 06/12/14 00:58, bearophile via Digitalmars-d-learn wrote:Joseph Rushton Wakeling:Ah, I see. That function would only be called on consumption of the results of the map.Can anyone advise why,map is lazy, like most other ranges.Lazy higher order functions like map/filter should be used only with pure functions. There are bugs/troubles in using them on impure code.Yes, I did wonder about that. I'll post up the actual code tomorrow -- I was having some fun playing with one of the metrics in my Dgraph library and trying to see to what extent I could simplify it (reading-wise) with a range-based approach.There was a proposal for a "each" function to terminate a range chain with something effectful, but I think it has gone nowhere. This means you have to use a foreach on a range.Yes, I remember you requesting that. Were there ever any PRs, or was it just spec?
Dec 05 2014
Joseph Rushton Wakeling:Yes, I remember you requesting that. Were there ever any PRs, or was it just spec?I think two different persons implemented something like "each". "iter": http://msdn.microsoft.com/en-us/library/ee340469.aspx Bye, bearophile
Dec 05 2014
map won't actually compute anything until you start asking for individual elements with front, back, or opIndex. Personally I like to use something like ref transform (alias action, R, T...)(ref R range, T addl_args) { range = action (range, addl_args); return range; } to do mutation in the middle of UFCS chains. Its more flexible and more obvious than an impure map. range.callchain.array.transform!(x => x.map!whatever).filter.etc
Dec 05 2014