The code
let a = {x: 1}; in abs a.x
gives ERROR: abs({x:1}): domain error. The reason is that abs a.x is actually interpreted as (abs a).x. Similarly (and contrary to what I claimed in #48!), f a[0] appears to be equivalent to (f a)[0] rather than f(a[0]), although this is often hard to notice because of Curv's array nature.
I find this behavior highly unintuitive. The main reason is that the syntax itself already suggests that a and x (being joined together by a period) are bound more closely than abs and a (being separated by a space). I have been bitten by this issue in many forms; indeed, almost every time I was confused about what some Curv code did the problem came down to precedence.
Another confusing example is
move cross(a, b) cube
which one might expect to translate a cube by the cross product of a and b (since in every mainstream programming language, a function call f(a,b) forms a syntactic unit). Instead, it gives an error, because it attempts to pass the function cross as the argument to move, so move (cross(a, b)) cube is needed instead.
Such (apparently) ambiguous precedence rules are typical of research-associated languages like Haskell and OCaml. I have always found such languages to be very difficult to parse mentally. Lisp is on the opposite end of the spectrum, where everything is bracketed so there is never any question about precedence, at the expense of increased verbosity. Scala shows a nice balance between the two extremes.
该提问来源于开源项目:curv3d/curv