Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

321–330 of 360 posts

Re: Pipelining might be my favorite programming language feature

#321

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…

Shouldn’t modern debuggers be able to handle that easily? You can step in, step out, until you get where you want, or you could set a breakpoint in the method you want to debug instead of at the call site.

Even if your debugger can't do that, an AI agent can easily change the code for you to add intermediate output.

Re: Pipelining might be my favorite programming language feature

#322
post #261
post #120

Earlier quoted context omitted.

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

The difference between .let{} and ?.let{} has great utility. You'd either have to give that up or promote let from regular code in the standard library to magic language feature. And you'd lose all those cases of extension methods where the convenience of accepting null left of the dot is their sole reason to be. Null is a valid state, not something incredibly scary best dealt with with a full reboot or better yet th…

Personally I find ?.let et al to be terrible for readability; most of the time you're better off doing a standard != null check. The same with nullable extension functions; they hurt readability.

> Null is a valid state, not something incredibly scary best dealt with with a full reboot or better yet throwing away the container. Kotlin is about making peace with null, instead of pretending that null does not exist. (yes, I'm looking at you, Scala)

I honestly find this to be such a weird thing to say or imply. No one is "scared" of null.

Re: Pipelining might be my favorite programming language feature

#323
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've been using Elxir for a long time and had that same hope after having experienced how clear, concise and maintainable apps can be when the core is all a bunch of pipelines (and the boundary does error handling using cases and withs). But having seen the pipe operator in Ruby, I now think it was a bad idea.

The problem is that method-chaining is common in several OO languages, including Ruby. This means the functions on an object return an object, which can then call other functions on itself. In contrast, the pipe operator calls a function, passing in what's on the left side of it as the first argument. In order to work properly, this means you'll need functions that take the data as the first argument and return the same shape to return, whether that's a list, a map, a string or a struct, etc.

When you add a pipe operator to an OO language where method-chaining is common, you'll start getting two different types of APIs and it ends up messier than if you'd just stuck with chaining method calls. I much prefer passing immutable data into a pipeline of functions as Elixir does it, but I'd pick method chaining over a mix of method chaining and pipelines.

Re: Pipelining might be my favorite programming language feature

#324

Earlier quoted context omitted.

I don't think |> really can support applying the result of one of its composite applications in general, so it's not ambiguous. Given this example: (await getFutureAsyncFactory("bar"))("input") the getFutureAsyncFactory function is async, but the function it returns is not (or it may be and we just don't await it). Basically, using |> like you stated above doesn't do what you want. If you wanted the same semantics, y…

Ah sorry I didn't explain properly, I meant a |> await f() and a |> (await f()) Might be expected to do the same thing. But the latter is syntactically undistinguishable from a |> await returnsF() What do you think about a |> f |> g Where you don't really call the function with () in the pipeline syntax? I think that would be more natural.

It's still not ambiguous. Your second example would be a syntax error (probably, if I was designing it at least) because you're missing the invocation parenthesis after the wrapped value:

    a |> (await f())()
which removes any sort of ambiguity. Your first example calls f() with a as its first argument while the second (after my fix) calls and awaits f() and then invokes that result with a as its first argument.

For the last example, it would look like:

    a |> (await f())() | g()
assuming f() is still async and returns a function. g() must be a function, so the parenthesis have to be added.

Re: Pipelining might be my favorite programming language feature

#325

Earlier quoted context omitted.

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.

Yes, you totally misunderstood.

Re: Pipelining might be my favorite programming language feature

#327

(Un)surprisingly, the author ignores this is almost already a thing in JS. What a terrible oversight. Anyway, JS wins again, give it a try if you haven't, it's one of the best languages out there.

TypeScript is a beauty to work with. It's a shame that it's most often used in web contexts though. I would love to write a game engine that uses TypeScript as the scripting language.

Re: Pipelining might be my favorite programming language feature

#328
post #321

Earlier quoted context omitted.

Shouldn’t modern debuggers be able to handle that easily? You can step in, step out, until you get where you want, or you could set a breakpoint in the method you want to debug instead of at the call site.

Even if your debugger can't do that, an AI agent can easily change the code for you to add intermediate output.

...an AI agent can independently patch your debugger to modify the semantics? Wow that's crazy.

Incidentally, have you ever considered investing in real estate? I happen to own an interest in a lovely bridge which, for personal reasons, I must suddenly sell at a below-market price.

Re: Pipelining might be my favorite programming language feature

#329
post #244

Earlier quoted context omitted.

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

I'm not sure that's right, method chaining is just immediately acting on the return of the previous function, directly. It doesn't pass the return into the next function like a pipeline. The method must exist on the returned object. That is different to pipelines or thrush operators. Evaluation happens in the order it is written. Unless I misunderstood the author, because method chaining is super common where I feel…

They cite Gleam explicitly, which has a thrush operator in place of method chaining.

I get the impression (though I haven't checked) that the thrush operator is a backport of OOP-style method chaining to functional languages that don't support dot-method notation.

Re: Pipelining might be my favorite programming language feature

#330

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…

Yeah, I've always heard this called method chaining. It's widespread in C#, particularly with Linq (which was explicitly designed to leverage it).

I've only ever heard the term 'pipelining' in reference to GPUs, or as an abstract umbrella term for moving data around.

Post reply on HN