The only major downside of significant indentation is that it makes it impossible to define multi-line anonymous functions in a clean way.
The only major downside of significant indentation is that it makes it impossible to define multi-line anonymous functions in a clean way.
This is maybe a bit far from the topic, but I would like to know why there is such a need for anonymous functions in Python.
I understand very well the need for stateless functions (functions that do not change anything else than their return value, have no side effect, except maybe logging), and I understood it was a piece of functional programming.
In Javascript, with silent overwriting of functions and without modules, it is obviously very bad to pollute the only namespace with function names that can clash with each other, but in Python, you are or should be always inside a relatively small scope, and there you can def _my_temp_func() without any problems, no?
Moreover, as it is lame to use _temp as function name, it forces you to formulate a meaningful function name, which is good pratice, especially for your lectorate, right?
Or am I missing something?
For example, in scheme:
> (define (foo x) (lambda (y) (+ x y)))
> (define bar (foo 10))
> (bar 5)
15
This sort of thing is of course immensely useful. >>> def foo(x):
... def add(y):
... return x + y
... return add
...
>>> bar = foo(10)
>>> bar(5)
15bar = foo(10)
This is perfectly correct Python code too if you prefer. The only real thing with Python's lambdas is that, because Python makes a distinction between statements and expressions, you can't easily do things like use temporary variables inside a lambda, but cases like that are rare and are typically more readable with a separate standalone function definition anyway.
x = [{1: 'b', 2: 'a'}, {1:'a', 2:'b'}]
You want to sort it on the value at the "2" key. You could write a dummy function: def extract_2(dct):
return dct[2]
x.sort(key=extract_2)
Or, you could just use a quick lambda: x.sort(key=lambda dct: dct[2])
The latter is more terse, and to a functional programmer, more clear (YMMV, of course). Lambda is just syntactic sugar in python; it's not necessary, and a lot of places where a functional programmer uses it in python make more sense as list comprehensions, but I think it's a nice thing to have.EDIT:
I think the biggest reason I prefer the lambda approach to the named-function approach is that I don't like seeing one-off functions defined first and then seeing them used later. If python could do this:
x.sort(key=extract_2)
def extract_2(dct):
return dct[2]
or even somehow support ruby-style blocks, it wouldn't be so ugly to my eye. Python lets functions call functions that are defined below them at the module level, but not at the function level, so the above isn't valid in the scope of a function.Building new control structures in-language, without having to hack the interpreter, and without the result looking like somebody has puked all over your screen. First-class functions are under-used in Python because they're syntactically and semantically heavy. With full anonymous functions, the `with` statement would not have been needed, it could have been handled through a higher-order function, akin to Haskell's `bracket`[0]
> In Javascript, with silent overwriting of functions and without modules, it is obviously very bad to pollute the only namespace with function names that can clash with each other
Namespace pollution is completely irrelevant (it's very easy to handle it in Javascript via the namespace pattern).
> Moreover, as it is lame to use _temp as function name, it forces you to formulate a meaningful function name, which is good pratice, especially for your lectorate, right?
If it is, why can I put name-less blocks of code in `for`, `if`, `while` and `with` bodies?
Not all code blocks need a name. Those that do will be given one.
[0] http://hackage.haskell.org/packages/archive/base/latest/doc/...
That's really besides my point. And last time I checked, Haskell's `if` and `case` expressions did not take functions, they took anonymous expressions.
> So with the bracket function, for example, it's still considered better practice to pass named functions to it.
To pass a named function as third argument to bracket?
I think part of my initial dislike for Python was manually typing nested indentation, even with one space the level for class->def->for->if can get annoying to type. I used to use EditPad Lite that didn't have auto-indent. Everything got better once I learned vim.
Regarding multi-line lambdas in Python, you can do it more or less but like you said it's not clean and can be dangerous.
a = [1]
blah = lambda x: eval(compile('''
print x
a.append(x)
''', '', 'exec'))I'm not convinced that multi-statement anonymous functions are a good idea.
def go : this.some_other_method : here_is_my_block
?