> How about Haskell's notion of fixity of the symbols/operators/names?
Every language has implicit fixity and precedence for infix operators. What's different about Haskell is that you can actually define infix operators yourself. And if you're going to define your own you need to be able to also define the precedence of your operators. Fixity has always been there. You just didn't realize it.
>>Every language has implicit fixity and precedence for infix operators. What's different about Haskell is that you can actually define infix operators yourself.
It seems I didn't make my point clearer. I am asking what is the semantic benefit for the programmer of the explicit fixity and ability to change fixity at one's will?
The whole notion of explicit fixity in Haskell exists because of Haskell's fetish (pardon me using this term again) for symbols instead of functions-names with fixed implicit fixity. They needed to support explicit fixity only because they wanted the programmers to be able to define operator symbols arbitrary with arbitrary fixities.
So, now when you wish to read someone's code, then other than dealing with the inherent complexity present in their code, you also have to deal with the intentionally inflicted accidental complexity (to paraphrase Fred Brooks) over there because of their choice of using symbols with arbitrary fixities. [1]
IMHO, Haskell adds to accidental complexity in this way instead of curtailing it just to satisfy their urge on usage of arbitrary symbols.
Let me explain it a bit further: to read someone's code, first I have to see what symbols they have defined and what fixity they have ascribed to each of those. Now I have to keep all that additional unnecessary cognitive load in my brain to just be able to get a hang of their code with their fixity rules associated with their symbols.
Why does any programming language have infix operators? Because they make some things easier to read. Fixity and precedence are not accidental complexity. They are the essential complexity of having infix operators. In order to evaluate "3 * 4 ^ 3 ^ 2 / 4 / 2 + 5 * 8" you must define the fixity and precedence of the operators involved. You don't usually have to think about defining these things in most mainstream languages because the language defines the fixity and precedence of those operators for you to give the behavior you expect. You still have to learn it though. Do you know how Python evaluates the above expression? (Change the carets to double stars...HN didn't render double star properly.) In my first programming class long before Haskell was created, the textbook had a C operator precedence chart. The concept is not new to Haskell. Haskell has just given you control over something that has been there the whole time.
Haskell lets you make your own infix operators so that you can get the same benefits in other domains than the ones that the language designers decided to provide for you. Therefore it follows that Haskell also needs to allow you to specify the fixity and precedence so that your operators will fit together in the way that is appropriate for your domain.
> Let me explain it a bit further: to read someone's code, first I have to see what symbols they have defined and what fixity they have ascribed to each of those. Now I have to keep all that additional unnecessary cognitive load in my brain to just be able to get a hang of their code with their fixity rules associated with their symbols.
The same is true of C, Java, Python, etc. The only difference is that those languages have a closed set of operators while Haskell's is open. There is a small amount of cognitive overhead, but I think you're greatly exaggerating it. In six and a half years of professional Haskell development I can count on one hand the number of times this has been an issue. And it can be trivially resolved by adding parentheses or by decomposing the expression into separate expressions.
> Therefore it follows that Haskell also needs to allow you to specify the fixity and precedence so that your operators will fit together in the way that is appropriate for your domain.
This is the key point. Operators drawn from my target domain probably already have well established fixities. Forcing my expressions to look radically different than what's in the textbooks and papers discussing the domain in which I'm working is itself introducing incidental complexity.
Every language has implicit fixity and precedence for infix operators. What's different about Haskell is that you can actually define infix operators yourself. And if you're going to define your own you need to be able to also define the precedence of your operators. Fixity has always been there. You just didn't realize it.