7
\$\begingroup\$

I've come across the following answer in a challenge in Haskell, where one has to provide a function:

<bindings>
<expression>

Now, the last line on its own is a curried expression and as such eligible. However, without the previous definitions, it won't work and results in an error. For example, the following code defines the list of Fibonacci numbers (f) and provides an expression to get the n-th Fibonacci number:

f=0:1:zipWith(+)f(tail f)
(f!!)

This isn't valid Haskell, since top-level splices/annotations/expressions in a .hs file are only possible with TemplateHaskell (and it won't work if you use -XTemplateHaskell, since that's not a valid use of TH either). It also cannot get streamed into GHCi or other interpreters with

cat File.hs | interpreter`

since you need let to create bindings:

ghci> let f=0:1:zipWith(+)f(tail f)

The only way to create a single expression from this would be let … in, which takes up to 7 additional bytes

let f=0:1:zipWith(+)f(tail f)in(f!!)

which can be used as anonymous function (2), but that seems an overkill to a binding, which takes just two additional bytes:

f=0:1:zipWith(+)f(tail f)
g=(f!!)

Question

Is the invalid code invalid? Or are we allowed to introduce syntax/semantic errors and dump some of the work (properly bind, change syntax, or similar) to the user?

Personal remarks

Given that answers should provide working code that just needs to get loaded/executed, I think that answers of this kind are invalid. The code cannot get loaded in Hugs/GHCi with :l and it cannot get executed with runhaskell, ghc -e or similar.

However, I think that can lead to many Haskell answers needing two additional bytes.

Note that this isn't a duplicate of Unnamed Functions in Code Golf, since that question considers only syntactically valid code. One can have a expression at top-level in Python. It's an error in Haskell.

\$\endgroup\$
16
  • \$\begingroup\$ Related. \$\endgroup\$
    – Zgarb
    Jul 15, 2016 at 10:59
  • \$\begingroup\$ Also related. \$\endgroup\$
    – Zgarb
    Jul 15, 2016 at 11:32
  • \$\begingroup\$ @Zgarb: The essence of both answers is that the code should evaluate to a (unnamed) function, or define a named one. This is fine in some languages. However, in Haskell, such code will lead to a parser/syntax error (unless you take the measurements described above), which is why I'm asking about syntactically correct code. By the way, sorry for forgetting to notify you in the other answer. \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 11:44
  • \$\begingroup\$ Seems pretty simple: the answer works when run with Template Haskell, or not at all \$\endgroup\$
    – cat
    Jul 15, 2016 at 15:12
  • \$\begingroup\$ @cat: Err, no. It doesn't work with TemplateHaskell. TemplateHaskell only allows you to use top-level splices to create new code. Also, the code that's used to create that splice must be imported. I'll add that. \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 15:16
  • 1
    \$\begingroup\$ @Mego: I don't think so. The incorrect code does not create an unnamed function in Haskell, it creates non-working code. It's another story in Python, though. \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 18:32
  • 1
    \$\begingroup\$ @Zeta: Of course this is of general interest and not specific to Haskell, but the code of the linked Haskell answer works if you split it: A file with the helper functions (# and t), let's say f.hs and then call it like ghc -e '(filter t[1..]!!) 54' f.hs. This even saves a byte, because you can omit one newline. \$\endgroup\$
    – nimi
    Jul 15, 2016 at 19:16
  • 4
    \$\begingroup\$ @Mego I don't think it's a dupe because this is talking about a much more specific (and gray) area where unnamed functions create a syntax error. \$\endgroup\$
    – DJMcMayhem
    Jul 15, 2016 at 19:33
  • 1
    \$\begingroup\$ @DrGreenEggsandIronMan My answer on that question answers this question perfectly - if it doesn't evaluate to a function that can be captured, it's not valid. \$\endgroup\$
    – user45941
    Jul 15, 2016 at 19:52
  • \$\begingroup\$ @nimi: Splitting the code is probably a standard loophole. After all, ghc -e '' still has to be written somewhere. But that's for another question. \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 19:57
  • 1
    \$\begingroup\$ @Zeta: yes, ghc -e '' has to be written, but that's for free, just like perl -e '' for Perl. After all we provide functions as answers, not the boilerplate to call them. \$\endgroup\$
    – nimi
    Jul 15, 2016 at 20:01
  • \$\begingroup\$ @Mego: Your point "Any expression which evaluates to a (named or unnamed) function is acceptable" can be wrought into a strange argument for expressions. If you really meant it that way (that all the code must evaluate to an expression), you should probably add that the overall code must be syntactically correct, not only sub-expressions with helpers. E.g., in this case the last line does evaluate to a function, but the overall syntax is incorrect. Yes, this is nit-picky, but better fix that misunderstanding? \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 20:02
  • \$\begingroup\$ @nimi: In this case, the actual answer should probably get also visually split, e.g. consist of two different code blocks, which would be perfectly reasonable. \$\endgroup\$
    – Zeta
    Jul 15, 2016 at 20:03
  • \$\begingroup\$ @Zeta If it's not syntactically valid, it doesn't evaluate to anything. There's no ambiguity here. \$\endgroup\$
    – user45941
    Jul 15, 2016 at 20:06
  • 3
    \$\begingroup\$ @Zeta You confuse "syntactically correct" with "can compile or run the code as it is". This is explicitly not required in codegolf, as e.g. functions are allowed by default. You also cannot compile public static void main(String[]args){System.out.println("Hello, World");} in Java, but it still is a valid code-golf submission and it is in fact syntactically correct. \$\endgroup\$
    – flawr
    Jul 17, 2016 at 12:35

0

Browse other questions tagged .