Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

111–120 of 360 posts

Re: Pipelining might be my favorite programming language feature

#112
The one thing that I don’t like about pipelining (whether using a pipe operator or method chaining), is that assigning the result to a variable goes in the wrong direction, so to speak. There should be an equivalent of the shell’s `>` for piping into a variable as the final step. Of course, if the variable is being declared at the same time, whatever the concrete syntax is would still require some getting used to, being “backwards” compared to regular assignment/initialization.

Re: Pipelining might be my favorite programming language feature

#113
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…

... and then recreate the scripting language...

Re: Pipelining might be my favorite programming language feature

#116
post #91

I feel like, at least in some cases, the article is going out of its way to make the "undesired" look worse than it needs to be. Compairing fn get_ids(data: Vec ) -> Vec { collect(map(filter(map(iter(data), |w| w.toWingding()), |w| w.alive), |w| w.id)) } to fn get_ids(data: Vec ) -> Vec { data.iter() .map(|w| w.toWingding()) .filter(|w| w.alive) .map(|w| w.id) .collect() } The first one would read more easily (and, s…

They did touch on that. > You might think that this issue is just about trying to cram everything onto a single line, but frankly, trying to move away from that doesn’t help much. It will still mess up your git diffs and the blame layer. Diff will still be terrible because adding a step will change the indentation of everything 'before it' (which, somewhat confusingly, are below it syntactically) in the chain.

Diff can ignore whitespace, so not really an issue. Not _as_ nice, but not really a problem.

Re: Pipelining might be my favorite programming language feature

#117

I suffer from (what I call) bracket claustrophobia. Whenever brackets get nested too deep I makes me uncomfortable. But I fully realize that there are people who are the complete opposite. Lisp programmers are apparently as claustrophil as cats and spelunkers.

Forget the parenthesis, embrace the automatic indentation and code source manipulations that only perfectly balanced homoiconic expressions can give you.

Re: Pipelining might be my favorite programming language feature

#118
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() ```

We might be able to cross one more language off your wishlist soon, Javascript is on the way to getting a pipeline operator, the proposal is currently at Stage 2 https://github.com/tc39/proposal-pipeline-operator I'm very excited for it.

It also has barely seen any activity in years. It is going nowhere. The TC39 committee is utterly dysfunctional and anti-progress, and will not let any this or any other new syntax into JavaScript. Records and tuples has just been killed, despite being cited in surveys as a major missing feature[1]. Pattern matching is stuck in stage 1 and hasn't been presented since 2022. Ditto for type annotations and a million other things.

Our only hope is if TypeScript finally gives up on the broken TC39 process and starts to implement its own syntax enhancements again.

[1] https://2024.stateofjs.com/en-US/usage/#top_currently_missin...

Re: Pipelining might be my favorite programming language feature

#119
post #105

I feel like, at least in some cases, the article is going out of its way to make the "undesired" look worse than it needs to be. Compairing fn get_ids(data: Vec ) -> Vec { collect(map(filter(map(iter(data), |w| w.toWingding()), |w| w.alive), |w| w.id)) } to fn get_ids(data: Vec ) -> Vec { data.iter() .map(|w| w.toWingding()) .filter(|w| w.alive) .map(|w| w.id) .collect() } The first one would read more easily (and, s…

Oh wow, are we living in the same universe? To me the one-line example and your example with line breaks... they just... look about the same? See how adding line breaks still keeps the `|w| w.alive` very far from the `filter` call? And the `|w| w.id` very far from the `map` call? If you don't have the pipeline operator, please at least format it something like this: fn get_ids(data: Vec ) -> Vec { collect( map( filte…

> It's not about line breaks, it's about the order of applying the operations

For me, it's both. Honestly, I find it much less readable the way you're split it up. The way I had it makes it very easy for me to read it in reverse; map, filter, map, collect

> Also see how this still reads fine despite being one line

It doesn't read fine, to me. I have to spend mental effort figuring out what the various "steps" are. Effort that I don't need to spend when they're split across lines.

For me, it's a "forest for the trees" kind of thing. I like being able to look at the code casually and see what it's doing at a high level. Then, if I want to see the details, I can look more closely at the code.

Re: Pipelining might be my favorite programming language feature

#120
post #25
post #19

data.iter() .filter(|w| w.alive) .map(|w| w.id) .collect() collect(map(filter(iter(data), |w| w.alive), |w| w.id)) The second approach is open for extension - it allows you to write new functions on old datatypes. > Quick challenge for the curious Rustacean, can you explain why we cannot rewrite the above code like this, even if we import all of the symbols? Probably for lack of > weird operators like , , $, or >>=

Extension methods to the rescue: https://en.wikipedia.org/wiki/Extension_method Examples: https://kotlinlang.org/docs/extensions.html https://docs.scala-lang.org/scala3/reference/contextual/exte... See also: https://en.wikipedia.org/wiki/Uniform_function_call_syntax

I really wish you couldn't write extensions on nullable types. It's confusing to be able to call what look like instance functions on something clearly nullable without checking.

    fun main() {
        val s: String? = null
        println(s.isS()) // false
    }

    fun String?.isS() = "s" == this
Post reply on HN