Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

261–270 of 360 posts

Re: Pipelining might be my favorite programming language feature

#261
post #120
post #25

Earlier quoted context omitted.

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

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

What I do agree with is that extension methods should be a last ditch solution. I'd actually like to see a way to do the nullable receiver thing defined more like regular functions. Perhaps something like

   fun? name() = if (this==null) "(Absent)" else this.name
that is defined inside the regular class block, imported like a regular method (as part of the class) and even present in the class object e.g. for reflection on the non-null case (and for Java compat where that still matters)

Re: Pipelining might be my favorite programming language feature

#262

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…

> Despite being clean and readable, I don't tend to do it any more, because it's harder to debug. More often these days, I write things like this: data = File.readlines("haystack.txt") data = data.map(&:strip) data = data.grep(/needle/) data = data.map { |i| i.gsub('foo', 'bar') } data = data.map { |i| File.readlines(i).count } Hard disagree. It's less readable, the intend is unclear (where does it end?), and the var…

The person you are quoting already conceded that is less readable, but that the ability to set a breakpoint easily (without having to stop the process and modify the code) is more important.

I myself agree, and find myself doing that too, especially in frontend code that executes in a browser. Debuggability is much more important than marginally-better readability, for production code.

Re: Pipelining might be my favorite programming language feature

#263
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.

PHP RFC for version 8.5 too: https://wiki.php.net/rfc/pipe-operator-v3

Re: Pipelining might be my favorite programming language feature

#264

Earlier quoted context omitted.

Aren't transducers strictly functional terminology? Also, does the name matter if it works the same and has the same properties? Maybe the author called it "pipelines" to avoid functional purists from nitpicking it.

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 lot of stress around purity, why would anyone want to make it worse?

Re: Pipelining might be my favorite programming language feature

#265

Earlier quoted context omitted.

Correct me if I'm wrong, but if you use the below syntax "bar" |> await getFuture() How would you disambiguate it from your intended meaning and the below: "bar" |> await getFutureAsyncFactory() Basically, an async function that returns a function which is intended to be the pipeline processor. Typically in JS you do this with parens like so: (await getFutureAsyncFactory())("input") But the use of parens doesn't tran…

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.

Re: Pipelining might be my favorite programming language feature

#266
The left associativity of functions really doesn't work well with English reading left to right. I found this especially clear with the'composition opperator' of functions. Where f.g has to mean f _after_ g because you really want:

    f.g = f(g(x))
Based on this, I think a reverse polish type of notation would be a lot better. Though perhaps it is a lot nicer to think of "the sine of an angle" than "angle sine-ed".

Not that it matters much, the switching costs are immense. Getting people able to teach it would be impossible, and collaboration with people taught in the other system would be horrible. I am doubtful I could make the switch, even if I wanted.

Re: Pipelining might be my favorite programming language feature

#267

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…

I don’t find your “seasoned developer” version ugly at all. It just looks more mature and relaxed. It also has the benefits that you can actually do error handling and have space to add comments. Maybe people don’t like it because of the repetition of “data =“ but in fact you could use descriptive new variable names making the code even more readable (auto documenting). I’ve always felt method chaining to look “cramped”, if that’s the right word. Like a person drawing on paper but only using the upper left corner. However, this surely is also a matter of preference or what your used to.

Re: Pipelining might be my favorite programming language feature

#268

Earlier quoted context omitted.

In my eyes newlines don't solve what I feel to be the issue. Reader needs to recognize reading from left->right to right->left. Of course this really only matters when you're 25 minutes into critical downtime and a bug is hiding somewhere in these method chains. Anything that is surprising needs to go. IMHO it would be better to set intermediate variables with dead simple names instead of newlines. fn get_ids(data: V…

> Reader needs to recognize reading from left->right to right->left. Yeah, I agree. The problem is that you have to keep track of nesting in the middle of the expression and then unnest it at the end, which is taxing. So, I also think it could also read better written like this, with the arguments reversed, so you don't have to read it both ways: fn get_ids(data: Vec ) -> Vec { collect( map(|w| w.id, filter |w| w.ali…

The argument ordering Haskell (and, I think, most functional languages) uses is definitely simpler to read. It keeps the components of the tranformation/filter together.

Re: Pipelining might be my favorite programming language feature

#269

PowerShell has the best pipeline capability of any language I have ever seen. For comparison, UNIX pipes support only trivial byte streams from output to input. PowerShell allows typed object streams where the properties of the object are automatically wired up to named parameters of the commands on the pipeline. Outputs at any stage can not only be wired directly to the next stage but also captured into named variab…

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

Re: Pipelining might be my favorite programming language feature

#270

PowerShell has the best pipeline capability of any language I have ever seen. For comparison, UNIX pipes support only trivial byte streams from output to input. PowerShell allows typed object streams where the properties of the object are automatically wired up to named parameters of the commands on the pipeline. Outputs at any stage can not only be wired directly to the next stage but also captured into named variab…

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
Post reply on HN