frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Reverse Engineering Medium.com's Editor: How Copy, Paste, and Images Work

https://app.writtte.com/read/gP0H6W5
1•birdculture•3m ago•0 comments

Go 1.22, SQLite, and Next.js: The "Boring" Back End

https://mohammedeabdelaziz.github.io/articles/go-next-pt-2
1•mohammede•8m ago•0 comments

Laibach the Whistleblowers [video]

https://www.youtube.com/watch?v=c6Mx2mxpaCY
1•KnuthIsGod•10m ago•1 comments

I replaced the front page with AI slop and honestly it's an improvement

https://slop-news.pages.dev/slop-news
1•keepamovin•14m ago•1 comments

Economists vs. Technologists on AI

https://ideasindevelopment.substack.com/p/economists-vs-technologists-on-ai
1•econlmics•16m ago•0 comments

Life at the Edge

https://asadk.com/p/edge
2•tosh•22m ago•0 comments

RISC-V Vector Primer

https://github.com/simplex-micro/riscv-vector-primer/blob/main/index.md
3•oxxoxoxooo•26m ago•1 comments

Show HN: Invoxo – Invoicing with automatic EU VAT for cross-border services

2•InvoxoEU•26m ago•0 comments

A Tale of Two Standards, POSIX and Win32 (2005)

https://www.samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
2•goranmoomin•30m ago•0 comments

Ask HN: Is the Downfall of SaaS Started?

3•throwaw12•31m ago•0 comments

Flirt: The Native Backend

https://blog.buenzli.dev/flirt-native-backend/
2•senekor•33m ago•0 comments

OpenAI's Latest Platform Targets Enterprise Customers

https://aibusiness.com/agentic-ai/openai-s-latest-platform-targets-enterprise-customers
1•myk-e•35m ago•0 comments

Goldman Sachs taps Anthropic's Claude to automate accounting, compliance roles

https://www.cnbc.com/2026/02/06/anthropic-goldman-sachs-ai-model-accounting.html
2•myk-e•38m ago•5 comments

Ai.com bought by Crypto.com founder for $70M in biggest-ever website name deal

https://www.ft.com/content/83488628-8dfd-4060-a7b0-71b1bb012785
1•1vuio0pswjnm7•39m ago•1 comments

Big Tech's AI Push Is Costing More Than the Moon Landing

https://www.wsj.com/tech/ai/ai-spending-tech-companies-compared-02b90046
4•1vuio0pswjnm7•41m ago•0 comments

The AI boom is causing shortages everywhere else

https://www.washingtonpost.com/technology/2026/02/07/ai-spending-economy-shortages/
2•1vuio0pswjnm7•43m ago•0 comments

Suno, AI Music, and the Bad Future [video]

https://www.youtube.com/watch?v=U8dcFhF0Dlk
1•askl•44m ago•2 comments

Ask HN: How are researchers using AlphaFold in 2026?

1•jocho12•47m ago•0 comments

Running the "Reflections on Trusting Trust" Compiler

https://spawn-queue.acm.org/doi/10.1145/3786614
1•devooops•52m ago•0 comments

Watermark API – $0.01/image, 10x cheaper than Cloudinary

https://api-production-caa8.up.railway.app/docs
1•lembergs•54m ago•1 comments

Now send your marketing campaigns directly from ChatGPT

https://www.mail-o-mail.com/
1•avallark•57m ago•1 comments

Queueing Theory v2: DORA metrics, queue-of-queues, chi-alpha-beta-sigma notation

https://github.com/joelparkerhenderson/queueing-theory
1•jph•1h ago•0 comments

Show HN: Hibana – choreography-first protocol safety for Rust

https://hibanaworks.dev/
5•o8vm•1h ago•1 comments

Haniri: A live autonomous world where AI agents survive or collapse

https://www.haniri.com
1•donangrey•1h ago•1 comments

GPT-5.3-Codex System Card [pdf]

https://cdn.openai.com/pdf/23eca107-a9b1-4d2c-b156-7deb4fbc697c/GPT-5-3-Codex-System-Card-02.pdf
1•tosh•1h ago•0 comments

Atlas: Manage your database schema as code

https://github.com/ariga/atlas
1•quectophoton•1h ago•0 comments

Geist Pixel

https://vercel.com/blog/introducing-geist-pixel
2•helloplanets•1h ago•0 comments

Show HN: MCP to get latest dependency package and tool versions

https://github.com/MShekow/package-version-check-mcp
1•mshekow•1h ago•0 comments

The better you get at something, the harder it becomes to do

https://seekingtrust.substack.com/p/improving-at-writing-made-me-almost
2•FinnLobsien•1h ago•0 comments

Show HN: WP Float – Archive WordPress blogs to free static hosting

https://wpfloat.netlify.app/
1•zizoulegrande•1h ago•0 comments
Open in hackernews

Working pipe operator today in pure JavaScript

https://github.com/irony/aspipes
261•urvader•4mo ago

Comments

koito17•4mo ago
Since this library leverages Symbol.toPrimitive, you may also use operators besides bitwise-OR. Additionally, the library does not seem to dispatch on the `hint` parameter[0]. Now I want to open a JS REPL, try placing this library's pipe object into string template literals, and see what happens.

Overall, cool library.

[0] https://tc39.es/ecma262/multipage/abstract-operations.html#s...

bryanrasmussen•4mo ago
what are your ideas regarding the pipe object in string template literals? I'm just looking for an overview to see if it sparks some ideas.
bckr•4mo ago
Very appealing.
stephenlf•4mo ago
Cool work!
c249709•4mo ago
this is sick
tinyspacewizard•4mo ago
Sad that the pipe operator proposal seems to have stalled.

The F# version of the proposal was probably the simplest choice.

pavlov•4mo ago
Further proof that JavaScript accidentally became the new C++.

“Aren’t you surprised that this syntax works?” is not praise for a language design.

asah•4mo ago
Agreed!!!!

Serious q: but how does this sentiment change with LLMs? They can pickup new syntax pretty fast, then use fewer tokens...

fph•4mo ago
I imagine the error messages must be terrible to read, since this hack is based on reusing syntax that was meant for something entirely different.
Cthulhu_•4mo ago
It sounds like using less tokens (or, less output due to a more compact syntax) is like a micro-optimization; code should be written for readability, not for compactness. That said, there are some really compact programming languages out there if this is what you need to optimize for.
pavlov•4mo ago
I’ve heard it said before on HN that this is not true in general because more tokens in familiar patterns helps the model understand what it’s doing (vs. very terse and novel syntax).

Otherwise LLMs would excel at writing APL and similar languages, but seems like that’s not the case.

throwawaymaths•4mo ago
probably because there arent enough apl examples to imbue the rare weird apl tokens with sufficient semantic meaning to be useful.
miningape•4mo ago
IMO it's more likely to get confused because there are less unique tokens to differentiate between syntax (e.x. pipe when we want bitwise-or or vice-versa)
rco8786•4mo ago
Is there a language that can’t be contorted in surprising ways that I’m unaware of?
IshKebab•4mo ago
Probably not, but there are definitely languages that don't do automatic type coercion - so at least one fewer contortion available.
bobbylarrybobby•4mo ago
LISP — the contortions are expected, not surprises
kazinator•4mo ago
Non-Lisp: gratuitous contortions are expected.
dominicrose•4mo ago
A language where there's only one way to do things, maybe a very early version of CSS. The things is all languages end up bloated with new features.
dymk•4mo ago
I think that depends on the person, the language, and how familiar they are with the language. Someone's "what the fuck" is another's "obviously it can do that".
cluckindan•4mo ago
Reminder that Perl exists:

https://metacpan.org/dist/perlsecret/view/lib/perlsecret.pod...

refulgentis•4mo ago
Swift, IMHO. Grew up on ObjC and the absolutely crazy things you could pull off dynamically at runtime. You can definitely feel they did not want that in Swift. There's operator overriding but idk if I'd count that as contorting in surprising ways shrugs
cluckindan•4mo ago
It is not a surprise that overriding the implementation of an operator’s type coercion works and overrides the behavior of the operator’s type coercion.
pavlov•4mo ago
Do you really think that most JavaScript users are aware that “overriding the implementation of an operator’s type coercion” is a language feature?

Sure, you can claim that everyone should know this obscure feature when they don’t. But that’s how this language enters C++ territory.

catapart•4mo ago
I actually don't think you are wrong, but I'm not backing that up with any actual data.

I happened to know it because of how the hyperHTML micro-library works; the author went into great detail about it and a ton of other topics. But my gut would say that the average js dev doesn't know about it.

But then... it's useful for creating component frameworks which... most js devs use. Which doesn't mean they know how they work under the hood. But... a lot of devs I've met specifically choose a framework because of how it works under the hood.

... so... I really have no idea how many people know this. I'm still betting it's less than average.

cluckindan•4mo ago
Well, Proxy objects do allow you to override the behavior of any property, including Symbol properties. Symbol.iterator is pretty widely used to create custom iterable objects, so I would expect curious devs to have taken a look at what else can be done through the use of Symbol properties.
overgard•4mo ago
No way dude, this does a disservice to the insanity that is C++'s syntax. Wake me up when you have 6 different initialization syntaxes or fun things like 4[array]
jonny_eh•4mo ago
> “Aren’t you surprised that this syntax works?” is not praise for a language design.

It's a clever hack. This is Hacker News. Let's try to appreciate clever hacks while here.

ricardobeat•4mo ago
Nothing new. This was 15 years ago:

https://github.com/tbtlr/def.js

goobert•4mo ago
Nice! I love it when a language introduces new syntax for things that weren't remotely difficult in the first place!
Ciantic•4mo ago
First example doesn't work though:

    const greeting = pipe('hello')
       | upper
       | ex('!!!')

    await greeting.run() // → "HELLO!!!"
If you look at the tests file, it needs to be written like this to make it work:

    let greeting;
    (greeting = pipe('hello')) | upper | ex('!!!');
    await greeting.run();
Which is not anymore as ergonomic.
byteknight•4mo ago
Seems similar to the problem encountered when making the stupid idea PyNQ:

https://github.com/IAmStoxe/PyNQ

md224•4mo ago
I suspect this was written with an LLM and the author didn't actually verify that the examples in the README worked.
dymk•4mo ago
Recently, I ripped usage examples out of a rust project's README.md, and put them in doc comments. Almost all of them were broken due to small changes over time, and I never remembered to update the readme. `cargo test` runs doc comments like mini integration tests, so now the examples never rot. I wish more languages and tools had this feature.

It means having to go to the linked docs (which are automatically pushed to the repo's github pages) to see examples, but I think this is a reasonable tradeoff.

Thom2000•4mo ago
FWIW it's possible to run readme examples automatically add part of tests: https://github.com/parallaxsecond/rust-cryptoki/blob/main/cr...
urvader•4mo ago
I wrote this with an LLM but manually changed the README. Thanks for pointing this out, it is now updated.
nticompass•4mo ago
I was playing with it, and you can do this, which looks a little better.

    const greeting = pipe('hello');
    greeting | upper | ex('!!!');
    await greeting.run(); // → "HELLO!!!"
Since it uses the "Symbol.toPrimitive" method, you can use any operator (not just "bitwise OR" (|)).

    const greeting = pipe('hello');
    greeting / upper * ex('!!!');
    await greeting.run(); // → "HELLO!!!"
urvader•4mo ago
Thanks for pointing this out, I updated the examples now to this syntax.
hinkley•4mo ago
That’s not better because it implies these are all destructive function calls.

Mutating your inputs is not functional programming. And pipes are effectively compact list comprehensions. Comprehensions without FP is Frankensteinian.

hinkley•4mo ago
That is a big enough DX problem that I would veto using this on a project.

You’ve implied what I’ll state clearly:

Pipes are for composing transformations, one per line, so that reading comprehension doesn’t nosedive too fast with accumulation of subsequent operations.

Chaining on the same line is shit for readying and worst for git merges and PR reviews.

sproutini•4mo ago
Overengineered in my view, what is wrong with `x | f` is `f(x)`? Then `x | f | g` can be read as `g(f(x))` and you're done. I don't see any reason to make it more complicated than that.
xigoi•4mo ago
You can’t make it work like that in current JavaScript.
flanked-evergl•4mo ago
It would be nice to have well-maintained fluent/pipe/streaming API solution for Python.
reverseblade2•4mo ago
Alternatively just use F# and Fable
jappgar•4mo ago
is this solving a problem people actually have?

other libraries like rxjs use .pipe(f,g,h) which works just fine.

whizzter•4mo ago
Fully agreed, var-arg functions are well established in JS so no need to abuse operators for these kinds of things.
whizzter•4mo ago
This kind of stuff is why C++ developers has an almost overly allergic reaction to operator overloading.
jagged-chisel•4mo ago
C++ is the reason people have that reaction. The quintessential example in introductory texts for operator overloading is using bit-shift operators to output text. I mean, come on - if that’s your example, don’t complain when people follow suit and get it wrong.
whizzter•4mo ago
C++ has std::format these days that does a far more sane thing, people are too quick to throw out the baby with the bathwater when it comes to bad things.

Some OO is fine, just don't make your architecture or language entirely dependent on it. Same with operator overloading.

When it comes to math heavy workloads, you really want a language that supports operator overloading (or have a language full of heavy vector primitives), doing it all without just becomes painful for other reasons.

Yes, the early C++ _STDLIB_ was shit early on due to boneheaded architectural and syntactic decisions (and memory safety issues is another whole chapter), but that doesn't take away that the language is a damn powerful and useful one.

zamadatix•4mo ago
std::format in C++20 is just for the string manipulation half but you still left shift cout by the resulting string to output text in canonical C++.

C++23 introduced std::print(), which is more or less the modernized printf() C++ probably should have started with and also includes the functionality of std::format(). Unfortunately, it'll be another 10 years before I can actually use it outside of home projects... but at least it's there now!

1718627440•4mo ago
While that operator is also used for bit-shift, it is not the bit-shift operator. It's not that the bit-shift operator is used for stream direction, it's that the same operator is used for both stream direction and bit-shifts. And which code is operating on both high-level abstract streams and bit-shifts at the same time.
cluckindan•4mo ago
This isn’t overloading the operator, it is replacing the implementation of type coercion when | is used with pipe() or asPipe() objects.

| itself still works exactly as before.

whizzter•4mo ago
Oh wait, looked at the source again, so it's some weird stateful collection thing triggered by the type coercion? By now I'm wishing that it was operator overloading.
cluckindan•4mo ago
Imagine the possibilities for control flow obfuscation when this trick is used with parentheses wrapping a part of the pipeline. :-)
keepamovin•4mo ago
Damn, that’s really clever. I love seeing these expressive explorations of JavaScript syntax.
keepamovin•4mo ago
Damn, that’s really clever. I love seeing these expressive explorations of JavaScript syntax.
gregabbott•4mo ago
In case it might interest anyone, I wrote a similar vanilla JS function last year called Chute. Chute chains methods and function calls using dot-notation.

https://github.com/gregabbott/chute

suspended_state•4mo ago
That's Point-free style programming.

https://en.wikipedia.org/wiki/Tacit_programming

xixixao•4mo ago
Won’t work in TS.

I would actually love extension of TS with operator overloading for vector maths (games, other linear algebra, ML use cases). I wouldn’t want libraries to rely on it, but in my own application code, it can sometimes be really helpful.

CharlieDigital•4mo ago
Check out C#. CliWrap does exactly this: https://github.com/Tyrrrz/CliWrap/blob/master/CliWrap/Comman...

    // Examples
    var cmd = Cli.Wrap("foo") | (stdOut, stdErr);

    var target = PipeTarget.Merge(
        PipeTarget.ToFile("file1.txt"),
        PipeTarget.ToFile("file2.txt"),
        PipeTarget.ToFile("file3.txt")
    );

    var cmd = Cli.Wrap("foo") | target;
juliend2•4mo ago
This cargo seem to give magical superpowers.
MathMonkeyMan•4mo ago
Neat, but I think that functions already do what we need.

For one thing, the example isn't the most compelling, because you can:

    const greeting = 'hello'.toUpperCase() + '!!!';
or

    const greeting = 'HELLO!!!';
That said, there is already:

    function thrush(initial, ...funcs) {
        return funcs.reduce(
            (current, func) => func(current),
            initial);
    }

    const greeting = thrush('hello', s => s.toUpperCase(), s => s + '!!!');
nonethewiser•4mo ago
Are any of the cases compelling? Thinking of the actual proposal. It creates some new magic with |> and % just for syntactic sugar.
accrual•4mo ago
I am all for clean syntax but I feel like JS has already reached a nice middle ground between expressiveness (especially w/ map/reduce/filter) and readability. I'd personally rather not have another syntax that everyone will have to learn unless we're already moving to a new language.
nonethewiser•4mo ago
I agree but to steelman it, what about custom functions? I think just doing it naively is perfectly fine. Or if you want use some pipe utility. Or wrap the array, string, etc. with your own custom methods.
IshKebab•4mo ago
I think JS's map/reduce/filter design is one of the worst ones out there actually - map has footguns with its extra arguments and everything gets converted to an array at the drop of a hat. Still, pipeline syntax probably won't help fix any of that.
eyelidlessness•4mo ago
> everything gets converted to an array at the drop of a hat

Can you name an example? IME the opposite is a more common complaint: needing to explicitly convert values to arrays from many common APIs which return eg iterables/iterators.

IshKebab•4mo ago
`map` returns an array and can only be called on an array.
eyelidlessness•4mo ago
Right, but I’m not clear on what gets converted to an array. Do you mean more or less what I said in my previous comment? That it requires you (your code, or calling code in general) to perform that conversion excessively?
recursive•4mo ago
People write a lot of stuff like [...iterable].map(fn). They do it so much it's as if they do it each time a hat drops.
eyelidlessness•4mo ago
Thank you for clarifying. (I think?)

I think what confused me is the passive language: "everything gets converted" sounds (to me) like the runtime or some aspect of language semantics is converting everything, rather than developers. Whereas this is the same complaint I mentioned.

Timwi•4mo ago
One gripe I have is that the result of map/filter is always an array. As a result, doing `foo.map(...).filter(...).slice(0, 3)` will run the map and the filter on the entire array even if it has hundreds of entries and I only need the first 10 to find the 3 that match the filter.
thdhhghgbhy•4mo ago
I always thought JS map filter reduce felt quite nice, especially playing around with data in the REPL. Java maps with all the conversions back and forth to streams are clumsy.
Timwi•4mo ago
Well in JS you have to convert to arrays instead. You can't do `document.querySelectorAll(...).map(...)`.
thdhhghgbhy•4mo ago
That's the DOM API, it's not part of the language! They had reasons for querySelectorAll not returning an array.
rco8786•4mo ago
Whatever that thrush thing is feels 10x more gross than the pipe
svieira•4mo ago
Thrush is the "T combinator" - I believe that the "Thrush" name comes from To Mock a Mockingbird by Raymond Smullyan [1].

[1]: https://www.amazon.com/Mock-Mockingbird-Other-Logic-Puzzles/...

[2]: https://en.wikipedia.org/wiki/Combinatory_logic#In_computing

[3]: https://leanpub.com/combinators/read#leanpub-auto-the-thrush

flexagoon•4mo ago
Not if you consider that the linked repo requires you to use asPipe on all functions first. So it's this:

  const greeting = thrush(
    'hello',
    s => s.toUpperCase(),
    s => s + '!!!'
  );
Vs this:

  const upper = asPipe(s => s.toUpperCase())
  const ex = asPipe((s) => s + '!!!')
  const greeting = pipe('hello')
    | upper
    | ex
  await greeting.run()
(And that doesn't work in reality, as the top comment here notes)
fergie•4mo ago
Pipes are great in environments where "everything is a string" (bash, etc), but do we really need them in javascript? I have yet to see a compelling example.
tinyspacewizard•4mo ago
Pipes are great where you want to chain several operations together. Piping is very common in statically typed functional langauges, where there are lots of different types in play.

Sequences are a common example.

So this:

    xs.map(x => x * 2).filter(x => x > 4).sorted().take(5)
In pipes this might look like:

    xs |> map(x => x * 2) |> filter(x => x > 4) |> sorted() |> take(5)
In functional languages (of the ML variety), convention is to put each operation on its own line:

    xs 
    |> map(x => x * 2) 
    |> filter(x => x > 4) 
    |> sorted() 
    |> take(5)
Note this makes for really nice diffs with the standard Git diff tool!

But why is this better?

Well, suppose the operation you want is not implemented as a method on `xs`. For a long time JavaScript did not offer `flatMap` on arrays.

You'll need to add it somehow, such as on the prototype (nasty) or by wrapping `xs` in another type (overhead, verbose).

With the pipe operator, each operation is just a plain-ol function.

This:

    xs |> f
Is syntactic sugar for:

    f(xs)
This allows us to "extend" `xs` in a manner that can be compiled with zero run-time overhead.
discomrobertul8•4mo ago
if the language or std lib already allows for chaining then pipes aren't as attractive. They're a much nicer alternative when the other answer is nested function calls.

e.g.

So this:

    take(sorted(filter(map(xs, x => x \* 2), x => x > 4)), 5)
To your example:

    xs |> map(x => x \* 2) |> filter(x => x > 4) |> sorted() |> take(5)
is a marked improvement to me. Much easier to read the order of operations and which args belong to which call.
nonethewiser•4mo ago
First of all, with the actual proposal, wouldnt it actually be like this? with the %.

    xs
      |> map(%, x => x * 2)
      |> filter(%, x => x > 4)
      |> sorted(%)
      |> take(%, 5);
Anything that can currently just chain functions seems like a terrible example because this is perfectly fine:

    xs.map(x => x * 2)
        .filter(x => x > 4)
        .sorted()
        .take(5)
Not just fine but much better. No new operators required and less verbose. Just strictly better. This ignores the fact that sorted and take are not actually array methods, but there are equivalent.

But besides that, I think the better steelman would use methods that dont already exist on the prototype. You can still make it work by adding it to the prototype but... meh. Not that I even liket he proposal in that case.

tinyspacewizard•4mo ago
There is more than one proposal; the F#-style one doesn't have the (weird) placeholder syntax.

> You can still make it work by adding it to the prototype

This is exactly what we want to avoid!

nonethewiser•4mo ago
wrap the object?

Why would you want to avoid that? It's controversial syntactic sugar. Enforcing a convention locally seems ideal.

tinyspacewizard•4mo ago
1. Wrapping is more code than using a built-in pipe operator

2. There is a run-time overhead to wrapping

IMO a design goal of programming langauges should be for the most readable code to also be the most performant.

Language features tend to be controversial until they are mainstream.

nymalt•4mo ago
That's clever! But I still want JS to get the actual pipeline operator.
bonquesha99•4mo ago
If you're interested in the Ruby language too, check out this PoC gem for an "operator-less" syntax for pipe operations using regular blocks/expressions like every other Ruby DSL.

https://github.com/lendinghome/pipe_operator#-pipe_operator

  "https://api.github.com/repos/ruby/ruby".pipe do
    URI.parse
    Net::HTTP.get
    JSON.parse.fetch("stargazers_count")
    yield_self { |n| "Ruby has #{n} stars" }
    Kernel.puts
  end
  #=> Ruby has 15120 stars

  [9, 64].map(&Math.pipe.sqrt)           #=> [3.0, 8.0]
  [9, 64].map(&Math.pipe.sqrt.to_i.to_s) #=> ["3", "8"]
dominicrose•4mo ago
It's an interesting experiment but standard Ruby is expressive enough.

[9, 64].map { Math.sqrt(_1) } #=> [3.0, 8.0]

For the first example I would just define a method that uses local variables. They're local so it's not polluting context.

pwdisswordfishy•4mo ago

    new Proxy(function(){}, {
      get(_, prop) {
        if (prop === Symbol.toPrimitive)
          return () => ...
As opposed to, you know, just defining a method. Proxy has apparently become the new adding custom methods to built-in prototypes.
sethcalebweeks•4mo ago
I love the idea! The creativity of (ab)using JavaScript type coersion is really neat. I did something similar using proxies to create a chainable API.

https://dev.to/sethcalebweeks/fluent-api-for-piping-standalo...

  const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);
  const zipWith = (a, b, fn) => a.slice(0, Math.min(a.length, b.length)).map((x, i) => fn(x, b[i]));
  const log = (arr) => {
    console.log(arr);
    return arr;
  };

  const chain = chainWith({shuffle, zipWith, log});

  chain([1, 2, 3, 4, 5, 6, 7, 8, 9])
    .map((i) => i + 10)
    .log() // [ 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
    .shuffle()
    .log() // e.g. [ 16, 15, 11, 19, 12, 13, 18, 14, 17 ]
    .zipWith(["a", "b", "c", "d", "e"], (a, b) => a + b)
    .log() // e.g. [ '16a', '15b', '11c', '19d', '12e' ]
    [0]; // e.g. '16a'
gregabbott•4mo ago
In another comment, I mentioned a vanilla JavaScript function I published in 2024 called Chute. https://github.com/gregabbott/chute

In a similar way to the featured project, Chute also uses proxies to work like a pipeline operator. But like in your reply, Chute uses a dot-notation style to chain and send data through a mix of functions and methods.

You might like to see how Chute uses proxies, as it requires no `chainWith` or similar setup step before use. Without setup, Chute can send data through global or local, top-level or nested, native or custom, unary, curried or non-unary functions and methods. It gives non-unary functions the current data at a specific argument position by using a custom-nameable placeholder variable.

The Chute page describes some more of its features: https://gregabbott.pages.dev/chute/

rco8786•4mo ago
Very clever. Love seeing stuff like this that pushes the bounds
don_searchcraft•4mo ago
These TC39 proposals take way too long to get approved and implemented.
user____name•4mo ago
Is this intended for code golf or something? This buys you literally nothing and just makes the language needlessly cryptic.
ilaksh•4mo ago
See also https://livescript.net/
aprilnya•4mo ago
This is just different syntax for nesting function calls (i.e. c(b(a(value))) becomes value | a | b | c), right? Definitely would make code more readable if this was just something in JS or a compiler where it’s the same as normally calling functions.
urvader•4mo ago
I'm not sure this is at all a good idea but thanks to the great discussion here at Hacker News - it is now up on npm:

npm i aspipes

adamddev1•4mo ago
Now we just need 'do notation' for monads! :-)
mlajtos•4mo ago
Pipe "operator" for the rest of us:

    Object.prototype.pipe = function(fn) { return fn(this) }

    'hello'.pipe(upper).pipe(ex('!!!'))
Or code golf version:

    Object.prototype.P=function(...F){return F.reduce((v,f)=>f(v),this)}
    'hello'.P(upper,ex('!!!'))
taylorallred•4mo ago
Piping syntax is nice for reading, but it's hard to debug. There's no clear way to "step through" each stage of the pipe to see the intermediate results.
rokob•4mo ago
There is usually some variant of tee that lets you do that.
bitwize•4mo ago
It's simultaneously a miracle and deeply wrong that this worked.
tacone•4mo ago
I know that it's wrong but I love it.

I am wondering if it could be useful for libraries:

    grid.columns.name.format(v => v | trim | truncate | bold)
    form.fields.name.validate(v => v | trim | required | email)