For me the only problem with the `x=x` default argument "fix" is that.
. . well, it's in the argument signature. That means it effectively
becomes part of the function's public API, and people can pass in other
values, which maybe you don't want. Plus it just seems very unclean to
me to have to shoehorn "I want to capture these variables from the
enclosing scope at definition time" into the mechanism for "these are
the arguments you can pass at call time". What we really want is a way
to separate these into orthogonal choices.
But do we? The key to language design is to have as few features as you can that can be combined in as many ways as they can. *That* is what I consider orthogonality (of features). Using argument defaults for a novel purpose scores high according to this, while dedicated syntax as you show below (def f(a, b, c) with x, y: ...) scores low -- it's a new feature that can do only one thing.
OTOH if we were to introduce 'let' or 'const' in the language, it would surely be usable to solve a whole bunch of other problems, in addition to giving us a cleaner way to solve the value capture problem.