Arc Forumnew | comments | leaders | submitlogin
2 points by zck 3395 days ago | link | parent

> gcd a + b c - (square d)

> In this example, the + and - look like punctuation separating the phrases "gdc a", "b c", and "(square d)", and it takes me a moment to realize "b c" isn't a meaningful expression.

Agreed. This is possibly my main complaint with mixing infix syntax with prefix syntax.

> gcd (a + b) (c - square d) (* ML ) (gcd ((+) a b) ((-) c (square d))) ( ML again *)

This is the same in Haskell^1. But I really dislike how this is done. It conflates calling a function (by surrounding it in parentheses) with converting an infix function to prefix. And if the function is unfamiliar, you don't know which it is. I assume this is taken care of by the parser, so it's into the arbitrariness of syntax, not the clear standard of function application^2.

[1] I assume Haskell got it from ML.

[2] This is unless you assume some insane return type that's basically "if called infix with two arguments, return a number; if called with zero arguments, return a prefix function of two arguments that returns a number".



2 points by rocketnia 3395 days ago | link

"I assume Haskell got it from ML."

I think so. I'm primarily familiar with Haskell, but I hope those examples at least work in SML too.

A lot of the syntactic similarity starts to break down once the examples include lambdas, pattern matching, and top-level declarations, but I think that's similar to how the similarity between Lisp dialects breaks down when we look closely enough.

---

"It conflates calling a function (by surrounding it in parentheses) with converting an infix function to prefix."

I was making it look similar to Lisp syntax for the sake of argument, but parentheses aren't actually used like Lisp function calls there. In that example, parentheses are just used for two purposes:

- Grouping.

- Referring to infix variables (+) without applying them, which would otherwise be impossible to do.

The syntax for function application is juxtaposition with left associativity, so "gcd a b" is grouped as "(gcd a) b".

Agda[1] and some notes on Epigram 2[2] track "spines" of elimination contexts for the purposes of type inference and implicit argument elaboration. I think Haskell might use spines to resolve type class instances as well. In that case, the meaning of gcd in ((gcd a) b) can depend on the types known for a and b. With this kind of trick, Haskell's instance resolution can supposedly be used to write what are effectively varargs functions[3].

[1] http://www2.tcs.ifi.lmu.de/~abel/talkIHP14.pdf

[2] http://mazzo.li/epilogue/index.html%3Fp=1079.html

[3] https://wiki.haskell.org/Varargs

-----