13 ms·
R adds native pipe and lambda syntax
- burlesona 6y agoThat backslash syntax is pretty funky, but then again all of R is a little funky. Very nice addition to the language though!
- f6v 6y agoAFAIK the same as in Julia.
- kkoncevicius 6y agoI think that symbol is used as an approximation of "lambda" character (λ) on a standard US keyboard.
- johannes_ne 6y agoHere is a tweet thread explaining this: https://twitter.com/rabaath/status/1335226691304775681?s=20 https://twitter.com/rabaath/status/1335226691304775681?s=20
- desine 6y agoIt is, and it's not the first language to use it as such. But for many programmers it always triggers the 'escape' alarm in the mind, and it will always cause slight discomfort seeing it used in the raw.
- boogies 6y agoIMO it should be like Fennel and just support `lambda` and `λ`. The latter is not even that hard to type, in virtually any free (libre) OS you can just $ echo ' <Multi_key> <Y> <Y> : "Λ" # GREEK CAPITAL LETTER LAMDA <Multi_key> <y> <y> : "λ" # GREEK CAPITAL LETTER LAMDA ' >> ~/.XCompose If you’re limited by a nonfree OS you should be able to patch the problem with free duct tape like Karabiner or AutoHotKey. And in vim you can just <C-K>*l in insert mode (which can be done with option-l on macOS if you `inoremap ¬ <C-K>*l` https://apple.stackexchange.com/questions/230422/type-lambda-%ce%bb-on-a-mac#comment556351_230439 https://apple.stackexchange.com/questions/230422/type-lambda...).
- michaelhoffman 6y agoIn Windows, WinCompose lets you set up compose keys like that, although the default ⋄yy goes to ʎ.
- dash2 6y agoI don’t think R yet has native Unicode support on every platform.
- LoathsLights 6y agoNow imagine doing that same thing for every system you're programming on. And then imagine having to do it for a million different symbols. I'm sure as hell glad you're not in charge of any of this.
- thotsBgone 6y agoA better solution is just to use the word 'lambda', and let your text editor render it as a lambda symbol if you want (my emacs does this).
- BigJono 6y agoNo, that's a shithouse solution. Everyone that doesn't have a fancy IDE now has 6-8 extra useless characters for something that should be syntax.
- thotsBgone 6y agoHow is it different than the word "function"?
- BigJono 6y agoIt's not, that's why people use arrow syntax in languages like Javascript for short in-lined functions.
- boogies 6y ago
- improbable22 6y agoJulia's lambdas look like `x -> f(x,2)`, with no backslashes. The pipe `x |> f` is indeed the same.
- bachmeier 6y agoBorrowed from Haskell. (Which of course does not make it unfunky.) https://wiki.haskell.org/Anonymous_function https://wiki.haskell.org/Anonymous_function
- lottin 6y agoIn R all functions are anonymous functions. Functions are created anonymously and then (usually, but not always) assigned to a variable using the assignment operator.
- joelthelion 6y agoI must say I don't really see the point, given that function() does the same thing, with only a few more characters.
- deleted 6y ago[deleted]
- smabie 6y agothat's a lot more characters. useless, unnecessary characters I might add.
- f6v 6y agoBetter late than never, but dplyr solved the pipe problem long time ago.
- melling 6y agoi’m new to R but I really prefer the |> to %>% Much better to use the OCaml, F# syntax. Think Julia uses it too.
- data_ders 6y agoAgreed but |> instead of %>% is certainly easier to type! I’ll be interested in trying it out at least
- deleted 6y ago[deleted]
- kkoncevicius 6y agoThere is a big difference between what is allowed from within a package and what is possible in native implementation. As an example - currently this pipe operator seems to be implemented at the parser level. The parser simply takes the pipe expression and translates it into standard nested function call f(g(x)). Which means - there will be almost no cost in speed (%>% was notoriously slow). In addition the user will get the usual error stack in case something within this pipe fails.
- wenc 6y agoI'm sure some of us who are out of the loop might be wondering: what about the magrittr pipe operator (%>%) that we all know and love? Luke Tierney explains the move from %>% to a native pipe |> here [1]. The native pipe aims to be more efficient as well as addresses issues with the magrittr pipe like complex stack traces. Turns out the |> syntax is also used in Julia, Javascript and F#. The lambda syntax (\(x) -> x + 1) is similar to Haskell's (\x -> x + 1). [1] https://www.youtube.com/watch?v=X_eDHNVceCU&feature=youtu.be&t=3099 https://www.youtube.com/watch?v=X_eDHNVceCU&feature=youtu.be...
- dugmartin 6y ago|> is also used in Elixir where it is implemented as a macro so it’s a little less flexible since it can’t be assigned as a value.
- submeta 6y agoBeautiful. - Elixir has this as well. Love it. - In Mathematica you'd have to write `data // f // g` to denote `g(f(data))`. ## Edit Corrected a notation.
- crooked-v 6y ago> Turns out the |> syntax is also used in Julia, Javascript and F#. Note that for JS it's still just a proposal and has been stuck in an indeterminable bikeshedding phase for most of this year.
- clircle 6y agoI think I'm going to appreciate the native pipes, it will likely improve the readability of my data.table chains.
- dm319 6y agoDo you use the Magrittr pipes? Works well with data.table for me.
- clircle 6y agoI've seen them used with data.table, but I don't use them myself. Reason being that I don't want to load a lib just to make my chains look a bit better. I usually have chains short enough that it's okay doing DT[..][..][..]
- bluenose69 6y agoThese will both come in pretty handy, although the first is just a formalization of something that's already available in packages, the lambda syntax will clean up code a fair bit, and make realtime analysis easier to type.
- wodenokoto 6y agoKind of odd they didn't decide to go with the magrittr syntax, which is in common use and heavily promoted in dplyr / tidyverse. I wonder if RStudio will change its `ctrl` + `shift` + m shortcut from the magrittr ( %>% ) style pipes to these new pipes ( |> )
- grayclhn 6y agoI'm pretty happy that they didn't, because silently replacing one operation with a similar operation that inevitably has different bugs and different ways of handling edge cases would be pretty frustrating. Letting both live side-by-side as people transition would be my preference.
- johnmyleswhite 6y agoIsn't the reason that magrittr was able to use that syntax that it already existed, so your proposal is a breaking change?
- wodenokoto 6y agoI thought %% was some sort of macro expansions and that is how magrittr creates pipes. But browsing through the magrittr github repo, it looks like they just define %>% and the other pipes as functions [1]. I don't actually know the relation between magrittr and the RStudio shortcut, but I've always assumed a shortcut for typing the pipe characters exist because RStudio employs Hadley Wichkham, who in turn is really big on tidyverse and pipes. Would %>% mean anything in R if you didn't import magrittr? [1] https://github.com/tidyverse/magrittr/blob/8b3d510f2a333b22401e8b7be44e0df2ad36ec6f/R/pipe.R#L130 https://github.com/tidyverse/magrittr/blob/8b3d510f2a333b224...
- kkoncevicius 6y agoAll %fun% constructs are just simple functions that can be created by the user and can be used as infix operators. Base R has a few of those: %in%, %o%, %*%, %x%, %%, %/%. magrittr created %>% which, when used in infix: x %>% f() calls the function on the right side with the argument on the left side f(x). There are package that provide tons more. For example: https://github.com/moodymudskipper/inops https://github.com/moodymudskipper/inops . And you can easily create your own: `%sum%` <- function(x, y) x + y 1 %sum% 2 [1] 3
- deleted 6y ago[deleted]
- Huntsecker 6y agopersonally Im surprised R is still in active development when the main use case for people to use R (at least when I was using it) was for statistical analysis. Python with its libraries (a lot I believe ported from R) just does is nicer, and faster.
- civilized 6y agoNah, it's not nicer. dplyr is way better than pandas. But there is no end to the supply of Python fanbois who only know Python and assume that whatever's in Python just has to be better
- CameronNemo 6y agoI don't mind pandas so much, although dplyr is quite nice IMO (feels like natural language and declarative/SQL like, whereas pandas ends up with lots of procedural idioms). ggplot is something that I don't think matplotlib is comparable to at all, though. I am so much faster at iterating on a visualization with R/ggplot than Python/matplotlib. Maybe it is my tooling, though. How about others who have used both? What are your experiences?
- dm319 6y agoNo, same here. I tried to recreate some covid rate graphs in python. The ggplot code did facetting and fitted a LOESS to the data. Nothing ground breaking, but it really hit the limits of what seaborn was able to do, and I wasn't able to tinker with it much further. It got to the point where to make it look good I needed to calculate all the curves manually.
- t_serpico 6y agoggplot >> matplotlib and dplyr >> pandas. its not even close imo.
- hated 6y agoPandas is used in some top 10 banks for analytics. Its performance is abysmal at the scale used there. Nobody wants to invest resources in training analysts to write high performance code so here we are. I have never viewed SQL more highly after seeing the mess that analysts make when writing imperative code.
- civilized 6y agoThis sounds promising, but how do we type that pipe easily if we're going to be using it all the time? I actually like %>% because it's easy to reach the keys and hammer it out. Agreed on the ugly stack traces.
- SubiculumCode 6y agoYour hands are obviously quite different than mine, because |> is so much easier to reach than %>%
- kgwgk 6y agoIt may be the keyboard layout which is different.
- ellisv 6y agoMost likely via RStudio or VS Code hotkeys. It might replace Ctrl/Cmd+Shift+M
- stewbrew 6y agoWell, afaik it isn't really a pipe but syntactic sugar. A pipe streams data from one output stream to an input stream. This rewrites the code as if the input were passed as an argument.
- creddit 6y agoThat's exactly right. This is useful in the context of a large portion of R's most popular data wrangling packages known as the "Tidyverse". These packages used an equivalent pipe function that was non-native and had some perf and understandability issues.
- epistasis 6y ago|> This is not a pipe -René Magritte
- kgwgk 6y agoThe lambda thing may be useful. Sometimes I was tempted to do something like this > f <- function(expr) eval(substitute( function(x) expr )) > sapply(1:4, f({ a <- x^2 ; b <- x^3 ; a+b })) [1] 2 12 36 80 but I'm not sure it would have worked well. The new syntax is of course also more flexible.
- iaw 6y agoI've literally written something similar 4 times in the last month, I hate having to load the temp function to be sure the next line runs. This is such a useful addition.
- cwyers 6y agoThe R "userland" pipe magrittr has been altered to make it more compatible with the proposed base pipe, as well: https://www.tidyverse.org/blog/2020/11/magrittr-2-0-is-here/ https://www.tidyverse.org/blog/2020/11/magrittr-2-0-is-here/
- arthurcolle 6y agoThis is awesome. Wonder if they picked up on that specific syntactic operator from Elixir or from another world.
- saeranv 6y agoQuestion by someone who is ignorant but interested in functional programming: what is the closest equivalent to these functions in Python? (Or correct me if I'm asking the wrong question). I used to love using lambdas in Python, along with map/reduce/filter but for whatever reason the Python community has turned against it. Map and filter can now be nicely done with list comprehensions, although I still haven't found a decent one-line equivalent for reduce (other then importing functools).
- RussianCow 6y agoI'm not sure what specific "functions" you're talking about, but Python generally encourages a procedural style of programming as opposed to functional. The rationale is that functional code can be really difficult to read if you aren't already familiar with the idioms and terminology, whereas it's pretty easy to mentally parse and understand a `for` loop. So in that sense, list comprehensions are about as far as Python goes in that direction; there is no syntactic equivalent to the pipe operator, and no way to write reduce or similar operations as succinctly as you can in functional languages.
- vizzier 6y agoAnd just in brief as to what the pipe generally does without the syntax available. If you have functions x and y which take 1 argument. Where |> is the piping syntax y(1) |> x would be equivalent to x(y(1)) in python.
- nightski 6y agoHaving read plenty of python numerical code, I'm not sure "easy to parse and understand" is what exactly comes to mind.
- empthought 6y agoMost of the problem comes from Pandas which is of course R-inspired.
- 6y ago
- identity0 6y agoI wish more languages gave us a "|>" operator. Too many languages settle with dot notation, which confuses encapsulation/method calling with syntactical convenience.
- civilized 6y agoThis, along with inferior metaprogramming affordances, is the biggest reason pandas will never be as productive an analyst tool as R's dplyr. In R you can pipe anything into anything. In pandas you're stuck with the methods pandas gives you. This is also why pandas API is so bloated. A lot of pandas special-case functionality, like dropping duplicate rows, can be replicated in R by chaining together more flexible and orthogonal primitives.
- kaitai 6y agoAs someone who is now bouncing back & forth between Python and R on a weekly basis, I've been surprised (after making fun of R sometimes) how much I miss the piping when I leave R for Python. Pandas seems so inflexible by comparison, so nitpicky for little gain. I've been surprised again and again how much dplyr supports near-effortless fluency and productivity. Never really thought I'd be writing that in a public forum.
- smabie 6y agoI'm not an R user, but you should try Julia for data analysis. It seems as flexibility (maybe more) than R, while also having blazing performance. I do like Pandas concept of row indices, which I know Julia (and I believe, R) lack.
- tpoacher 6y agonitpicking, but this is not a lambda. it's an anonymous function.
- clircle 6y agoCare to elaborate?
- tpoacher 6y agoA lambda, at least as understood in a functional programming context, is pure. Whereas what is proposed here is simply syntactic sugar for creating an anonymous function; from the little that is said in the announcement there is no reason to think this syntax would provide any guarantees that state changes due to lexical scoping won't affect the function's output.
- deleted 6y ago[deleted]
- r-w 6y agoJulia crew, where you at?
- ellisv 6y ago:wave: But I’m also part of the R crew so :shrug:
- tpoacher 6y agoFor people asking how one could possibly ever manage to chain operations in python without a pipe operator: https://github.com/tpapastylianou/chain-ops-python https://github.com/tpapastylianou/chain-ops-python Same principle in octave: https://github.com/tpapastylianou/chain-ops-octave https://github.com/tpapastylianou/chain-ops-octave