Hacker News new | past | comments | ask | show | jobs | submit login

I think things get a little lost here when you start treating infix operators as special. When talking about creating uniform syntaxes, I think people don't look hard enough at the basic structure of SmallTalk, where operators work mostly like you'd expect, are infix, and are uniform with all other kinds of calls because the convention is always (subject verb object) instead of the lispy (verb object subject). You don't get operator precedence, but I've largely come around to the idea that maybe we should be questioning if it's something we actually need.

Of course that leaves you with the problem of when a verb lacks a subject.




Honestly, most of the time I think we would be better off without operator precedence. It just adds another thing you need to keep in your head when reading code.

Unfortunately, nearly everyone -- even non-programmers -- learned the operator precedence for arithmetic operators, which means they might be confused if those operators in a language didn't use it.


A limited hierarchy like Go's could be OK:

    parens (...)
    paths  . [] and args (x,y)
    unary  ! -
    binary * / &
    binary + - |
    binary == != <= >= < >
    binary &&
    binary ||
    comma  ,
    assign = += -= *= /= &= |= :=


SmallTalk does have some operator precedence: unary operators bind tightest, followed by binary, keyword, and assignment.

In general, what precedence buys you is that it lets you omit grouping brackets in situations where you would almost always have to write them. Consider assignment, for instance. Without operator precedence, you will often write "x := (y + z)", but you will almost never write "(x := y) + z". By giving := lower precedence than +, you can now omit the brackets 99% of the time.

This being said, I don't think operator precedence is particularly useful for arithmetic. It's deeply ingrained in expectations, though.


To clarify, I meant arithmetic operator precedence. Obviously there is still a grammatic precedence below that.


Sure, but the same principles that justify this grammatical precedence could be used to justify arithmetic precedence. I mean, why does assignment have lower priority? It could be left associative with arithmetic.

Presumably it has low priority because it never makes sense as a sub-expression, but you could use a similar argument to give lower priority to equality as compared to arithmetic, since you typically don't do arithmetic on the result of a logical operation.


I don't think they're really the same thing. Arithmetic precedence comes from the meaning of the operators themselves while the other layers of grammatical precedence simply provide consistent structure. The reason this is a problem when the operators can overload is that the structural aspects of the operators may no longer apply to their meaning. See for example the iostream operators << and >> in C++, which actually have a very awkward precedence that forces you to parenthesize things in unexpected ways sometimes.


Operators were first introduced in programming languages for arithmetic, .e.g. Fortran, but they've evolved beyond that. As an example, Scala gives precedence to operators based on the first token in the op, so e.g.

  *>> has higher precedence than +~< because * "beats" +
Golang treats

  * / and & as having the same precedence, and ditto with + - and |




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: