If you think about it is more efficient for ++. So X ++ Y ++ Z will evaluate faster, less copying, if it is interpreted as X ++ ( Y ++ Z ) than if it interpreted as ( X ++ Y ) ++ Z. Hence it is right associative. -- was just given the same to try and be a little consistent.
Actually -- came later. It was a bit of a joke actually: if we have ++ couldn’t we have -- and ** and // as well? I couldn’t come up with something sensible for lists for ** and //. It also took a while to work out the semantics.