I discovered that a lot of "special forms" are just macros that use their asterisks version in the background (fn*, let* and all the others).
In case of fn, for example, it adds the destructuring capability into the mix which fn* alone does not provide. I tried to find some detailed documentation of what fn* can and can't do on its own, but I was not so lucky.
It definitely supports:
the &/catchall indicator
(fn* [x & rest] (do-smth-here...))
and curiously also the overloading on arity, as in:
(fn* ([x] (smth-with-one-arg ...) ([x y] (smth-with-two-args ...))
So my question finally is, why not only define:
(fn& [& all-args] ...)
which would be absolutely minimal and could provide all the arity selection via macros (checking size of parameter list, if/case statement to direct code path, bind first few parameters to desired symbol, etc..).
Is this for performance reasons? Maybe someone even has a link to the actual standard definition of the asterisks special forms handy.