Well that's because Sage has a preparser. You could as well say that because f(a) = 2 is invalid Python code, so should it be invalid Sage code, regardless of whether it's a function definition or not.
This, on the other hand, is perfectly valid Python:
>>> def f(x):
... a = 1
... def f(a):
... return a
... return f(x)
...
>>> f(2)
2
>>>
Your invalid Python above is invalid not because of the semantics of redefining f within f, but just the fact that vanilla Python doesn't have the "f(x) = foo" symbolic 'function' definition syntax Sage does.
If there's anything wrong with defining symbolic functions inside other functions it's this, IMO:
sage: a
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/home/fs/src/ipython/<ipython console> in <module>()
NameError: name 'a' is not defined
sage: def f(x):
....: p(a) = 3
....: return "foo"
....:
sage: f(2)
'foo'
sage: a
a
sage:
-Keshav
----
Join us in #sagemath on
irc.freenode.net !