Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> So, you start out with g(x) and then need to go all the way back and add f.

That's one thing I will say after coming from Perl/PHP to Java, is that despite its verbosity and the uselessness of having to write .stream(), I much prefer Java's stream.map(...).filter(...) syntax over the more functional-style filter(map(list, ..), ..) syntax. The Java syntax reads left-to-right, which is the order you want when you're thinking about code, and also as you say writing it. I think if I were creating a programming language I too would try to make stuff read left-to-right as much as possible.



It's notable that raku (previously known as perl6) lets you write things in either direction, if I remember correctly something like

  @source >>> map { ... } >>> grep { ... } >>> my @sink;
though note I'm typing from memory on my second coffee so I may have got that slightly wrong.

Plus of course there's many languages with a |> operator so you can do

  g(x) |> f
I also (the example is specialised for I/O but the implementation technique could trivially be borrowed for something that wasn't) implemented something sort of in this direction for perl once: http://p3rl.org/IO::Pipeline

I'm not convinced that left-to-right is -always- the best option and prefer having the choice of both, but I wouldn't be at all surprised if a survey of developers found that if they could only pick one they'd pick left-to-right, and while I'd find it hard to choose for myself alone I'd probably pick left-to-right on the basis that it'd likely make it easier to onboard people to any given codebase.


Raku also has map and grep methods for collections, so it could be written as...

  my @sink = @source.map({...}).grep({...}).sort;
Which also makes multithreading the operation easy:

  my @sink = @source.hyper.map({...}).grep({...}).sort.list;
That said, I think the operator you're looking for is the feed operator, ==>:

  my @sink;
  @source ==> map {...} ==> grep {...} ==> sort ==> @sink;
It also has the corresponding reverse, <==, because why not. The docs* mention that ==> may at some point do automatic parallelization, but I don't know what the status of that feature is.

* https://docs.raku.org/routine/==%3E


> That said, I think the operator you're looking for is the feed operator, ==>

Yes, yes it was.

Your clarifications, corrections and elaborations are much appreciated.


Aligning reading order with flow of actions is so important!

That's why I use and msybe tend to abuse the `->` and `->>` macros in Clojure and the pipe operator `|>` in Elixir.

Hopefully soon in JS as well, if I've read correctly.


Not sure about other Lisp languages, but Clojure has thread operators that allow you to compose function calls this way, allowing you to visualize code in that preferred left-to-right (or top-to-bottom) order.


In addition to the examples other people have given, I think Ruby does this very nicely by making map, filter, and reduce methods on collection data structures.

Of course, Ruby is a bit of a mixed bag, but for the applications where it fits, it can be very nice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: