arc> (help get)
[fn] (get i)
Returns a function to pass 'i' to its input.
Useful in higher-order functions, or to index into lists, strings, tables, etc.
Examples:
arc> (get.2 '(1 2 3 4))
3
arc> (get!b (obj a 10 b 20))
20
arc> (get.9 sqrt)
3
arc> (map get.2
'((a b c)
(1 2 3)
(p q r)))
(c 3 r)
nil
arc> (help set)
[mac] (set . args)
Sets each place in 'args' to t.
nil
These are the functions you end up calling because your dispatch can't see the earlier get and set bindings.
The macro definition of with creates a function with all the names as inputs and the body of the with as the body of the function. The newly created function is called with the definitions of each name, which are effectively in independent namespaces.
The withs definition, however; recursively calls itself so that each succeeding name sees the definitions of previous names.
I believe the difference is historically due to higher speed of with. In modern programming it probably makes sense to use withs everywhere and only change to with in places where optimization is necessary.
I actually tend to the opposite: use with everywhere unless I need withs. The reason isn't performance. It tends to make code more elegant to not rely on the order in which things are defined. And when I'm reading code, with gives me the warm fuzzies that the code is going to be cleaner. When I see withs I slow down to look at the dependencies between the bindings.
Similarly to this, when I'm writing Java, I use `final`^1 everywhere I can. It's nice to be able to know that anywhere later where the variable declared final is in scope, it will have the same value as at the point it's set. I don't need to look through any code to see if it's rebound; I know it hasn't been.
[1] "final" is kind of like "const", if I understand `const` right. `final int x = 3;` means that it is an error to later have the line of code `x = 4;`.