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.
Pipelining might be my favorite programming language feature
321–330 of 360 posts
Re: Pipelining might be my favorite programming language feature
#322Earlier 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…
> 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
#323I'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() ```
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
#324Earlier 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.
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
#325Earlier 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.
Re: Pipelining might be my favorite programming language feature
#326Anyway, JS wins again, give it a try if you haven't, it's one of the best languages out there.
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.
Re: Pipelining might be my favorite programming language feature
#328Earlier 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.
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
#329Earlier 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…
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
#330The 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…
I've only ever heard the term 'pipelining' in reference to GPUs, or as an abstract umbrella term for moving data around.