HN Companion◀︎ back | HN Companion home | new | best | ask | show | jobs
Yet another way to invoke functions without parentheses (blog.ikaes.de)
141 points by aragonite 2 days ago | 37 comments


This reminds me of "Creators admit Unix, C hoax" (e.g. https://www.gnu.org/fun/jokes/unix-hoax.html)

> We stopped when we got a clean compile on the following syntax:

    for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);

How Perl was created:

‘Larry, throw the cat at the keyboard!’

MEEEOW!

‘What did it type?’

‘&}Ak'>v=4%Qe}9;’

‘OK, so let’s make this a syntax for hello world.’


There was a hilarious video in The early days of YouTube when someone tried to write Perl using vistas voice recognition.

I haven't seen it in many many years, but at the time it struck my giggle button every time.




I did genuinely try to run this since, well, it could be true, I don't know Perl.

Bareword found where operator expected (Missing operator before "Ak"?) at -e line 1, near "&}Ak" Bad name after Ak' at -e line 1.


I want to put the called function after the arguments:

    (((x)f)g)h
So I can see exactly the order in which things happen, from left to right. As opposed to:

    f(g(h(x)))
where I have to read backwards.

Mathematica has a crazy amount of syntax abbreviations (https://reference.wolfram.com/language/guide/Syntax.html). Of course your whish is fulfilled there: x // f called the postfix operator.

The function reference is actually evaluated first so your preferred order is actually backwards! Consider this:

  foo.bar(x)
The `foo.bar` field has to be retrieved before the function can be called. It does not evaluate `x` first. That is observable with JS proxies, or you can test with code like this:

  foo()(bar())

Do you mean (((x)h)g)f ?

since the order in which things happen is "h first, then g, then f"


Did you even have an RPN-based calculator at school?

As to more serious programming languages, Erlang, F#, Haskell have forms of a "pipe" operator, roughly

  [1 2 3] |> sum |> print
For it to work properly, functions should be either functions of one argument, or support currying.

But the original algebra functions, as introduced by Leibniz in 17th century, were, of course, pure functions, more like properties than procedures. So cos(x), aka cos x, is just a formalized shorthand for "cosine of x", so it preserved the order of words typical for Germanic and Romance languages. Maybe if functions were introduced by the Japanese, we would have the reverse order, kind of x の cos.


This is why some languages have the | pipe syntax for chaining operations.

If `f` is an expression, that would require it to be evaluated last as well.

And that's why "purely procedural" languages don't make much sense to me

It's more natural to write

    x.h().g().f()

I love this. This is a fun hack, but the article also hearkens back to pre-LLM days when people were still interested in _code_.

I wonder if there was a period in the 90s where the chess community was more interested in talking about IBM’s stock price than in actually playing chess.

I'm definitely gonna use that for April 1st though, just adding this as instruction in Claude.md

That will also serves as a litmus test to check how many of my coworkers are reading the code they push.


Programmers are still interested in code

Weekend hobby!

Now there is Monday again, no more coding, back to babysitting agents.

Ah yeah, here we go…

“Back in my days…”

“No true Scotsman…”

“I remember when…”

“Kids these days…”

Gotta love this self-aggrandising humble-brag nonsensical stuff.


Off topic: This website looks like a ransom note

Maybe it is, just requires a different parser

Not gonna work on Firefox, since according to the doc, Error.prepareStackTrace is an optional API and only implemented by V8.

> optional API and only implemented by V8

aka "Chrome implemented this and wanted everyone else to do so as well"


  Object.prototype.message='alert\x281337\x29';Array.prototype.toString=Error.prototype.toString;Error.prepareStackTrace = Function;const x = new Error;x.valueOf=x.stack;+x;
Well, that's a mouthful! So many years and JavaScript still can do the most amazing, weird, awesome, scary, obscure, and sexy things in the world of coding.

The prototype thing is quite unique among mainstream languages. It is kind of simple in principle and works well for what it intends to do, but god it causes so much confusion and is frequently a source of CVEs. valueOf combined with implicit conversion is a nightmare for production code.

Yesterday I was re-using some shaders I had written a long time ago, and here's what I used to do multiline strings before the glorious backtick arrived on the scene...

    (function () {/*
      my awesome shader code
    */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]
... I can't call it sexy, but I also can't deny I felt a mixture of fear and arousal when I saw that.

Pretty interesting that you can carry comments over.

    (x=>/*this is a comment*/1) + 1
    "x=>/*this is a comment*/11"
I wonder if anything cool can be done with it today. It's probably useless.

TIL about [^], never seen that before. Apparently, it works like a dot but it also matches newlines.

Oh, me too. I’ve previously used [\s\S] for that.

JavaScript is so cursed.

If I were to write a book on programming in JS, it would be a black cover with the JS Holy Trinity equality diagram in red, to emphasize its Satanic nature.

Satanic? never assume malice where incompetence suffices

What's the purpose of the +x at the end?

The unary plus implicitly converts an expression to a number, which calls `valueOf` for non-primitive values.

I think to implicitly trigger the valueOf function.