Let me also throw in my two cents about different workarounds.

How is a simple one-line lambda different from a normal function? I can think only of lack of assignments, some loop-like constructs (for, while), try-except clauses… And that’s it? We even have a ternary operator – cool! So, let’s try to deal with each of these problems.

### Assignments

Some guys here have rightly noted that we should take a look at lisp’s `let`

form, which allows local bindings. Actually, all the non state-changing assignments can be performed only with `let`

. But every lisp programmer knows that `let`

form is absolutely equivalent to call to a lambda function! This means that

```
(let ([x_ x] [y_ y])
(do-sth-with-x-&-y x_ y_))
```

is the same as

```
((lambda (x_ y_)
(do-sth-with-x-&-y x_ y_)) x y)
```

So lambdas are more than enough! Whenever we want to make a new assignment we just add another lambda and call it. Consider this example:

```
def f(x):
y = f1(x)
z = f2(x, y)
return y,z
```

A lambda version looks like:

```
f = lambda x: (lambda y: (y, f2(x,y)))(f1(x))
```

You can even make the `let`

function, if you don’t like the data being written after actions on the data. And you can even curry it (just for the sake of more parentheses ðŸ™‚ )

```
let = curry(lambda args, f: f(*args))
f_lmb = lambda x: let((f1(x),), lambda y: (y, f2(x,y)))
# or:
f_lmb = lambda x: let((f1(x),))(lambda y: (y, f2(x,y)))
# even better alternative:
let = lambda *args: lambda f: f(*args)
f_lmb = lambda x: let(f1(x))(lambda y: (y, f2(x,y)))
```

So far so good. But what if we have to make reassignments, i.e. change state? Well, I think we can live absolutely happily without changing state as long as task in question doesn’t concern loops.

### Loops

While there’s no direct lambda alternative for loops, I believe we can write quite generic function to fit our needs. Take a look at this fibonacci function:

```
def fib(n):
k = 0
fib_k, fib_k_plus_1 = 0, 1
while k < n:
k += 1
fib_k_plus_1, fib_k = fib_k_plus_1 + fib_k, fib_k_plus_1
return fib_k
```

Impossible in terms of lambdas, obviously. But after writing a little yet useful function we’re done with that and similar cases:

```
def loop(first_state, condition, state_changer):
state = first_state
while condition(*state):
state = state_changer(*state)
return state
fib_lmb = lambda n:\
loop(
(0,0,1),
lambda k, fib_k, fib_k_plus_1:\
k < n,
lambda k, fib_k, fib_k_plus_1:\
(k+1, fib_k_plus_1, fib_k_plus_1 + fib_k))[1]
```

And of course, one should always consider using `map`

, `reduce`

and other higher-order functions if possible.

### Try-except and other control structs

It seems like a general approach to this kind of problems is to make use of lazy evaluation, replacing code blocks with lambdas accepting no arguments:

```
def f(x):
try: return len(x)
except: return 0
# the same as:
def try_except_f(try_clause, except_clause):
try: return try_clause()
except: return except_clause()
f = lambda x: try_except_f(lambda: len(x), lambda: 0)
# f(-1) -> 0
# f([1,2,3]) -> 3
```

Of course, this is not a full alternative to try-except clause, but you can always make it more generic. Btw, with that approach you can even make `if`

behave like function!

Summing up: it’s only natural that everything mentioned feels kinda unnatural and not-so-pythonically-beautiful. Nonetheless – it works! And without any `evals`

and other trics, so all the intellisense will work. I’m also not claiming that you shoud use this everywhere. Most often you’d better define an ordinary function. I only showed that nothing is impossible.