# How to CASCADE a function-stored-in-a-variable-that-has-multiple-arguments

There are three ways to use a function with CASCADE:
CASCADE is a function from the "Iteration, composition" library. It repeatedly applies a function, first to a specified initial value, and to the result of the previous step from then on - in other words: if the function is f(x), then CASCADE (3) TIMES ( f) (x) (#) means: f ( f ( f (x))), with “#” being an upvar that at any time during the cascade signifies the present “round” (which can be used as an argument of the function).

1. as a regular function, e.g.: , with

2. as an anonymous function, e.g.:

3. as a variable, e.g.: .

But what if the function has multiple arguments? E.g. two-way addition:
the # upvar is 1 at the first round, and 2 at the second round. 1st: 3 + 1 = 4; 2nd: 4 + 2 = 6

1. as a regular function: , with

2. as an anonymous function:

3. as a variable: - take note of the CALL block in this final example; it won’t work without CALL !

This topic was originally phrased as a request for help regarding the final example; while I was writing it I found the solution, and decided to make it a mini-Tutorial.

I have a few quibbles.

In both of the numbered lists, I don't understand the word "as" at the beginning of each item. It seems to be suggesting that you can choose to use any function in any of the three ways, but I think what you really mean is that you can use named functions from the palette, you can use a ringed (anonymous) reporter, or you can use a reporter that's the value of a variable. I think the one about variables isn't like the other two because they're about what counts as a function, whereas the third one is about where you put the function, and isn't general enough. For example, you can put a function in a list, as in the project Open > Examples > vee:

and therefore you can put an (unringed) ITEM block in that second input to CASCADE. My point isn't that you should add a fourth list item for ITEM! You could write a custom block that reports a function, like this:

Note that the MAKE ADDER block is unringified in the CASCADE input slot! That's very important. You're not calling the function MAKE ADDER three times; you're calling the function MAKE ADDER before CASCADE runs, and the cascaded function is the one MAKE ADDER reports, which in this case is basically

So you don't want a zillion special cases in a list; what you want to say is that as always in Snap! any expression can go in any input slot as long as it provides an input that the calling function understands.

For multi-input functions, you don't explicitly say that the expression you provide should generally fill all but one hole, so
No
Yes
No

But sometimes you do have more than one empty slot, in which case the old value goes into all the open slots.

Also you don't explain what the # upvar means, so your examples are unclear.

And finally, you should also explain

not forgetting my favorite example:

actually i did this after reading the initial post wondering what that is.

i still dont get it lmao

For a function f(x), calling cascade(3) is the equivalent of f(f(f(x))). It also has an upVar for the last round and allows you to set an initial value for x.

that is much better explanation, thanks

I actually did mean to suggest any function may be used in any of these ways (a list item is just a variable within this context). Though perhaps your interpretation of “function” is more rigid than mine. From my perspective (1) and (2) are the same function, as both have the same definition - admittedly this may be somewhat different in case of a primitive function one doesn’t know the definition of.
What took me some time to find out is how to get arguments other than the seed, or the result of the previous iteration, fed into the function (in case 3). I tried stuff like

, and various other expressions I don’t all remember, until finally arriving at the solution.

BTW one reason for my sometimes wanting to use a variable-as-function is that I prefer to have all related code in a single script (for maintaining an overview), while keeping the main code simple.

Thx, I’ll add that to my OP.

I’ll leave that to you

Even in pig latin, letters aren’t jumbled, nor is -ay an ending. Perhaps you meant something like: LINGVA PROGRAMMANDI SCHEMAE ?Oops, I confused it with dog latin.

Ah. Technically, they are the same function, because for the same input they give the same output. But they're not the same procedure, because their definitions are different. The second one calls a primtive with one of its inputs filled in; the first one is a custom block that calls the first one. My usual example is this:

F and G are the same function, but different procedures. But I guess I don't think the different procedures in your example are very interesting, because there are infinitely many possible procedures to compute this function:

and so on.

F is a function of two inputs. This ringed expression is a function of one input that calls F. Doesn't that work? You don't put F(X,Y) in a ring because the value of that variable is the function you want to call, so you have to evaluate the variable to get the function.

Hmm, this leads me to suspect that you're still not getting #. It represents the number of invocations so far of the function. See if this helps:

If # meant the result so far, it'd be the same as an empty slot.

Oh wait, are you thinking that the # at the end of the line is an expression dragged into a second Any-type input slot in CASCADE?

Or am I not understanding what you're thinking?

I used this function (+1) as a simple example, so as for readers of my post to focus on the real issue: how to specify a callback-function-that-is-stored-in-a-variable-and-has-multiple-arguments (I’d like something less verbose, but that would probably be less precise) when calling CASCADE. So IMO this discussion about the +1 function is a bit off-topic.

Yes, I see now. CALL (variable) W/INPUTS ()() is itself a wrapper function that calls the function stored in the variable.

My initial confusion was caused by the fact that one can simply specify the variable containing F as a callback if F expects merely a single argument, like with:

Of course it wouldn’t harm to use