Skip to content

Instantly share code, notes, and snippets.

@smbache
Last active October 3, 2018 19:11
Show Gist options
  • Save smbache/ae9fb6bb747ac4f23a78 to your computer and use it in GitHub Desktop.
Save smbache/ae9fb6bb747ac4f23a78 to your computer and use it in GitHub Desktop.

To -> or not to ->

In the blog post "A Step to the Right in R Assignments", by @hrbrmstr, and in later twitter discussions (e.g. here), it is argued that <- (and %<>% for that matter) is "illogical" and feels awkward.

Although I can see where the temptation comes from, I consider -> to be bad practice (I do use it often in interactive work). In my view this kind of assignment in pipeline workflows is a great candidate for @hadleywickham's "you're doing it wrong if..." tweet series.

In other words I think that it is -> which is illogical and awkward, and that it is only making code more difficult to read. Let me explain why I think that it is semantically cleaner (or more idiomatic) to use <- by providing an analogy: you don't follow a recipe only to be enlightened after you followed all of the steps; "Oh, It was buns that I was baking!?" A recipe start with the promise, this is what you get, and then you follow the steps. Even next time you need to read about baking buns you may not need to read every detail in the workflow, but is still nice to quicly find the bun recipe:

buns <- # Know up front what you're going to get!
  bowl(rep("flour", 2), "yeast", "water", "warm milk", "oil") %>%
  append("flour", until = "soft") %>%
  beat(duration = "3mins") %>%
  shape(as = "balls", style = "slightly-flat") %>%
  bake(degrees = 200, duration = "15mins") %>%
  cool(buns, duration = "5mins") # -> buns  #rather than when you're done

Another analogy in the left-to-right discussion is that you don't see books where chapters are named on a page after the end of the chapter, although the pages are read from left-to-right (in most languages). You'll see it before the chapter starts; again this is what you get--and then the details. This holds true even if the author came up with the most appropriate name after finishing the chapter.

The <- symbol states what is being defined, and each step in the pipe-line provides the definition. Another benefit is that each step is aligned at the same level of indentation, whereas this is more messy:

some_outset %>% #Uh, what might be getting when I'm done?
    cool_stuff_here %>% # Can't wait...
    cute_stuff_there %>% #...
    and_finally -> CAT # Ahh, yay!

the first step, or the intial value, is not aligned with the rest, and you have to look closer before you see what is produced, even though I capitalized it.

The pipe %>% provides a mechanism for linearizing a workflow, and allows multiple statements to be read from left-to-right. It can be tempting to start using -> and to write long all-in-one pipelines. Some of this "mis-use" can lead to the very thing magrittr set out to minimize: hard-to-read, unstructured all-in-one code.

Of course you may find analogies that support -> too! An example is the latter sentence: only at the end did you see that it was to be emphasized (seing "!"). Wouldn't it be nice to know up front?

? What do you think...

@Guillawme
Copy link

Guillawme commented Oct 3, 2018

To me using -> goes against the design of R. E.g., AFAIK, you can't do this:

function(x,exponent){
  return(x^exponent)
  } -> 
pow2

Not saying you should use this notation, but it definitely works if you enclose the entire function definition with braces:

{
  function(x, exponent) {
      return(x^exponent)
  } 
} -> 
pow2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment