I don't know enough about HN to know why it doesn't display the two *'s that need to be be right after d.using(. I also couldn't figure out how to do keyword arguments in python where the key is a variable, not a constant, so if any python expert knows how, you could remove 4 characters from the above solution! :)
Yes, very cute and concise, and you know Python and I don't:) My point is to ask why to devote yourself to "rules" and optimizing conciseness of a trivial problem here. I don't think "readability" is a defense, because I believe my program (not being a Python programmer) is nearly completely free of guile, still fairly concise in terms of symbols, and instantly readable even to a new programmer.
It's interesting and revealing that you're not getting a good answer to your question. In these types of conversations, most of the back-and-forth is really just name-calling -- where the names are things like "readability" instead of "poopoohead" -- on top of statements of personal preference. It's easy for us to debate reduce vs. merge-with vs. foreach, but difficult to have a meaningful conversation about why we prefer what we prefer. I happen to have a few minutes between finishing my coffee and getting on with things, so here are some reflections.
A lot of people who are into FP simply find the concise style more satisfying. That's not regarded as a legitimate reason for preferring one choice over another, so this kind of discussion often hits a what-you-can't-say dead end. We've all seen too-clever code that was just awful, and we all keep saying that cleverness for its own sake is bad, and that position dominates the discussion in a heavyhanded way right now. Perhaps that's because it's necessary to keep the pseudo-clever crowd in check. I doubt it, though, because nothing keeps them in check.
Like it or not, the truth is that one factor driving what programmers do is intellectual satisfaction. This has always been and will always be the case, no matter how many schoolmistresses (most of them, of course, programmers trying to master their own temptations) beat us with the cane of "business value is the only thing that matters" and "no one cares about your stupid clever code".
(I'm by no means arguing that the impulse to make things "cute and concise" ought to take precedence or have free rein, but rather that this factor needs to have a seat at the table before we have a chance of working out a balanced approach.)
The mathematicians have one over on us here. In their world too, the most important thing is getting the job done, but elegance is a close runner-up: it's esteemed for its own sake, and more importantly it's well understood that there's an intimate dialectic between elegance and getting the job done. If we started thinking that way, we might finally make some progress out of these language game dead ends.
Switching gears to the technical matter of what the concise functional approach buys you (apart from elegance, for those who find it elegant), the trouble is that there's no way to answer this question at the level of a code snippet because all approaches yield reasonable snippets in intelligent hands. The real question is: what are the impacts of these varying approaches on building whole systems? That question, as far as I can tell, remains completely unaddressed! Except for the inevitable platitudes about side-effect free code being good for concurrency and so on. Yet that is the question that matters, and our code snippet debates are just the drunk looking for his car keys under the street lamp, even though he didn't drop them there, because the light's better.
Unless you believe that the choice of programming language is irrelevant (which is a little like saying an artist's medium is irrelevant), it's clear that different languages have different classes of programs that are easy to write in that language, and thus different classes of programs that will tend to evolve in it. Each version of an evolving program conditions the next version, so this influence gets compounded over time. (Code snippets are at the rudimentary extreme of that process, which is why they have so little comparative value; what we really need to see is how those snippets evolve into much larger systems.) The language itself and the current version of the program written in it condition the very stream of ideas about what you might do next. So there's a profound influence here, but we don't know how to study it. Failing that, the best approach is to let a thousand flowers bloom and see what systems emerge, but even there historical accident plays a huge role in where the development energy goes and thus what systems ever have a chance to emerge.
Personally I find that the imperative style is easiest in the small and the functional style is easiest in the large, and the trick is to find a design that allows the two to be fused with some regularity. But then I work in Common Lisp so I would say that.
Thank you for the post, it was interesting and made me think. I especially liked this point: "but rather that this factor needs to have a seat at the table before we have a chance of working out a balanced approach."
I agree that I would like to see how functional approaches can benefit large systems, in concrete terms, since almost all of the examples I've ever seen involve micro-code like this article. I'm especially skeptical that it can make a dramatic difference for the kind of messy business code that today is usually solved by large object-oriented systems and modular libraries.