www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A pass() identity range?

reply "bearophile" <bearophileHUGS lycos.com> writes:
I sometimes write code like:

auto data = File("data.txt")
             .byLine()
             .map!(r => r.strip().dup)()
             .filter!(r => !r.empty)()
             .array();


To help writing/improving/debugging such code maybe it's useful 
to create a pass() range in Phobos. It's like a "identity range" 
that just passes its inputs to its output, but also runs a given 
lambda to the items that pass through it (the lambda receives a 
const item, to avoid modifications of the data passing through 
the chain):


auto data = File("data.txt")
             .byLine()
             .pass(r => writeln("A: ", r))
             .map!(r => r.strip().dup)()
             .pass(r => writeln("B: ", r))
             .filter!(r => !r.empty)()
             .array();


This usage of pass() allows to introduce debug prints inside very 
long chains of such iterables, with no need to break them apart 
and assign the parts to temporary variables just to see what's 
going on in that chain.

But it's not hard to do it with a not pure map:

                 .map!((r){ writeln("B: ", r); return r; })()

Or even with an evil comma operator:

                 .map!(r => (writeln("B: ", r), r))()

So I don't know how much useful that pass() is.

Bye,
bearophile
Dec 22 2012
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 22 December 2012 at 08:55:35 UTC, bearophile wrote:
 I sometimes write code like:

 auto data = File("data.txt")
             .byLine()
             .map!(r => r.strip().dup)()
             .filter!(r => !r.empty)()
             .array();


 To help writing/improving/debugging such code maybe it's useful 
 to create a pass() range in Phobos. It's like a "identity 
 range" that just passes its inputs to its output, but also runs 
 a given lambda to the items that pass through it (the lambda 
 receives a const item, to avoid modifications of the data 
 passing through the chain):


 auto data = File("data.txt")
             .byLine()
             .pass(r => writeln("A: ", r))
             .map!(r => r.strip().dup)()
             .pass(r => writeln("B: ", r))
             .filter!(r => !r.empty)()
             .array();


 This usage of pass() allows to introduce debug prints inside 
 very long chains of such iterables, with no need to break them 
 apart and assign the parts to temporary variables just to see 
 what's going on in that chain.

 But it's not hard to do it with a not pure map:

                 .map!((r){ writeln("B: ", r); return r; })()

 Or even with an evil comma operator:

                 .map!(r => (writeln("B: ", r), r))()

 So I don't know how much useful that pass() is.

 Bye,
 bearophile
Bug reporting aside, it can be useful in the sense of *doing* something to each element, as opposed to "call a function and re-assign to original element". This would be especially true for say: Mutating functions that return void, or just plain calling member functions. I think it's a legit request. If anything, *map* could be re-implemented in terms of *call*.
Dec 22 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
See also:

http://tech.blinemedical.com/debugging-piped-sequences-f/

Bye,
bearophile
Dec 22 2012
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/22/2012 12:55 AM, bearophile wrote:

 To help writing/improving/debugging such code maybe it's useful to
 create a pass() range in Phobos.
I liked the idea yesterday but I thought that the name was a little off. How about a name like tap()? We tap into data as it's flowing through? Ali
Dec 22 2012
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 22 December 2012 at 21:21:21 UTC, Ali Çehreli wrote:
 On 12/22/2012 12:55 AM, bearophile wrote:

 To help writing/improving/debugging such code maybe it's
useful to
 create a pass() range in Phobos.
I liked the idea yesterday but I thought that the name was a little off.
Ditto.
 How about a name like tap()? We tap into data as it's flowing 
 through?
Niiice. I like it.
Dec 24 2012
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 24, 2012 at 02:35:29PM +0100, monarch_dodra wrote:
 On Saturday, 22 December 2012 at 21:21:21 UTC, Ali Çehreli wrote:
On 12/22/2012 12:55 AM, bearophile wrote:

 To help writing/improving/debugging such code maybe it's
 useful to create a pass() range in Phobos.
I liked the idea yesterday but I thought that the name was a little off.
Ditto.
How about a name like tap()? We tap into data as it's flowing
through?
Niiice. I like it.
This response is a year late ;-) but I thought tee() might be a better name. It has a precedent in the Unix tee command, which copies stdin into a file and also passes it along to stdout, quite similar to what is being done here (except that instead of a file it's a delegate/function). T -- To err is human; to forgive is not our policy. -- Samuel Adler
Jan 02 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
H. S. Teoh:

 This response is a year late ;-)
No problem.
 but I thought tee() might be a better name.
Python programmers have this "tee": http://docs.python.org/3/library/itertools.html#itertools.tee Bye, bearophile
Jan 02 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 02, 2013 at 07:19:31PM +0100, bearophile wrote:
 H. S. Teoh:
[...]
but I thought tee() might be a better name.
Python programmers have this "tee": http://docs.python.org/3/library/itertools.html#itertools.tee
[...] Hmm. But isn't that just the same as repeatedly calling .save with D's forward ranges? T -- If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
Jan 02 2013
parent reply D Lark <dlark example.com> writes:
On Wednesday, 2 January 2013 at 18:49:06 UTC, H. S. Teoh wrote:
 On Wed, Jan 02, 2013 at 07:19:31PM +0100, bearophile wrote:
 H. S. Teoh:
[...]
but I thought tee() might be a better name.
Python programmers have this "tee": http://docs.python.org/3/library/itertools.html#itertools.tee
[...] Hmm. But isn't that just the same as repeatedly calling .save with D's forward ranges? T
Not really, the python itertools.tee affords a sort of 'save' on *inputRanges* (all python iterators roughly model inputRanges, and nothing more) hence letting you simulate forwardRange: you just have to promise not to touch the underlying range directly after a call to itertools.tee and instead work with the resulting split ranges provided. I am a newcomer to D and I am looking for equivalent functionality in phobos (so far I have not found). Is there a way to convert inputRanges into forwardRanges, at the cost of extra memory? PS: thanks for your range calendar tutorial!
Dec 02 2021
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/2/21 6:35 AM, D Lark wrote:
 On Wednesday, 2 January 2013 at 18:49:06 UTC, H. S. Teoh wrote:
Note the date of post you are responding to. When the system says "hey, you are responding to a really old thread, let me fix that for you", you should click the button. Please don't reply to really old threads directly, instead you use a link (which is what the system will do for you automatically) -Steve
Dec 02 2021
next sibling parent D Lark <dlark example.com> writes:
On Thursday, 2 December 2021 at 13:22:55 UTC, Steven 
Schveighoffer wrote:
 On 12/2/21 6:35 AM, D Lark wrote:
 On Wednesday, 2 January 2013 at 18:49:06 UTC, H. S. Teoh wrote:
Note the date of post you are responding to. When the system says "hey, you are responding to a really old thread, let me fix that for you", you should click the button. Please don't reply to really old threads directly, instead you use a link (which is what the system will do for you automatically) -Steve
Well, if it should not be possible to reply then maybe disable it altogether? I think it is reasonable to respond to old threads if the context makes sense (as I believe it does in this case), and the system agrees with me.
Dec 02 2021
prev sibling parent D Lark <dlark example.com> writes:
On Thursday, 2 December 2021 at 13:22:55 UTC, Steven 
Schveighoffer wrote:
 On 12/2/21 6:35 AM, D Lark wrote:
 On Wednesday, 2 January 2013 at 18:49:06 UTC, H. S. Teoh wrote:
Note the date of post you are responding to. When the system says "hey, you are responding to a really old thread, let me fix that for you", you should click the button. Please don't reply to really old threads directly, instead you use a link (which is what the system will do for you automatically) -Steve
PS: I think this message is unhelpful, unnecessary (since you know that the system issues a warning) and is worse than ignoring the post altogether (if you otherwise had nothing to contribute).
Dec 02 2021
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 2 December 2021 at 11:35:53 UTC, D Lark wrote:
 I am a newcomer to D and I am looking for equivalent 
 functionality in phobos (so far I have not found).
The function you are looking for is [`std.range.tee`][1]. approximately one year after the post you replied to. This is why it's generally frowned upon to revive old threads: the information they contain is often out of date, and potentially misleading to anyone who reads them without looking carefully at the timestamps. [1]: https://phobos.dpldocs.info/std.range.tee.1.html [2]: https://github.com/dlang/phobos/pull/1965
Dec 02 2021
next sibling parent D Lark <dlark example.com> writes:
On Thursday, 2 December 2021 at 14:47:17 UTC, Paul Backus wrote:
 On Thursday, 2 December 2021 at 11:35:53 UTC, D Lark wrote:
 I am a newcomer to D and I am looking for equivalent 
 functionality in phobos (so far I have not found).
The function you are looking for is [`std.range.tee`][1]. approximately one year after the post you replied to. This is why it's generally frowned upon to revive old threads: the information they contain is often out of date, and potentially misleading to anyone who reads them without looking carefully at the timestamps. [1]: https://phobos.dpldocs.info/std.range.tee.1.html [2]: https://github.com/dlang/phobos/pull/1965
I had see the std.range.tee, but it does not appear to me to be the same as itertools.tee. I think with std.range.tee you get an input range and an output range out of an input range. With python's itertool.tee you get two or more input ranges from an input range (hence my claim earlier that it sort of simulates forwardRange.save). I felt the need to reply in-line to correct the misconception from that post that itertools.tee "basically works on forwardRanges". It does something very different, there is no "forwardRange" in python the only range concept (iterators) are equivalent to inputRanges and nothing more.
Dec 02 2021
prev sibling parent reply D Lark <dlark example.com> writes:
On Thursday, 2 December 2021 at 14:47:17 UTC, Paul Backus wrote:
 On Thursday, 2 December 2021 at 11:35:53 UTC, D Lark wrote:
 I am a newcomer to D and I am looking for equivalent 
 functionality in phobos (so far I have not found).
The function you are looking for is [`std.range.tee`][1]. approximately one year after the post you replied to. This is why it's generally frowned upon to revive old threads: the information they contain is often out of date, and potentially misleading to anyone who reads them without looking carefully at the timestamps. [1]: https://phobos.dpldocs.info/std.range.tee.1.html [2]: https://github.com/dlang/phobos/pull/1965
I had see the std.range.tee, but it does not appear to me to be the same as itertools.tee. I think with std.range.tee you get an input range and an output range out of an input range. With python's itertool.tee you get two or more input ranges from an input range (hence my claim earlier that it sort of simulates forwardRange.save). I felt the need to reply in-line to correct the misconception from that post that itertools.tee "basically works on forwardRanges". It does something very different, there is no "forwardRange" in python the only range concept (iterators) are equivalent to inputRanges and nothing more.
Dec 02 2021
parent reply D Lark <dlark example.com> writes:
On Thursday, 2 December 2021 at 14:53:31 UTC, D Lark wrote:
 On Thursday, 2 December 2021 at 14:47:17 UTC, Paul Backus wrote:
 This is why it's generally frowned upon to revive old threads: 
 the information they contain is often out of date, and 
 potentially misleading to anyone who reads them without 
 looking carefully at the timestamps.

 [1]: https://phobos.dpldocs.info/std.range.tee.1.html
 [2]: https://github.com/dlang/phobos/pull/1965
I had see the std.range.tee, but it does not appear to me to be the same as itertools.tee. I think with std.range.tee you get an input range and an output range out of an input range. With python's itertool.tee you get two or more input ranges from an input range (hence my claim earlier that it sort of simulates forwardRange.save).
Even in the present day, it seems there still exists a misconception. **Beyond the name there is not much similarity between the two, so I think my question is still valid**. Because it does not seem like that from the tone of responses I have gotten: I did my due diligence, I believe, before posting my original reply to the old question. I had looked at the docs and also searched the forum. There is no need for the patronizing tone you have taken.
Dec 02 2021
parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 2 December 2021 at 15:03:47 UTC, D Lark wrote:

 Because it does not seem like that from the tone of responses I 
 have gotten: I did my due diligence, I believe, before posting 
 my original reply to the old question. I had looked at the docs 
 and also searched the forum. There is no need for the 
 patronizing tone you have taken.
No one has been patronizing to you. They were just explaining the informal custom in these forums. Please don't take it the wrong way. The forum software is a web interface to a newsgroup server. The software could be enhanced to prevent posting to old threads, but there's never been a need to (and people would still be able to post through the newsgroup server anyway). It's a fairly common convention across the internet (and has been for years) that reviving old threads is frowned upon (the term often used is "necroposting"). Normally, the warning provided is enough. So let's leave this thread to Rest in Peace. And next time you attempt to post an old thread here, please allow the forum software to do it's thing when it warns you. Thanks!
Dec 02 2021