Why'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.
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.
Every 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.
I 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.
The 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 . 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.
Yeah. 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.