Arc Forumnew | comments | leaders | submit | dehrenberg's commentslogin
1 point by dehrenberg 3397 days ago | link | parent | on: Infix support in wart

I really like this syntax. Getting rid of precedence is definitely good. (You can also go right-associative like K, which has its small advantages.) To me, the most interesting part is the way you make whitespace significant. It's a great idea that I haven't heard before. It could be tempting to make that more intricate, but that's probably more trouble than it's worth in practice.


1 point by akkartik 3397 days ago | link

Hi Dan! Thanks! Yeah I tried counting spaces like we do for python indent, but that's probably not worth the trouble.

I can't take credit for the whitespace idea. rocketnia pointed out that a project called merd first came up with it (

And yes I considered going right-associative. In fact, I originally meant to make it right-associative, but ended up showing my C roots :) I might still revisit this decision. Can you point me at right-associativity's advantages?


1 point by dehrenberg 3397 days ago | link

APL and K are right-associative.


2 points by rocketnia 3392 days ago | link

A good reason to make something right-associative is if it takes a Foo and a Bar and gives you a Bar in return. In this case, left-associative grouping would only lead to type errors.

Taking a look at Haskell's right-associative operators, the cons operator (:) seems to follow that rule, and others seem to take into account other idiosyncrasies. Here are my guesses for each operator:

Exponentiation to the power of a natural number (a ^ b ^ c), an integer (a ^^ b ^^ c), or a float (a b c) is right-associative, probably to match the parentheses-less math notation: (a (b c)).

The function type constructor (a -> b -> result) is right-associative (a -> (b -> result)) so that it's easy to use multi-parameter curried functions. For the same reason, function currying/application (func a b) is left-associative ((func a) b).

Low-precedence function application (a $ b $ c) is right-associative. This might be because (a b c) tends to be sufficient for passing the usual curried parameters, so (a $ b $ c) is reserved for cases where the output of each ($) isn't another function to apply. If this is true, ($) usually takes a function and a non-function and returns a non-function, so it's naturally right-associative.

Haskell has a few other right-associative operators out of the box, but I'm not sure why. In some cases, maybe it helps with perfomance.