4 ms·
> A few years back, one big lure of Python or Ruby used to be the functional constructs that they offered like higher order functions. This statement surprises
by dons 14y ago
> A few years back, one big lure of Python or Ruby used to be the functional constructs that they offered like higher order functions.
This statement surprises me.
- steveklabnik 14y agoWhy's that, dons? They are playing a bit fast and loose with what 'higher order functions' means, but, for example, one of Ruby's best features is blocks. The details of higher order stuff in Ruby is certainly... messy, but blocks are a great introduction to the concept for people who haven't used them before. I've taught the concept to high school kids on their first day of programming, (mostly through a physical metaphor involving a list of chores on a piece of paper) and they picked it up easily enough.
- dons 14y agoFair enough. I'd say they provide more of a flavor of "higher orderness" rather than a true implementation, as the semantics are so limited and ad hoc in Ruby.
- steveklabnik 14y agoSeems fair. I highly respect your opinion on the topic, and that makes a lot of sense. There's a reason that I moonlight Haskell and Rust. :)
- sixbrx 14y agoI can't speak of Ruby (or for Dons :), but I'm not sure Python's use of hof's is a good example to learn from when it's lambda scoping rules produce such "interesting" results. >>> monomials = [lambda x: x(star)(star)i for i in [1,2,3]] #(not sure how to escape stars for exponentiation properly, whatever) OK, what will these functions evaluate to at the point 2.0? >>> monomials[0](2.0), monomials[1](2.0), monomials[2](2.0) (8.0, 8.0, 8.0) The i variable was captured as an address which all the lambdas share. For an integer. Ouch. You can do "lambda x,i=i: x(star)(star)i" and capture the value properly, but to me this is a landmine waiting to be stumbled upon every time I write a lambda. I for one will often forget to do this, at least so long as I also keep using other languages which can capture integers as values without hijinks.
- steveklabnik 14y agoYeah. Makes sense. Ruby also has a few of these kinds of weirdness, especially around the multiple kinds of hof, (lambdas, Procs, and blocks) and their limited utility compared to a truly functional language.
- east2west 14y agoI wonder if anyone knows why subtlety exists in Python. Is it because reference semantics and HOF are fundamentally incompatible, or could it have been avoided somehow but still retaining reference semantics. The most common complain about lambda in Python is that it is restricted to expressions, which is a conscious design decision that could have gone the opposite direction.
- halter73 14y agoThe subtlety sixbrx mentions used to be present in C#, but it has been mostly fixed by moving the declaration of the foreach loop variable inside of the loop [1]. Like Python, C# has reference semantics. I'm surprised that Guido van Rossum didn't make a similar change when he broke backwards compatibility in Python 3. [1]http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closi...
- Peaker 14y agoLexical scopes capturing variables is more powerful than capturing values. If you want to capture values, that's easy too, with: lambda x, i=i: ...
- plorkyeran 14y agoEvery language with mutable variables and closures that I've used works the same way (other than ones like C++ where you have to explicitly capture by either reference or value). The behavior can be a bit confusing, but it makes perfect sense once you realize that closures are capturing variables, not values.