From kev|nu@hey @end|ng |rom gm@||@com  Mon Dec  7 20:02:22 2020
From: kev|nu@hey @end|ng |rom gm@||@com (Kevin Ushey)
Date: Mon, 7 Dec 2020 11:02:22 -0800
Subject: [Rd] New pipe operator
In-Reply-To: <CAP01uRkphV1txi+59LXi3uQO-4RCL+gAt9gbOpDCLXOV-484Yw@mail.gmail.com>
References: <e55c2093-0bb5-5f9b-5521-0ca8bdf35953@gmail.com>
 <CALyqOb8c1hHOSaMV+fqXTwpeOsP--KJ_t-oeqMYYafVXeNpqZg@mail.gmail.com>
 <7586e034-e287-0970-6480-f82d747b5445@gmail.com>
 <CADfFDC7bT58_+52uvmpHuMMQRNbbmqV3_7t_fc4sgJ_Esw=xag@mail.gmail.com>
 <CAJmOi+PO_8XDC23=rT=pQ76ENL=gx2V-41ax2fHSVs87xURcEA@mail.gmail.com>
 <CAP01uRkkd3jOjvaS9JgKYCD1KA83HfzCd+MQSv_2aYJPgcOmSQ@mail.gmail.com>
 <CAP01uRkPcbCBRGwAzKM=W19Ohh-zDGwZH8gM7=A-sK2rRaQxaQ@mail.gmail.com>
 <CAD4oTHFBY4rBhiRsJUkA6jwD2YWaxPMz2OZDOqSvHfv6A7DZPg@mail.gmail.com>
 <CAP01uRmTYna1nM+ugELHrCqLjfWuWwHSfE4cvqoaq2537sHpAw@mail.gmail.com>
 <CAD4oTHHFWkiirncPRWngY+_k9HcB=8zo7VdXAONXQoXdNhKzDA@mail.gmail.com>
 <7e28d84a-f6d0-1e18-c131-163650e7cd75@gmail.com>
 <CAP01uRkCpLQ0uwJgFdTFTNG+80C+F1hn=TnQqRS2Z-nFuU5MmA@mail.gmail.com>
 <CADfFDC74ostfecs5mhOznSXEedGBA=_78SiNTfysz5B8JU=YUQ@mail.gmail.com>
 <F7AF463A-B9A1-4AEB-9EE3-1062B6AD3CFF@gmail.com>
 <7e1eb5e9-4ee7-4a80-ad7b-58ed67c830df@gmail.com>
 <91C38945-B1BA-4E7A-B2E0-79790A894240@gmail.com>
 <7f8cf17d-d5fa-0cd1-7760-7157ef1fe7bf@gmail.com>
 <CAP01uRkphV1txi+59LXi3uQO-4RCL+gAt9gbOpDCLXOV-484Yw@mail.gmail.com>
Message-ID: <CAJXgQP1Jpo3BNVGvEf6ctKu9Bv3SV-QFJa5BRByOO-yjYE2XFA@mail.gmail.com>

IMHO the use of anonymous functions is a very clean solution to the
placeholder problem, and the shorthand lambda syntax makes it much
more ergonomic to use. Pipe implementations that crawl the RHS for
usages of `.` are going to be more expensive than the alternatives. It
is nice that the `|>` operator is effectively the same as a regular R
function call, and given the identical semantics could then also be
reasoned about the same way regular R function calls are.

I also agree usages of the `.` placeholder can make the code more
challenging to read, since understanding the behavior of a piped
expression then requires scouring the RHS for usages of `.`, which can
be challenging in dense code. Piping to an anonymous function makes
the intent clear to the reader: the programmer is likely piping to an
anonymous function because they care where the argument is used in the
call, and so the reader of code should be aware of that.

Best,
Kevin



On Mon, Dec 7, 2020 at 10:35 AM Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
>
> On Mon, Dec 7, 2020 at 12:54 PM Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
> > An advantage of the current implementation is that it's simple and easy
> > to understand.  Once you make it a user-modifiable binary operator,
> > things will go kind of nuts.
> >
> > For example, I doubt if there are many users of magrittr's pipe who
> > really understand its subtleties, e.g. the example in Luke's paper where
> > 1 %>% c(., 2) gives c(1,2), but 1 %>% c(c(.), 2) gives c(1, 1, 2). (And
> > I could add 1 %>% c(c(.), 2, .) and  1 %>% c(c(.), 2, . + 2)  to
> > continue the fun.)
>
> The rule is not so complicated.  Automatic insertion is done unless
> you use dot in the top level function or if you surround it with
> {...}.  It really makes sense since if you use gsub(pattern,
> replacement, .) then surely you don't want automatic insertion and if
> you surround it with { ... } then you are explicitly telling it not
> to.
>
> Assuming the existence of placeholders a possible simplification would
> be to NOT do automatic insertion if { ... } is used and to use it
> otherwise although personally having used it for some time I find the
> existing rule in magrittr generally does what you want.
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] New pipe operator
Kevin Ushey