top | item 44944828

(no title)

aquafox | 6 months ago

The consensus here seems to be that Python is missing a pipe operator. That was one of the things I quickly learned to appreciate when transitioning from Mathematica to R. It makes writing data science code, where the data are transformed by a series of different steps, so much more readable and intuitive.

I know that Python is used for many more things than just data science, so I'd love to hear if in these other contexts, a pipe would also make sense. Just trying to understand why the pipe hasn't made it into Python already.

discuss

order

atq2119|6 months ago

The next step after pipe operators would be reverse assignment statements to capture the results.

I find myself increasingly frustrated at seeing code like 'let foo = many lines of code'. Let me write something like 'many lines of code =: foo'.

teo_zero|6 months ago

> reverse assignment statements to capture the results

Interesting idea! However, I'm not sure I would prefer

"Mix water, flour [...] and finally you'll get a pie"

to

"To make a pie: mix water, flour [...]"

redochre|6 months ago

R does have a right assign operator, namely ->

It's use is discourages in most style guides. I do not use it in scripts, but I use it heavily in console/terminal workflows where I'm experimenting.

df |> filter() |> summarise() -> x

x |> mutate() -> y

plot(y)

levocardia|6 months ago

The pipe operator in R (really, tidyverse R, which might as well be its own language) is one of its "killer apps" for me. Working with data is so, so pleasant and easy. I remember a textbook that showed two ways of "coding" a cookie recipe:

bake(divide(add(knead(mix(flour, water, sugar, butter)),eggs),12),450,12)

versus

mix(flour, water, sugar, butter) %>% knead() %>% add(eggs) %>% divide(12) %>% bake(temp=450, minutes=12)

So much easier!

yccs27|6 months ago

You'd never write that ugly one-liner. Just write the recipe imperatively:

    dough = mix(flour, water, sugar, butter)
    dough.knead()
    dough = dough.add(eggs)
    cookies = dough.divide(12)
    cookies = bake(temp=450, minutes=12)
Might be more verbose, but definitely readable.

hagendaasalpine|6 months ago

pandas and polars both have pipe methods available on dataframes. you can method chain to the same effect. it's considered best practise in pandas as you're hopefully not mutating the initial df

nxpnsv|6 months ago

I don't know if

   result = (df
      .pipe(fun1, arg1=1)
      .pipe(fun2, arg2=2)
   )
is much less readable than

   result <- df |> 
      fun1(., arg1=1) |> 
      fun2(., arg2=2)
but I guess the R thing also works beyond dataframes which is pretty cool

itishappy|6 months ago

The pipe operator uses what comes before as the first argument of the function. This means in R it would be:

    result <- df
      |> fun1(arg1=1)
      |> fun2(arg2=2)
Python doesn't have a pipe operator, but if it did it would have similar syntax:

    result = df
      |> fun1(arg1=1)
      |> fun2(arg2=2)
In existing Python, this might look something like:

    result = pipe(df, [
      (fun1, 1),
      (fun2, 2)
    ])
(Implementing `pipe` would be fun, but I'll leave it as an exercise for the reader.)

Edit: Realized my last example won't work with named arguments like you've given. You'd need a function for that, which start looking awful similar to what you've written:

    result = pipe(df, [
      step(fun1, arg1=1),
      step(fun2, arg2=2)
    ])

mb7733|6 months ago

I haven't used R in forever, but is your `.` placeholder actually necessary? From my recollection of pipe operator the value being pipe piped is automatically as the first argument to the next function. That may have been a different implementation of a pipe operator though.

tekknik|6 months ago

It seem like creative use of the map function and some iterators would provide the same functionality as a pipe does