On 07/12/2020 11:18 a.m., peter dalgaard wrote:> Hmm,
>
> I feel a bit bad coming late to this, but I think I am beginning to side
with those who want "... |> head" to work. And yes, that has to
happen at the expense of |> head().
Just curious, how would you express head(df, 10)? Currently it is
df |> head(10)
Would I have to write it as
df |> function(d) head(d, 10)
> As I think it was Gabor points out, the current structure goes down a
nonstandard evaluation route, which may be difficult to explain and departs from
usual operator evaluation paradigms by being an odd mix of syntax and semantics.
R lets you do these sorts of thing, witness ggplot and tidyverse, but the
transparency of the language tends to suffer.
I wouldn't call it non-standard evaluation. There is no function
corresponding to |>, so there's no evaluation at all. It is more like
the way "x -> y" is parsed as "y <- x", or "if
(x) y" is transformed to
`if`(x, y).
Duncan Murdoch
> It would be neater if it was simply so that the class/type of the object on
the right hand side decided what should happen. So we could have a rule that we
could have an object, an expression, and possibly an unevaluated call on the
RHS. Or maybe a formula, I.e., we could hav
>
> ... |> head
>
> but not
>
> ... |> head()
>
> because head() does not evaluate to anything useful. Instead, we could have
some of these
>
> ... |> quote(head())
> ... |> expression(head())
> ... |> ~ head()
> ... |> \(_) head(_)
>
> possibly also using a placeholder mechanism for the three first ones. I
kind of like the idea that the ~ could be equivalent to \(_).
>
> (And yes, I am kicking myself a bit for not using ~ in the NSE arguments in
subset() and transform())
>
> -pd
>
>> On 7 Dec 2020, at 16:20 , Deepayan Sarkar <deepayan.sarkar at
gmail.com> wrote:
>>
>> On Mon, Dec 7, 2020 at 6:53 PM Gabor Grothendieck
>> <ggrothendieck at gmail.com> wrote:
>>>
>>> On Mon, Dec 7, 2020 at 5:41 AM Duncan Murdoch <murdoch.duncan at
gmail.com> wrote:
>>>> I agree it's all about call expressions, but they
aren't all being
>>>> treated equally:
>>>>
>>>> x |> f(...)
>>>>
>>>> expands to f(x, ...), while
>>>>
>>>> x |> `function`(...)
>>>>
>>>> expands to `function`(...)(x). This is an exception to the
rule for
>>>> other calls, but I think it's a justified one.
>>>
>>> This admitted inconsistency is justified by what? No argument has
been
>>> presented. The justification seems to be implicitly driven by
implementation
>>> concerns at the expense of usability and language consistency.
>>
>> Sorry if I have missed something, but is your consistency argument
>> basically that if
>>
>> foo <- function(x) x + 1
>>
>> then
>>
>> x |> foo
>> x |> function(x) x + 1
>>
>> should both work the same? Suppose it did. Would you then be OK if
>>
>> x |> foo()
>>
>> no longer worked as it does now, and produced foo()(x) instead of
foo(x)?
>>
>> If you are not OK with that and want to retain the current behaviour,
>> what would you want to happen with the following?
>>
>> bar <- function(x) function(n) rnorm(n, mean = x)
>>
>> 10 |> bar(runif(1))() # works 'as expected' ~
bar(runif(1))(10)
>> 10 |> bar(runif(1)) # currently bar(10, runif(1))
>>
>> both of which you probably want. But then
>>
>> baz <- bar(runif(1))
>> 10 |> baz
>>
>> (not currently allowed) will not be the same as what you would want
from
>>
>> 10 |> bar(runif(1))
>>
>> which leads to a different kind of inconsistency, doesn't it?
>>
>> -Deepayan
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>