Ok, lets look at the ast
the lambda function generates:
import ast
tree = ast.parse('lambda S,b : (g(S[1:],b),S)[len(S)==b]')
ast.dump(tree)
After some formatting done in vim this is what I got:
Module(
[Expr(
Lambda(
arguments(
[Name('S', Param()), Name('b', Param())],
None,
None,
[]
),
Subscript(
Tuple(
[Call(
Name('g', Load()),
[Subscript(Name('S', Load()), Slice(Num(1), None, None), Load()), Name('b', Load())],
[],
None,
None
),
Name('S', Load())
],
Load()
),
Index(
Compare(
Call(Name('len', Load()), [Name('S', Load())], [], None, None),
[Eq()],
[Name('b', Load())]
)
),
Load()
)
)
)]
)
As you may see, the first thing this code executes when calls the lambda is the tuple creation and after that, comes directly the recursive call (Call(Name('g'...
) to the same lambda.
Calling is the first thing getting done and since the slicing of an empty list is still the empty list:
>>>[1][1:]
[]
>>>[][1:]
[]
This means that g(S[1:])
will reduce your list until the empty list and then continue endlessly calling g
with the empty list. This happens because the way the parser execute the statements. The first thing that's executed is the recursive method call, so it won't stop.
My point: base case is not working on the recursion.
Hope this bring more light to the subject.