Live data from Hacker News

Pipelining might be my favorite programming language feature

herecomesthemoon.net

161–170 of 360 posts

Re: Pipelining might be my favorite programming language feature

#161
post #147

Earlier quoted context omitted.

The pipe operator relies on the first argument being the subject of the operation. A lot of languages have the arguments in a different order, and OO languages sometimes use function chaining to get a similar result.

IIRC the usual workaround in Elixir involves be small lambda that rearranges things: "World" |> then(&concat("Hello ", &1)) I imagine a shorter syntax could someday be possible, where some special placeholder expression could be used, ex: "World" |> concat("Hello ", &1) However that creates a new problem: If the implicit-first-argument form is still permitted (foo() instead of foo(&1)) then it becomes confusing which…

Yeah I really hate that syntax and I can’t even explain why so I kind of blot it out, but you’re right.

My dislike does improve my test coverage though, since I tend to pop out a real method instead.

Re: Pipelining might be my favorite programming language feature

#162
I think there's a language syntax to be invented that would make everything suffix/pipeline-based. Stack based languages are kind of there, but I don't think exactly the same thing.

BTW. For people complaining about debug-ability of it: https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho... etc.

Re: Pipelining might be my favorite programming language feature

#163

Earlier quoted context omitted.

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…

It wouldn't though? The first await would... await the value out of the future. You still do the syntactic transformation with the magic parameter. In your example you're awaiting the future returned by getFuture twice and improperly awaiting the output of baz (which isn't async in the example).

In reality it would look like:

    "bar"
    |> await getFuture()
    |> baz()
    |> await bat()
(assuming getFuture and bat are both async). You do need |> to be aware of the case where the await keyword is present, but that's about it. The above would effectively transform to:

    await bat(baz(await getFuture("bar")));
I don't see the problem with this.

Re: Pipelining might be my favorite programming language feature

#164
post #20

To one up this: Of course it is even better, if your language allows you to implement proper pipelining with implicit argument passing by yourself. Then the standard language does not need to provide it and assign meaning to some symbols for pipelining. You can decide for yourself what symbols are used and what you find intuitive. Pipelining can guide one to write a bit cleaner code, viewing steps of computation as s…

> if your language allows you to implement proper pipelining with implicit argument passing by yourself > You can decide for yourself what symbols are used and what you find intuitive i mean this sounds fun but tbh it also sounds like it'd result in my colleague Carl defining an utterly bespoke DSL in the language, and using it to write the worst spaghetti code the world has ever seen, leaving the code base an unread…

Even veterans mess things up if you use too much of these exotic syntaxes. For loops and if statements rock, but they aren't cool and functional so they aren't discussed much.

Re: Pipelining might be my favorite programming language feature

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

The pipe operator relies on the first argument being the subject of the operation. A lot of languages have the arguments in a different order, and OO languages sometimes use function chaining to get a similar result.

Swiss arrows ftw!

https://github.com/rplevy/swiss-arrows https://github.com/hipeta/arrow-macros

Re: Pipelining might be my favorite programming language feature

#166
post #160

First example doesn't look bad in C++23: auto get_ids(std::span data) { return data | filter(&Widget::alive) | transform(&Widget::id) | to (); }

This looks awesome! I'm really want to start playing with some C++23 in the future.

I cheated a bit, I omitted the namespaces. Here's a working version: https://godbolt.org/z/1rE9o3Y95

Re: Pipelining might be my favorite programming language feature

#167

Earlier quoted context omitted.

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…

It wouldn't though? The first await would... await the value out of the future. You still do the syntactic transformation with the magic parameter. In your example you're awaiting the future returned by getFuture twice and improperly awaiting the output of baz (which isn't async in the example). In reality it would look like: "bar" |> await getFuture() |> baz() |> await bat() (assuming getFuture and bat are both asyn…

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 transpose to the pipeline setting well IMO

Re: Pipelining might be my favorite programming language feature

#168
post #93
post #87

Earlier quoted context omitted.

I would wager within a rounding error, all humans have a lifetime of experience in following directions of the form: 1. do the first step in the process 2. then do the next thing 3. followed by a third action I struggle to think of any context outside of programming, retrosynthesis in chemistry, and some aspects of reverse-Polish notation calculators, where you conceive of the operations/arguments last-to-first. All…

Consistency is more important. If you ever wrote: a(b()) then you're already breaking your left-to-right/first-to-last rule.

This is a foolish consistency, and a contrived counterexample. Consistency is not an ideal unto itself.

Re: Pipelining might be my favorite programming language feature

#169
post #70

I also like a syntax that includes pipelining parallelization, for example: A .B .C || D || E

Wouldn't this complicate variable binding? I'm unsure how to think about this kinda of syntax if either D or E are expected to return some kind of data instead of "fire and forget" processes.

Re: Pipelining might be my favorite programming language feature

#170
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 wish there were a variation that can destructure more ergonomically.

Instead of:

```

fetch_data()

|> (fn

  {:ok, val, _meta} -> val

  :error -> "default value"
end).()

|> String.upcase()

```

Something like this:

```

fetch_data()

|>? {:ok, val, _meta} -> val

|>? :error -> "default value"

|> String.upcase()

```

Post reply on HN