From g@bembecker @end|ng |rom gm@||@com  Tue Dec  8 00:30:27 2020
From: g@bembecker @end|ng |rom gm@||@com (Gabriel Becker)
Date: Mon, 7 Dec 2020 15:30:27 -0800
Subject: [Rd] New pipe operator
In-Reply-To: <8c468025-3d9f-1ace-6203-e58834f7dfdc@kogentum.hu>
References: <e55c2093-0bb5-5f9b-5521-0ca8bdf35953@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>
 <CAJXgQP1Jpo3BNVGvEf6ctKu9Bv3SV-QFJa5BRByOO-yjYE2XFA@mail.gmail.com>
 <CAD4oTHE6oWztx7BB+jp_EFs28jDNpUoznOS9jehz_P7iuUexRA@mail.gmail.com>
 <8c468025-3d9f-1ace-6203-e58834f7dfdc@kogentum.hu>
Message-ID: <CAD4oTHGdBAog9QweCFrCz8TQcSe0ZBSM2JNCBufpx19mR0QvLQ@mail.gmail.com>

Hi Denes,

On Mon, Dec 7, 2020 at 2:52 PM D?nes T?th <toth.denes at kogentum.hu> wrote:

>
>
> This gave me the idea that naming the arguments can be used to skip the
> placeholder issue:
>
> "funny" |> sub(pattern = "f", replacement = "b")
>
> Of course this breaks if the maintainer changes the order of the
> function arguments (which is not a nice practice but happens).
>

This is true, but only if you are specifying all arguments that appear
before the one you want explicitly. In practice that may often be true? But
I don't really have a strong intuition about that as a non-pipe user. It
would require zero changes to the pipe by the R-core team though, so in
that sense it could be a solution in the cases it does work. It does make
the code subtler to read though, which is a pretty big downside, imho.


> An option could be to allow for missing argument in the first position,
> but this might add further undesired complexity, so probably not worth
> the effort:
>
> "funny" |> sub(x =, "f", "b")
>
> So basically the parsing rule would be:
>
> LHS |> RHS(arg=, ...)     -> RHS(arg=LHS, ...)
>

The problem here is that its ambiguous, because myfun(x, y=, z) is
technically syntactically valid, so this would make code that parses now
into valid syntax change its meaning, and would prevent existing,
syntactically valid (Though hopefully quite rare) code in the pipe context.

~G


>
> >
> > (Assuming we could get the parser to handle |^bla^> correctly)
> >
> > For argument position issues would be sufficient. For more complicated
> > expressions, e.g., those that would use the placeholder multiple times or
> > inside compound expressions, requiring anonymous functions seems quite
> > reasonable to me. And honestly, while I kind of like it, I'm not sure if
> > that "stuffed pipe" expression (assuming we could get the parser to
> capture
> > it correctly) reads to me as nicer than the following, anyway.
> >
> > LHS |> \(x) RHS(arg1 = 5, pipearg = x, arg3 = 7)
> >
> > ~G
> >
> >>
> >> 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
> >>
> >> ______________________________________________
> >> R-devel at r-project.org mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-devel
> >>
> >
> >       [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>

	[[alternative HTML version deleted]]



[Rd] New pipe operator
Gabriel Becker