3 ms·
I don't understand this. You can just define a function anywhere in python and use it (in local scope). I do this all the time, and it's a lot more clear than a
by philipn 12y ago
I don't understand this. You can just define a function anywhere in python and use it (in local scope). I do this all the time, and it's a lot more clear than an unnamed lambda function. What's the use case here?
- anaphor 12y agoPart of the reason why functional languages like Scheme have anonymous functions (lambdas) is so that you can encode various language features in them. function definition: (define (f x) (+ x x)) => (define f (lambda (x) (+ x x))) variable binding: (let ((x 1) (y 2)) (+ x y)) => ((lambda (x y) (+ x y)) 1 2) delayed evaluation: (delay (display "foo")) => (lambda () (display "foo")) and lots more... But they also sometimes are convenient when you have a function or procedure that expects the same as one of its parameters, but said function doesn't already exist, and there isn't a simple composition of higher-order (functions that take or return functions) functions that does what you want. For example, say you wanted to multiply a list of numbers by their squares (this is in Racket): (define (sqrmult n) (foldr (lambda (x y) (* (sqr x) (sqr y))) 1 (stream->list (in-range 1 n)))) See you don't have to name the function?
- stdbrouw 12y agoIt's nice for chaining. E.g. in CoffeeScript: list .map (el) -> el * 2 .filter (el) -> el % 2 == 0 I suppose in this case a list comprehension would work too: list = [el * 2 for el in list if el % 2 == 0] ... but as these things get more complex, inline functions become really useful. It's also nice for various DSL purposes, e.g. unit tests with Mocha it 'should be able to multiply a number', -> a = 2 b = 3 (product a, b).should.eql 6 Which in Python would become def test(): a = 2 b = 3 assert product(a, b) == 6 it('should be able to multiply a number', test) Probably doesn't look that impressive, but once you're used to them from other languages, it gets to be really frustrating to not have them in Python. You also start noticing that Python has a couple of features that are actually entirely unnecessary if only you'd have multiline inline functions. For example, you could do away with decorators and `with` blocks. view = authenticate (req, res) -> res.send 'hello world'
- jerf 12y ago"Which in Python would become ... assert product(a, b) == 6" Python's got a lot more capacity for "DSLs" than it may immediately seem. Writing "it.shouldBeEqual(product(2, 3))(6)" would be quite easy in Python, actually; it's got all sorts of overloads and you can return all sorts of excitingly overloaded values. You don't see it because it isn't considered "Pythonic", not because Python can't do that. (And I'm with Python on this. Those "fluent" APIs spend way too much effort being cutesy and verbose and not enough effort being simple, transparent, and composable. It looks good in the common case but when you write good test code it stops looking so good when you're writing map(it.shouldBe.eq, testTable), and the fact that the cutesy "fluent" style takes even a baby step in the direction of discouraging anything like that is an immediate disqualification in my book. Oh, don't try to defend it by saying you can still do the map I said... I've got enough experience in such things myself to know that it's actually a bigger problem than I'm making it out to be, not a smaller one.)
- stdbrouw 12y agoKind of besides the point though -- that line in particular had nothing to do with blocks/inline functions.
- euank 12y agoPromises show a good use case. It's common to have many promise-laden bits of code and it's clear that the first callback is success, second, error, and third progress. Having to do "def promise1_success" ... "def promise1_error" ... etc all the way up through 5 promises is a pain. For event-emitter like things, it's also great to have anonymous functions. For example, in nodejs, you might have reader.on('data', function(chunk) {}); .... You gain no further insight into what that function does if you have "def handle_reader_data" and then use it once there. There are many cases where you don't need the function name for clarify, and it just clutters the current scope to have it not be anonymous. Code is also easier to follow if functions like that, used once only as a callback, are immediately defined where they are used, not lines above. When reading code that has a named function above, I'd have to skim the function the first time, see it used, and then trace back through it above knowing what was calling it.