Related: Are objects in Haskell valid if there is no input?
This answer prompted a question that I've wondered for a while so I could answer New users' guides to golfing rules in specific languages, which is what exactly constitutes a full program, function, and snippet in Mathematica (more accurately, the Wolfram Language).
In Mathematica, everything is an expression. There are atomic expressions like numbers, strings, images, etc., and there are compound expressions (not to be confused with CompoundExpression
) of the form f[x, y, ...]
, where f
, x
, y
, etc. are arbitrary expressions. For example consider the following program:
x = Input[];
x++;
Print[x]
This is just syntactic sugar for the following expression:
CompoundExpression[Set[x, Input[]], Increment[x], Print[x]]
In fact, the following would evaluate to True
:
Hold[x = Input[];
x++;
Print[x]] == Hold[CompoundExpression[Set[x, Input[]], Increment[x], Print[x]]]
All it means to run a Mathematica program is to evaluate it as an expression, and I guess you could say that the return value is whatever the expression evaluates to (not to be confused with Return
). Now any Mathematica expression could be used as the head of a compound expression, even the above program. So how does this relate to our definitions of full program or function?
The accepted answer to Full program in Clojure says that "A full program is anything that can be compiled/interpreted on its own, usually from a standalone file, using any pre-existing compiler/interpreter." Every (syntactically valid) Mathematica expression satisfies this (there is no boiler plate, just save the expression to a .wl
file an Get
it in Mathematica or run it from command line). Conversely, everything we would call a Mathematica program is an expression, so it seems full program = expression.
The accepted answer to What even is a “function” by our standards? says that a function "is a section of code, which can be directly inserted into a program with no modification, and should be able to be assigned/named/referred to in some way. It should be able to run independent of surrounding code. It should be able to take input/output in some form." Again, any Mathematica expression fits the bill. For example, we could do the following:
f := (x = Input[]; x++; Print[x])
Then we could pass in arguments as f[x, y, ...]
. In this example, the arguments would be ignored and the user would be prompted for input when the evaluator got to Input[]
, but that's not the point. There is absolutely no difference between which pieces of Mathematica code can be named, used as a function, passed as an argument, interpreted as a standalone program, etc. And this isn't just a quirk of the language, this is an essential part of the Mathematica paradigm.
Finally, what even is a snippet? I see references to "REPL snippets" (e.g. here), but the only formal definition I've seen is this answer, which seems more specific than how the term is commonly used. For example, the question that led to this post was whether $SystemWordLength
was a valid submission or if it was just a REPL snippet, which it doesn't seem to be.
So what exactly do these terms mean with respect to Mathematica?