Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

151–160 of 360 posts

Re: Pipelining might be my favorite programming language feature

#151
post #61

C# has had "Pipelining" (aka Linq) for 17 years. I do miss this kind of stuff in Go a little.

I don't see how LINQ provides an especially illuminating example of what is effectively method chaining. It is an exemplar of expressions [0] more than anything else, which have little to do with the idea of passing results from one method to another. [0]: https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

Example from article:

fn get_ids(data: Vec) -> Vec { data.iter() // get iterator over elements of the list .filter(|w| w.alive) // use lambda to ignore tombstoned widgets .map(|w| w.id) // extract ids from widgets .collect() // assemble iterator into data structure (Vec) }

Same thing in 15 year old C# code.

List GetIds(List data)

{

    return data

           .Where(w => w.IsAlive())

           .Select(w => w.Id)

           .ToList();

}

Re: Pipelining might be my favorite programming language feature

#152
post #61

Earlier quoted context omitted.

I don't see how LINQ provides an especially illuminating example of what is effectively method chaining. It is an exemplar of expressions [0] more than anything else, which have little to do with the idea of passing results from one method to another. [0]: https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

So many things have been called Linq over the years it's hard to talk about at this point. I've written C# for many years now and I'm not even sure what I would say it's referring to, so I avoid the term. In this case I would say extension methods are what he's really referring to, of which Linq to objects is built on top of.

I'd say there are just two things:

1) The method chaining extension methods on IEnumerable like Select, Where, GroupBy, etc. This is identical to the rust example in the article.

2) The weird / bad (in my opinion) language keywords analogous to the above such as "from", "where", "select" etc.

Re: Pipelining might be my favorite programming language feature

#153
post #17

The tidyverse folks in R have been using that for a while: https://magrittr.tidyverse.org/reference/pipe.html

Base R as well: |> was implemented as a pipe operator in 4.1.0.

Importantly, the base R pipe implements the operation at the language parsing level, so it has basically zero overhead.

Re: Pipelining might be my favorite programming language feature

#154
post #31

Am I the only one who thinks yuck? Instead of writing: a().b().c().d(), it's much nicer to write: d(c(b(a()))), or perhaps (d ∘ c ∘ b ∘ a)().

When a b c d are longer expressions, the pipeline version looks more readable especially when split on multiple lines since it only has one level of indentation and you don't have to think about the number of parentheses at the end.

Re: Pipelining might be my favorite programming language feature

#156
post #143

Pipelining 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.

Depends on the context - in a scripting language where you have some kind of console you just don't copy all lines, and see what each pipe does one after another. This is pretty straight forward. (Not talking about compiled code though)

Re: Pipelining might be my favorite programming language feature

#157
post #48

Earlier quoted context omitted.

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.

Cool I love it, but another thing we will need polyfills for...

I believe you meant to say we will need a transpiler, not polyfill. Of course, a lot of us are already using transpilers, so that's nothing new.

Re: Pipelining might be my favorite programming language feature

#158

Earlier quoted context omitted.

I was excited for that proposal, but it veered off course some years ago – some TC39 members have stuck to the position that without member property support or async/await support, they will not let the feature move forward. It seems like most people are just asking for the simple function piping everyone expects from the |> syntax, but that doesn't look likely to happen.

I don't actually see why `|> await foo(bar)` wouldn't be acceptable if you must support futures. I'm not a JS dev so idk what member property support is.

Seems like it'd force the rest of the pipeline to be peppered with `await` which might not be desirable

    "bar"
    |> await getFuture(%);
    |> baz(await %);
    |> bat(await %);
My guess is the TC committee would want this to be more seamless.

This also gets weird because if the `|>` is a special function that sends in a magic `%` parameter, it'd have to be context sensitive to whether or not an `async` thing happens within the bounds. Whether or not it does will determine if the subsequent pipes are dealing with a future of % or just % directly.

Re: Pipelining might be my favorite programming language feature

#159

Kotlin sort of have it with let (and run) a().let{ b(it) }.let{ c(it) }

Yeah, Kotlin's solution is nice because it's so general: you can chain on to anything instead of needing everyone to implement a builder pattern. And it's already idiomatic unlike bolting a pipeline operator onto a language that didn't start with it.

If you see somebody using a builder in Kotlin, they're basically doing it wrong. You can usually get rid of that stuff with a 1 line extension function (for example if it's some Java API that's being called).

  // extension function on Foo.Companion (similar to static class function in Java)
  fun Foo.Companion.create(block: FooBuilder.() -> Unit): Foo =
    FooBuilder().apply(block).build()

  // example usage
  val myFoo = Foo.create {
    setSomeproperty("foo")
    setAnotherProperty("bar")
  }
Works for any Java/Kotlin API that forces you into method chaining and calling build() manually. Also works without extension functions. You can just call it fun createAFoo(..) or whatever. Looking around in the Kotlin stdlib code base is instructive. Lots of little 1/2 liners like this.
Post reply on HN