Here is my ungolfed Ruby code for a function I want to try and golf:
Iter =-> k {
str = ""
(0..k).map{|m| str += "-> f#{m} {"}
str += "f#{k}.times{f1 = f0[f1]};f1"
(2..k).map{|m| str += "[f#{m}]"}
eval(str + "}" * (k+1))
}
The best I can do to golf this is essentially shortening variable names, removing spaces, and rearranging the code to reduce the amount of loops:
I=->k{s="f#{k}.times{f1=f0[f1]};f1"
(2..k).map{|m|s+="[f#{m}]"}
(0..k).map{|m|s="->f#{k-m}{"+s+?}}
eval s}
This function can be compacted so that it avoids a lot of defining new functions. You can think of it like this:
$$\operatorname{Iter}(k;f_0,f_1,\dots,f_k)=f_0^{f_k}(f_1)(f_2)(f_3)\dots(f_k)$$
where
$$f^n(x)=\underbrace{f(f(\dots f(}_nx)\dots))$$
denotes function iteration. The types of arguments are given as:
$$\operatorname{Iter}(\text{int};\dots,(\text{int}\mapsto\text{int})\mapsto(\text{int}\mapsto\text{int}),\text{int}\mapsto\text{int},\text{int})$$
That is, the last argument is an integer, and each previous argument maps from T to T, where T is the type of the next argument on the right.
It is true that accepting all arguments at once would allow me to golf the above code further:
I=->k,*a{a[-1].times{a[1]=a[0][a[1]]};(2..k).map{|m|a[1]=a[1][a[m]]};a[1]}
However, the issue is that I need to curry this function. This way, I may treat objects such as
$$\operatorname{Iter}(k)(f_0)$$
as their own object, and thus be able to pass this into Iter(k) to get things such as
$$\operatorname{Iter}(k)(\operatorname{Iter}(k)(f_0))$$
As a specific example of what this function does, we have
\begin{align}\operatorname{Iter}(2)(\operatorname{Iter}(1))(x\mapsto x+1)(2)&=\operatorname{Iter}(1)(\operatorname{Iter}(1)(x\mapsto x+1))(2)\\&=\operatorname{Iter}(1)(x\mapsto x+1)(\operatorname{Iter}(1)(x\mapsto x+1)(2))\\&=\operatorname{Iter}(1)(x\mapsto x+1)(2+1+1)\\&=\operatorname{Iter}(1)(x\mapsto x+1)(4)\\&=4+1+1+1+1\\&=8\end{align}
I'm interested in seeing if this can be golfed down further, with the restriction that the arguments must be curried in the order provided.
>:
is the increment function, and your exampleI[2][I[1]][->x{x+1}][2]
can be written>:^:2^:3 (2)
. Try it online!.^:
is the power of conjunction, and iteratively applies the verb on its left the number of times specified by the number on its right, with 1 being normal applicationf(x)
, 2 beingf(f(x)
, etc. \$\endgroup\$