Pipelining might be my favorite programming language feature
131–140 of 360 posts
Re: Pipelining might be my favorite programming language feature
#132This article is great, and really distills why the ergonomics of Rust is so great and why languages like Julia are so awful in practice.
imap(f) = x -> Iterators.map(f, x)
ifilter(f) = x -> Iterators.filter(f, x)
v = things |>
ifilter(isodd) |>
imap(do_process) |>
collectRe: Pipelining might be my favorite programming language feature
#133That new Rhombus language that was featured here recently has an interesting feature where you can use `_` in a function call to act as a "placeholder" for an argument. Essentially it's an easy way to partially apply a function. This works very well with piping because it allows you to pipe into any argument of a function (including optional arguments iirc) rather than just the first like many pipe implementations ha…
Re: Pipelining might be my favorite programming language feature
#134For example, we can write: (foo (bar (baz x))) as (-> x baz bar foo)
If there are additional arguments, we can accommodate those too: (sin (* x pi) as (-> x (* pi) sin)
Where expression so far gets inserted as the first argument to any form. If you want it inserted as the last argument, you can use ->> instead:
(filter positive? (map sin x)) as (->> x (map sin) (filter positive?))
You can also get full control of where to place the previous expression using as->.
Full details at https://clojure.org/guides/threading_macros
Re: Pipelining might be my favorite programming language feature
#135The tone of this (and the entire Haskell section of the article, tbh) is rather strange. Operators aren't special syntax and they aren't "added" to the language. Operators are just functions that by default use infix position. (In fact, any function can be called in infix position. And operators can be called in prefix position.)
The commit in question added & to the prelude. But if you wanted & (or any other character) to represent pipelining you have always been able to define that yourself.
Some people find this horrifying, which is a perfectly valid opinion (though in practice, when working in Haskell it isn't much of a big deal if you aren't foolish with it). But at least get the facts correct.
Re: Pipelining might be my favorite programming language feature
#136Earlier quoted context omitted.
I prefer Scala. You can write ``` params.get("user") |> create_user |> notify_admin ``` Even more concise and it doesn't even require a special language feature, it's just regular syntax of the language ( |> is a method like .get(...) so you could even write `params.get("user").|>(create_user) if you wanted to)
In elixir, ```Map.get("user") |> create_user |> notify_admin ``` would aso be valid, standard elixir, just not idiomatic (parens are optional, but preferred in most cases, and one-line pipes are also frowned upon except for scripting).
Also, what if the function you want to use is returned by some nullary function? You couldn't just do |> getfunc(), as presumably the pipeline operator will interfere with the usual meaning of the parentheses and will try to pass something to getfunc. Would |> ( getfunc() ) work? This is the kind of problem that can arise when one language feature is permitted to change the ordinary behaviour of an existing feature in the name of convenience. (Unless of course I'm just missing something.)
Re: Pipelining might be my favorite programming language feature
#137Being able to inspect the results of each step right at the point you’ve written it is pretty convenient. It’s readable. And the compiler will optimize it out.
Re: Pipelining might be my favorite programming language feature
#138Clojure has pipeline functions -> and ->> without resorting to OO dot syntax.
As well as some-> (exit on null) and cond-> (with predicates) that are often handy.
Re: Pipelining might be my favorite programming language feature
#139Earlier quoted context omitted.
The Clojure equivalent of `c |> baz |> bar |> foo` are the threading macros: (-> c baz bar foo) But people usually put it on separate lines: (-> c baz bar foo)
And with the Emacs Enlighten feature the second version enables seeing the results of each step right in the editor, to the right of the step.
Re: Pipelining might be my favorite programming language feature
#140Earlier quoted context omitted.
Yes, but here's my hot take - what if you didn't have to edit the source code to debug it? Instead of chaining method calls you just assign to a temporary variable. Then you can set breakpoints and inspect variable values like you do normally without editing source. It's not like you lose that much readability from foo(bar(baz(c))) c |> baz |> bar |> foo c.baz().bar().foo() t = c.baz() t = t.bar() t = t.foo()
I feel like a sufficiently good debugger should allow you to place a breakpoint at any of the lines here, and it should break exactly at that specific line. fn get_ids(data: Vec ) -> Vec { data.iter() .filter(|w| w.alive) .map(|w| w.id) .collect() } It sounds to me like you're asking for linebreaks. Chaining doesn't seem to be the issue here.