I have been using functions for Zsh submissions for some time. I typically submit the body alone, as the body can be run as a full program with no modification: afunction arg1 arg2
vs ./aprogram arg1 arg2
. If recursion is needed, $0
can be used.
I saw this recent challenge, which is a purely mathematical one. Now Zsh has a math mode and allows math functions which work fairly different from normal functions:
Normal function:
f(){ # define function
echo "Hello $1"
}
f world! # call
s=$(f world!) # call and capture stdout
Math function:
f(){ # define function
(( ($1 * $2)**0.5 ))
}
functions -M f # define mathfn f, bind it to the function of the same name
functions -M g 2 2 f # OR define mathfn g which takes min:2, max:2 args
# and bind it to the shell function f
(( k = f(4,9) )) # call and capture
Math function, but in zcalc
(a math-mode REPL provided in Zsh):
:f f ($1*$2)**0.5 # bind (this defines a function named zsh_math_func_f and binds the mathfn f to it)
f(4,9) # call
k = f(4,9) # call and capture
How can/should the above math function be scored?
(0) ((($1*$2)**0.5))
: This is the body of the function.
(1) ()((($1*$2)**0.5))
: This creates an anonymous function, executed immediately and discarded
(2) f()((($1*$2)**0.5))
: This is sufficient to bind the body to a shell function, but it hasn't been bound to a mathfn
(3) f()((($1*$2)**0.5));functions -M f
(4) ($1*$2)**0.5
with language as "Zsh zcalc REPL"?
(5) :f f ($1*$2)**0.5
with language as "Zsh zcalc REPL"?
Looking at previous discussions both specific and general, I am unsure how this "double binding" of the function should be accounted for, and how it affects re-usability.
EDIT: The logic in question in Zsh's source
Given a valid MathFunc f
, if it is bound to a Shfunc shfunc
, it will doshfunc(shfunc, l, 1)
and return lastmathval
. So the value computed by the last arithmetic expression in the function determines the output of the math function. I wrote my conclusions as an answer. I will consider votes as consensus.
P
in REPL (print) \$\endgroup\$f
in this way, zcalc can even be exited and the function persists. \$\endgroup\$