Hacker News new | ask | show | jobs
by GuuD 1259 days ago
This is fantastically written documentation. What is even more exciting for me, that this is almost exactly what I was dreaming and talking non-stop about for the last few years. I never figured out the brilliant insight about redundancy of operator precedence. On the more embarrassing note in numerous implementation not-quite-attempts I always ended up gutting loops as a feature in favor of recursion and went with effects for capabilities (among other things). Then I was usually caught off guard by either of those or my other darling — partial application interacting in unexpected way (only for me probably) with linear types, which always punched me back to square one. Extremely impressed with how sound and grounded in reality your choices are. Fantastic job.
1 comments

> I never figured out the brilliant insight about redundancy of operator precedence

As many things go, the Smalltalk designers had this insight a few decades ago, all "binary messages" have the same precedence.

I still think it's weird, but it makes sense.

Fuck, I mean… yeah. Thanks for one more insight, by showing me that sending message/calling a method is a binary operation, seems so obvious but I never made that connection. This day started by shelling by Russian rockets, but reading the post and your comment somehow made it… good? I always get caught off-guard by how much baby we’ve thrown with the water with modern languages compared to some brilliancy we had in Lisp and Smalltalk. Both are extremely out of my cup of tea region, but I learn so much when I interact with them. The only thing JS and something like Java taught me is to stay away:)
> Thanks for one more insight, by showing me that sending message/calling a method is a binary operation

The other way around.

A "binary message" is specifically the message of binary operators. Smalltalk also has unary messages (named messages with no parameters), and keyword messages (non-binary messages with parameters).

Its precedence rules are unary > binary > keyword, and left to right.

So

    foo bar - baz / qux quux: corge
binds as

    (((foo bar) - baz) / qux) qux: quux
You can still get into sticky situations, mostly thanks to the cascading operator ";":

    a b; c
sends the message following ";" to the receiver of the message preceding ";". So here it's equivalent to

    a b.
    a c
now consider:

    foo + bar qux; quux
This is equivalent to

    foo + bar qux.
    foo quux
Because the message which precedes the ";" is actually "+", whose receiver is "foo":

    foo + (bar qux); quux
All Smalltalk history talks mention that APL was a major influence, and it didn't have operator precedence either. In addition, the Smalltalk-72 scheme of "parse as you go" would make implementing precedence really awkward.

Smalltalk-76 introduced a fixed syntax and does have a bit of precedence: unary > binary > keywords. All binary messages have the same priority, which given that you can define new ones avoids a lot of complexity at the cost of a few extra parenthesis.