import java.util.Collection;
import java.util.Iterator;
// crap elided
Iterator<String> iterator = myCollection.iterator();
while (iterator.hasNext()) {
doSomethingWithString(iterator.next());
}
over, say:
(map do-something-with-string my-collection)
But Paul! says you, Java gives you static typing! The Scheme example above doesn't, so it can get away with that kind of dynamic-language brevity! Well, so does Haskell:
map doSomethingWithString myCollection
and SML:
map(doSomethingWithString)(myCollection)
For fun, lets just see it in a smattering of other languages I've used. Ruby:
my_collection.each { |x| do_something_with_string x }
Erlang:
lists:foreach(fun do_something_with_string/1, MyCollection),
Common Lisp:
(mapcar #'do-something-with-string my-collection)
Naturally, this isn't even the whole picture. The example assumes you're iterating for side effects; if you needed the list with its elements transformed, that would be another 5-7 lines of Java. And the list can only exist because it was constructed to begin with, which if you did it in another class, requires 3-6 more import declarations there.
I know its trendy to hate on Java, and I've mentioned before that PL hating like this is unproductive. Still, we use and work with variable-sized lists all the time, and what functional designers figured out (long, long ago) is that it's quite nice to have them built-in.
Bleh, sorry. Android programming is fun, despite the Java.
I did say "imperative" above, not just Java. Kind of a misnomer, as CL and Ruby, above, provide one-line map and are arguably imperative. In that case, I let my biases shine through and used "imperative" interchangeably with "luddite." But let's never forget our buddy C++:
#include <list>
using namespace std;
list<string>::iterator iter;
for (iter = my_collection->begin(); iter != my_collection->end(); ++iter) {
do_something_with_string(*iter);
}
PUKE
No comments:
Post a Comment