Yes.. and no. There *is* a memoization decorator, called CachedFunction (or cached_function), and it can be applied easily:

```
sage: @CachedFunction
....: def f(x):
....: print 'slow call..'
....: sleep(5)
....: return x**2
....:
sage: f(10)
slow call..
100
sage: f(10)
100
```

(Or, equally, `g = cached_function(f)`

or `h = CachedFunction(f)`

.)

Unfortunately you can still blow the recursion stack:

```
sage: @CachedFunction
....: def r(x):
....: return 1 if x<= 1 else 1+r(x-1)
....:
sage: r(20)
20
sage: r(2000)
[...]
RuntimeError: maximum recursion depth exceeded while calling a Python object
```

CPython doesn't do tail-recursion optimization, so writing recursive functions isn't as natural. If you're interested, there are some ways around this but I wouldn't recommend them for production use..