Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

301–310 of 360 posts

Re: Pipelining might be my favorite programming language feature

#301
post #96

Earlier quoted context omitted.

Why, if you don't have to, would you write the functions in reverse order of when they're applied?

It's a bit snarky, but would you rather write FORTH then? So instead of draw(line.start, line.end); print(i, round(a / b)); you'd write line.start, line.end |> draw; i, a, b |> div |> round |> print;

Still too much syntax for a Forth. It should be

    line.start line.end draw
    i a b div round print

Re: Pipelining might be my favorite programming language feature

#302
post #242

The 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…

In most debuggers I have used, if you put a breakpoint on the first line of the method chain, you can "step over" each function in the chain until you get to the one you want. Bit annoying, but serviceable. Though there's nothing wrong with your approach either.

debuggers can take it even further if they want that UX. in firefox given a chain of foo().bar().baz() you can set a breakpoint on any of 'em.

https://gist.github.com/user-attachments/assets/3329d736-70f...

Re: Pipelining might be my favorite programming language feature

#303
post #203
post #24

I'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() ```

Pipelines are one of the greatest Gleam features[1]. [1] https://tour.gleam.run/functions/pipelines/

I wouldn't say it's a Gleam feature per se, in that it's not something that it's added that isn't already in Elixir.

Re: Pipelining might be my favorite programming language feature

#304

Earlier quoted context omitted.

You should look at Nushell. Much as I like powershell, Nushell just seems better.

I’d love to, but even the core concepts like pipeline behaviour aren’t documented. There’s just a bunch of empty headings: https://www.nushell.sh/lang-guide/chapters/pipelines.html

Yeah, it's younger than powershell so there's some rough edges in some places. I wouldn't let empty headings in the docs stop you using/experimenting with it though.

I use powershell daily but am hopeful that I can replace it with Nushell at some point.

Re: Pipelining might be my favorite programming language feature

#305
post #24

I'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'm a big fan of the Elixir operator, and it should be standard in all functional programming languages. You need it because everything is just a function and you can't do anything like method chaining, because none of the return values have anything like methods. The |> is "just" syntax sugar for a load of nested functions. Whereas the Rust style method chaining doesn't need language support - it's more of a programming style.

Note also that it works well in Elixir because it was created at the same time as most of the standard library. That means that the standard library takes the relevant argument in the first position all the time. Very rarely do you need to pipe into the second argument (and you need a lambda or convenience function to make that work).

Re: Pipelining might be my favorite programming language feature

#306

Earlier quoted context omitted.

Yeah I do think of transducers as a functional paradigm, I read the article as describing a very functional paradigm as well. In the context of a specific programming language feature it seems like terminology would be important, I wasn't trying to nitpick unintentionally.

It is important for the functional guys, and I recognize the importance it has for them. These "pipelines" and "object streaming" APIs are often built upon OOP. I feel that calling it "transducers" would offend the sensibilities of those who think it must be functional all the way down. Don't you think it's better to keep it with a different name? I mean, even among the functional community itself there seems to be a…

I may have just misunderstood the OP. It sounded to me like describing the benefits specifically of transducers, but if it was OOP and more just about piping operators or chaining the term wouldn't fit.

Re: Pipelining might be my favorite programming language feature

#307

The 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…

If you add in a call to “.lazy“ it won’t create all the intermediate arrays. There since at least 2.7. https://ruby-doc.org/core-2.7.0/Enumerator/Lazy.html

I do the same with Python, replacing multilevel comprehensions with intermediary steps of generator expressions, which are lazy and therefore do not impact performance and memory usage.

https://peps.python.org/pep-0289/

Re: Pipelining might be my favorite programming language feature

#308
post #24

I'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() ```

Yes, a small feature set is important, and adding the functional-style pipe to languages that already have chaining with the dot seems to clutter up the design space. However, dot-chaining has the severe limitation that you can only pass to the first or "this" argument. Is there any language with a single feature that gives the best of both worlds?

Do concatenative langs like Factor fit the bill?

Re: Pipelining might be my favorite programming language feature

#309
post #95

A 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…

for loops are also gotos with less power, yet we usually prefer them.

Re: Pipelining might be my favorite programming language feature

#310

The 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…

Isn't the difference between a pipeline and a method chain that a pipeline doesn't have to wait for the previous process to complete in order to send results to the next step? Grep sends lines as it finds them to sed and sed on to xargs, which acts as a sink to collect the data (an is necessary otherwise wc -l would write out a series of ones).

Given File.readlines("haystack.txt"), the entire file must be resident in memory before .grep(/needle/) is performed, which may cause unnecessary utilization. Iirc, in frameworks like Polars, the collect() chain ending method tells the compiler that the previous methods will be performed as a stream and thus not require pulling the entirety into memory in order to perform an operation on a subset of the corpus.

Post reply on HN