@cfry Doing two arguments is just changing how many arguments you pop off the stack and replacing the [route bang float] after the command receive to [route bang list]. So a loop command could be made like this (untested and not even fully thought through):

I used [value] because add works off the last value that was output and [value] keeps things neater than tying lots of stuff to a single [float]. In this case you don't need to use [v $0val] to get the output for val, it just stores the float for add, same, and any other command you want to use it for, sending the float to both [v $0val] and [s $0out] is exactly what I would do in this case. I don't think $0-same will work as you expect, there is no need to pop for that and out is getting a bang instead of a float, just need to do [route bang] -> [v $0val] -> [s $0out].
Your comments look to be correct. [r $0stack] is used for the trace but it is useful for other things, you can have a print command which just bangs the message [send $0print( to [s $0stack( and then a [r $0print] connected to a [print] so you can check the stack's condition in those cases when things did not work as planned and you did not have the trace on. Notice the send message is to $0print and not $0-print, receives with the $0 hyphen prefix are only for commands and you will get into trouble if you use that prefix for non-commands. In this case we send the print to $0print instead of $0-print because if the stack is empty it would output a bang which would bang the message again and send you into an infinite loop. Remember to save before testing new commands, it is easy to miss an obvious loop like this.
We prepend to stack instead of append because that means we always get to do [delete 0 $1(, if we appended we would have to keep track of stack size and then subtract how many to delete so we can do a [delete $1 $2(, just more efficient to do it this way in pd land. There is a bit of a flaw here as well, think about what happens if you run the line 1 2 3
, one is pushed, then two, then three, so three is top of the stack and the contents of the stack is reversed as 3 2 1
, as it should be, the issues is if we have a command which pushes more than one value onto the stack. If you had the command which just bangs the message [1 2 3( to [s $0push] you would have one as top of the stack instead of three so in commands you need to send your lists backwards. Slightly annoying and could be fixed but would be less efficient, so I just remember that when patching commands which push a list, the list needs to be backwards or it will cause confusion elsewhere.
I will do another post later tonight or tomorrow going into the rest and elaborating on a few things.
Edit: Suppose that loop command only works for looping to a point earlier in the program, which is probably workable but perhaps not ideal. We will deal with that in the next post and start really exploiting that this is a programming language and will save you work as any programming language should. Trying not to dump too much on you all at once, next post will be a big one. Or maybe you are already ahead of me? can't quite tell.
Edit2: No, that loop will not quite work, for got to resend the float to $0-goto on each iteration, only loops once.