Re. 2: That's true. In general, it would mean you could only define names with =, not objects in general. The other option would be to leave = as is and change def to have PLT-esque behavior, but then we're away from the whole "reducing the number of operators" idea. (And whether (def f (args) ....) or (def (f args) ... is better is is kind of a religious debate, though my religion favors the second as more closely resembling how f is actually used later on.)
Re. 4: It might be zap, if you could write something like ((zap f) x y z) or (zap f x y z), instead of (= x (f x y z)). In fact, though, (f! x y z) is equivalent to (zap [f _ y z] x), and f! alone is equivalent to
(fn args (= (car args) (apply f args))). (I couldn't think of a more concise expression using zap.) I think I'd much rather pass f! than (fn args (= (car args) (apply f args))) as an argument.
Actually, I might be mistaken, and I don't have the code (or my own machine) in front of me at the moment. Can you write (zap f x y z) right now?
After testing it, I find that (zap f x y z) does in fact act as (= x (f x y z)). And, if implicit currying is added as per someone else's suggestion, (zap f) will act as (fn args (= (car args) (apply f args))). So that works, then.