Earlier quoted context omitted.
Haskell has & which goes the other way: users & map validate & catMaybes & mapM persist
Yes, `&` (reverse apply) is equivalent to `|>`, but it is interesting that there is no common operator for reversed compose `.`, so function compositions are still read right-to-left. In my programming language, I added `.>` as a reverse-compose operator, so pipelines of function compositions can also be read uniformly left-to-right, e.g. process = map validate .> catMaybes .> mapM persist
Pipelining might be my favorite programming language feature
241–250 of 360 posts
Re: Pipelining might be my favorite programming language feature
#242The author keeps calling it "pipelining", but I think the right term is "method chaining". Compare with a simple pipeline in bash: grep needle Each of those components executes in parallel, with the intermediate results streaming between them. You get a similar effect with coroutines. Compare Ruby: data = File.readlines("haystack.txt") .map(&:strip) .grep(/needle/) .map { |i| i.gsub('foo', 'bar') } .map { |i| File.re…
Bit annoying, but serviceable. Though there's nothing wrong with your approach either.
Re: Pipelining might be my favorite programming language feature
#243The author keeps calling it "pipelining", but I think the right term is "method chaining". Compare with a simple pipeline in bash: grep needle Each of those components executes in parallel, with the intermediate results streaming between them. You get a similar effect with coroutines. Compare Ruby: data = File.readlines("haystack.txt") .map(&:strip) .grep(/needle/) .map { |i| i.gsub('foo', 'bar') } .map { |i| File.re…
Other than that I think both styles are fine.
Re: Pipelining might be my favorite programming language feature
#244The author keeps calling it "pipelining", but I think the right term is "method chaining". Compare with a simple pipeline in bash: grep needle Each of those components executes in parallel, with the intermediate results streaming between them. You get a similar effect with coroutines. Compare Ruby: data = File.readlines("haystack.txt") .map(&:strip) .grep(/needle/) .map { |i| i.gsub('foo', 'bar') } .map { |i| File.re…
> The author keeps calling it "pipelining", but I think the right term is "method chaining". I believe the correct definition for this concept is the Thrush combinator[0]. In some ML-based languages[1], such as F#, the |> operator is defined[2] for same: [1..10] |> List.map (fun i -> i + 1) Other functional languages have libraries which also provide this operator, such as the Scala Mouse[3] project. 0 - https://lean…
Unless I misunderstood the author, because method chaining is super common where I feel thrush operators are pretty rare, I would be surprised if they meant the latter.
Re: Pipelining might be my favorite programming language feature
#245I'm personally someone who advocates for languages to keep their feature set small and shoot to achieve a finished feature set quickly. However. I would be lying if I didn't secretly wish that all languages adopted the `|>` syntax from Elixir. ``` params |> Map.get("user") |> create_user() |> notify_admin() ```
I wish there were a variation that can destructure more ergonomically. Instead of: ``` fetch_data() |> (fn {:ok, val, _meta} -> val :error -> "default value" end).() |> String.upcase() ``` Something like this: ``` fetch_data() |>? {:ok, val, _meta} -> val |>? :error -> "default value" |> String.upcase() ```
Re: Pipelining might be my favorite programming language feature
#246In fact, I always thought it would be a good idea for all statement blocks (in any given programming language) to allow an implicit reference to the value of the previous statement. The pipeline operation would essentially be the existing semicolons (in a C-like language) and there would be a new symbol or keyword used to represent the previous value.
For example, the MATLAB REPL allows for referring to the previous value as `ans` and the Julia REPL has inherited the same functionality. You can copy-paste this into the Julia REPL today:
[1, 2, 3];
map(x -> x * 2, ans);
@show ans;
filter(x -> x > 2, ans);
@show ans;
sum(ans)
You can't use this in Julia outside the REPL, and I don't think `ans` is a particularly good keyword for this, but I honestly think the concept is good enough. The same thing in JavaScript using `$` as an example: {
[1 ,2, 3];
$.map(x => x * 2);
(console.log($), $);
$.filter(x => x > 2);
(console.log($), $);
$.reduce((acc, next) => acc + next, 0)
}
I feel it would work best with expression-based languages having blocks that return their final value (like Rust) since you can do all sorts of nesting and so-on.Re: Pipelining might be my favorite programming language feature
#247Pipelining looks nice until you have to debug it. And exception handling is also very difficult, because that means to add forks into your pipelines. Pipelines are only good for programming the happy path.
Programming should be focused on the happy path. Much of the syntax in primitive languages concerning exceptions and other early returns is pure noise.
Re: Pipelining might be my favorite programming language feature
#248Earlier quoted context omitted.
I feel like Haskell really missed a trick by having $ not go the other way, though it's trivial to make your own symbol that goes the other way.
Haskell has & which goes the other way: users & map validate & catMaybes & mapM persist
users
|> map validate
|> catMaybes
|> mapM persistRe: Pipelining might be my favorite programming language feature
#249The author keeps calling it "pipelining", but I think the right term is "method chaining". Compare with a simple pipeline in bash: grep needle Each of those components executes in parallel, with the intermediate results streaming between them. You get a similar effect with coroutines. Compare Ruby: data = File.readlines("haystack.txt") .map(&:strip) .grep(/needle/) .map { |i| i.gsub('foo', 'bar') } .map { |i| File.re…
the chaining really only works if your language is strongly typed and you are somewhat guaranteed that variables will be of expected type.
Re: Pipelining might be my favorite programming language feature
#250A pipeline operator is just partial application with less power. You should be able to bind any number of arguments to any places in order to create a new function and "pipe" its output(s) to any other number of functions. One day, we'll (re)discover that partial application is actually incredibly useful for writing programs and (non-Haskell) languages will start with it as the primitive for composing programs instea…