Skip to content

Instantly share code, notes, and snippets.

@rodocite
Last active June 16, 2017 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodocite/99d470890658a1b1253830204afd0223 to your computer and use it in GitHub Desktop.
Save rodocite/99d470890658a1b1253830204afd0223 to your computer and use it in GitHub Desktop.
This is why we need the pipe operator in every language.
list = [1, [[2], 3]]
list
|> List.flatten
|> Enum.reverse
|> Enum.map(fn(n) -> n * n end)
|> IO.inspect
IO.inspect(Enum.map(Enum.reverse(List.flatten(list)), fn(n) -> n * n end))
@krainboltgreene
Copy link

krainboltgreene commented Jun 15, 2017

In Ruby (no pipe operator):

list.flatten.reverse.map { |n| n * n }.to_s

In javascript (no pipe operator)

pipe(flatten, reverse, map, console.log)(list)

@rodocite
Copy link
Author

rodocite commented Jun 16, 2017

Ruby - You need to return an array for each transform (that's why you had to call to_s in the end instead of using puts). In Elixir, you can use any function you want.
JS - You need to bring in Ramda (It's disingenuous to call it JS). And R.pipe has arity limitations on subsequent functions.

You couldn't do this with R.pipe():

list
|> my_func1
|> my_func2(arg2, arg3) #=> the return from `my_func1` is arg1
|> IO.inspect

@krainboltgreene
Copy link

You need to return an array for each transform (that's why you had to call to_s in the end instead of using puts). In Elixir, you can use any function you want.

  1. No, you don't need to return an array for each transform. These functions work on any Enumerable inheriting object.
  2. I didn't have to call to_s, I just thought that was Io.console did. Here's a more equivalent:
list.flatten.reverse.map { |n| n * n }.map(&method(:puts))

You need to bring in Ramda (It's disingenuous to call it JS). And R.pipe has arity limitations on subsequent functions.

  1. Yes, it's not the standard library for javascript...but when do you not have a third party library system?
  2. Pipe has no arity limitations:
pipe(myFunc1, myFunc2(arg2, arg3), console.log)(list)

@rodocite
Copy link
Author

rodocite commented Jun 16, 2017

Ruby - If it was not an Enumerable, the chaining would be broken. Elixir pipe allows any value to be piped.
Ramda - pipe has arity limitations. First function can have any arity. Subsequent functions can only be unary-- meaning you have to write adapter functions or use R.curry for already existing functions you could have just piped in. I don't think your example will work. http://ramdajs.com/docs/#pipe

Less trivial example of a pipe:

"path/to/some/file"
|> File.stream!
|> Flow.from_enumerable()
|> Flow.flat_map(&String.split(&1, " "))
|> Flow.partition()
|> Flow.reduce(fn -> %{} end, fn word, acc ->
  Map.update(acc, word, 1, & &1 + 1)
end)
|> Enum.to_list()

That counts the occurrence of each word in a several gig file in a few seconds, distributed across all processor cores. Stream the file, convert to enumerable, flat map it, partition it, reduce it, dump to list. Reads like a list.

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