This is kind of a follow-up to / re-asking of "Should point-free function expressions be allowed when a function is asked for?" with specific reference to the only language I know how to golf in, j, where the issue is a little bit pernicious and involved. (Note that there was no final consensus in that meta.PPCG question, so it is technically still open for debate!)
I don't know how to ask this in general without being exceedingly abstract, nor do I have examples in any other languages, but hopefully it's clear enough how this applies to other languages where there are parentheses for modifying evaluation order or operator precedence/associativity.
A little bit of background, for the non-J folk. The J language has an interesting syntax, arguably the main reason it is reasonably competitive against golflangs, called verb trains: to pretend to be more like a functional language, you can jam verbs (AKA functions) together without any extra syntax, and instead of throwing an error, J will compose them in a useful, nontrivial way.
More concretely, suppose
f
andg
are one-argument functions. Then you can write(f + g)
to mean a function such that(f + g) y
is the same as(f y) + (g y)
. (Think of the sum of two functions, from first-year calculus.) To oversimplify, any odd-length train of verbs does this kind of thing, in a right-associative manner, and we can put any two-argument function we want instead of+
. (There is a version of this for even-length trains, too, but that's irrelevant.)So here's the issue. If your answer to a code golf question is
(f+g)
, then do you have to include the parens? You don't have to wrap it in parens to name the function, but you do to use it anonymously, since it is not a syntax error to omit the parens:answer =: f+g answer 42 NB. this works as intended (f+g) 42 NB. this works as intended f+g 42 NB. this is equivalent to f (+ (g 42)) which is different!
But it gets weirder. For convenience, the
f
above can be a noun (AKA datatype like array or integer or string) and J will automatically upgrade it to a constant function. So e.g.(2 + g) y
is equivalent to2 + (g y)
. But now if your submission to the golf is2+g
, then all three examples above will act identically (most of the time). I should note that, having knowledge of the J interpreter, I can say it is reading and evaluating the expression differently in the third case.And if you want an example of this mattering in a real golf, I came across one just today! If parens are required then my 20 byte solution is (probably) the best possible in J; but if they can be omitted, then my alternative solution is shorter, weighing in at 19 bytes, and ties the current best answer, which is in a golflang.
- A big argument for not wrapping in parens is that, when you give an expression, you implicitly assume it will be evaluated as-is, not in some context that can possibly change what is meant.
- A big argument for requiring parens, on the other hand, is that it is only unambiguous when in parens—in J in particular, effectively the only time you can ever omit the parens from a train is when making a simple definition like
answer =: f+g
.- One odd possibility that I personally believe is unacceptable is that, if we require parens, then omitting them in a submission means that answer is invoking the effects of the intentionally unparenthesized code.
- A third option, entertained in the meta.PPCG question I linked earlier, might be to require that you add the characters necessary to name the function literal. This is unfair for languages like J and R, though, where the assignment operator is longer than one character, so counting the parens would cost less!
This is code golf, however, and there are (at least) 2 bytes at stake here, so there should be some discussion. I tend to err on the side of caution and count the parens in my submissions, but I think by now I've seen this happen enough times to warrant another look. Like I said, the old meta.PPCG question did not come to a consensus, even in the comments.