Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Correction: The last time I used FORTRAN was 27 years ago. Apparently it got functions.

FORTRAN had user-defined functions since FORTRAN II in 1958; see http://archive.computerhistory.org/resources/text/Fortran/10... on page numbers 5, 14, and 15.

Joel unfortunately completely misses the point of why C and Java suck at this stuff: you can use functions as values in them (anonymous inner classes in Java) but they aren't closures. And his comment about automatically parallelizing "map" is a little off-base; if you take some random piece of code and stick it into a transparently parallel "map", you're very likely to discover that it isn't safe to run multiple copies of it concurrently, which is why languages like Erlang have a different name for the "parallel map" function. The "map" in MapReduce is inspired by the function of that name in Lisp and other functional languages; it isn't a drop-in replacement for it.

As usual, while Joel's overall point is reasonably accurate, most of his supporting points are actually false to the point of being ignorant nonsense. I think someone could tell as good a story in as entertaining a way without stuffing it full of lies, although admittedly my own efforts fall pretty far short.



You're nitpicking about details that are not relevant to the article at all.

His point was that languages that treat functions as first-class citizens enable a class of abstractions that are tedious/impossible in languages which don't support them.

Whether the naive implementation of map can be easily parallelized across multiple machines/threads/processes is not relevant. In fact, he even says that you need a 'super genius' to write the scaling map and reduce operations.


> Whether the naive implementation of map can be easily parallelized across multiple machines/threads/processes is not relevant. In fact, he even says that you need a 'super genius' to write the scaling map and reduce operations.

I think this brings out why I wasn't just "nitpicking." Even though you're presumably pretty savvy, Joel's article has confused you. You're thinking that the easy parallelization is an attribute of the implementation of map, and that a sufficiently smart implementor could make it work.

In fact, the implementation of parallel map is pretty irrelevant here. The important thing is that the function provided to map create no inter-loop dependencies. And given that, you don't need to be a super-genius to implement MapReduce. The super-genius was in coming up with the interface constraints in the first place and recognizing that they were applicable to a large class of problems.

So there are two problems with these "details that are not relevant to the article".

One is that Joel is presenting these details in order to convince you of his point of view. But since they aren't actually true, any confidence they inspire in you is misplaced. You'd be better off with a bald assertion of the importance of functional programming, backed up with "trust me, I know better than you." Admittedly, that's not as much fun to read.

The second problem is that, although Joel has achieved his goal of convincing many people of his point of view, he has done damage to their models of the world in the process. I fully expect to see newbies for years believing that you could never possibly implement MapReduce in C or C++, or that Java requires you to create a whole new file instead of an anonymous function, or that Google Search works by invoking a MapReduce job. And these false beliefs will do real damage to their lives.


But isn't that point pretty obvious?


Perhaps to you. Perhaps not to someone who programmer exclusively in Java or VB.


Just to complement your point, try to do recursion on 80's BASIC.


> Joel unfortunately completely misses the point of why C and Java suck at this stuff: you can use functions as values in them (anonymous inner classes in Java) but they aren't closures

I don't at all think he completely misses the point.

First, anonymous inner classes do capture their lexical environment, and you can access outer variables provided they are declared as final.

Second, even if closures allow another bunch of programming techniques, and even if they seem a natural way of programming with anonymous functions, they are not needed for everything related to being able to pass functions as arguments, at all. Notably, every example joel has given in his article doesn't rely on functions capturing their outer lexical environnment. mapping an add function to an array doesn't, and is still a very useful programming technique.

Admitedly though, i really prefer my languages to support full lexical scoping and closures. But i don't think the article was about that, and i feel more like you missed what joel had to say because you think joel should have introduced the full notion of what a first class function is.


> First, anonymous inner classes do capture their lexical environment, and you can access outer variables provided they are declared as final.

Well, I admit I haven't written much in Java in years, but doesn't that mean they only capture a small part of their lexical environment --- an immutable part? And that means you can't write jQuery.each in Java, right? Any time you want to write a loop with data dependencies between iterations, you need to use some mechanism other than just mutation of variables from the outer scope?

> every example joel has given in his article doesn't rely on functions capturing their outer lexical environnment. mapping an add function to an array doesn't, and is still a very useful programming technique.

You are absolutely correct. Thank you. (That means you can do it in C with almost no trouble.)

> i feel more like you missed what joel had to say because you think joel should have introduced the full notion of what a first class function is.

See my other comment about "nitpicking" for my commentary on that.


> Well, I admit I haven't written much in Java in years, but doesn't that mean they only capture a small part of their lexical environment ...

They capture only the immutable variables. Wether that's a good or bad thing in itself is open to discussion, but that's clearly not the only problem with anonymous inner classes. Most people end up never using them where you would have passed a function just because it's so long and boilerplatey to do so.

> You are absolutely correct. Thank you. (That means you can do it in C with almost no trouble.)

Yeah that's right, and part of why i consider C being a less retarded language than java.

> See my other comment about "nitpicking" for my commentary on that

I read it, didn't really understand where you were going. You're first saying that joel is incorrect about some details in his article, but i've yet to see which ones. I see him overgeneralizing, sure. The point you then develop is that the fact that he is over-generalizing will harm newbies programmers.

This has been discussed a thousand times before in other contexts, but suffice to say that i profoundly disagree with that kind of statements, and that i find it weak to even go there.

First, you have no real proof of that, so even mentionning it, saying you are sure of it, is weak, you're basically saying "what you're written is gonna harm people", which is a pretty serious accusation in my opinion, without backing it with any facts at all.

Second, i really don't believe that even if it is true and you can prove it, the responsibility should be on the writer. No individual has a perfect knowledge of it's field, that's why it is your responsibility as an engineer to question the facts, and to demand hard data before you say something is true or false. If you fail to do that you have bigger problems than what Joel Splosky is writing on his blog.

In the end, and to explain more generally why i find your critique to be quite unfair, is that, while i agree that Joel is over generalizing, that things are far from being as simple as he is saying they are, the general idea , that i'm gonna sum up as "Having first class functions should be a basic building block of your language" is not only valid, but seriously needs to spread to the whole programming community.

It was because of such an article that i learnt functionnal programming in the first place. It probably wasn't this article, but it wasn't a lot better, maybe even worse. It doesn't mean that i think functionnal programming is the silver bullet to parallelism.


Well, java is retarded, so the standard trick is to declare an array of size one and declare the array itself as final. So you can't change the array object but you're certainly free to change the object it contains. Stupid? As all hell. Makes static local classes much closer to closures, though, even if twenty times as lengthy to write.


"Joel unfortunately completely misses the point of why C and Java suck at this stuff: you can define anonymous functions in them (anonymous inner classes in Java) but they aren't closures."

You can't define anonymous functions in C.

And I wouldn't "attack" Joel for "stuffing the article full of lies". It's more like "abstracting away the details". When people talk of the benefits of some practice or programming paradigm, they don't always mention all the work going into it - they just explain the concept. That's what a good teacher does, IMO. He takes complex concepts and explains the important parts.


> You can't define anonymous functions in C.

You are of course correct. I have corrected the parent post.

My point is, though, that you almost can't define anonymous functions in Python, either, but you can do nearly all of these clever patterns. The difference is that Python functions are closures.

> And I wouldn't "attack" Joel for "stuffing the article full of lies". It's more like "abstracting away the details".

I agree that that's what a good teacher does, but I don't see this article as doing that.


Anonymous inner classes in Java actually are closures. The compiler will force you to declare any closed-over local variables as final. Like everything else in Java, it's verbose but it works. The problems with using closures in Java is that the type system doesn't play well with function objects and that the standard library doesn't care about functional programming, and it's really only the former that is stopping you from functional programming in Java.


There's a great talk on parallelism, by guy steele: http://www.infoq.com/presentations/Thinking-Parallel-Program...

Notice that you need different data structures.


He also misses the point that FORTRAN compilers are bloody good at finding and exploiting opportunities for parallelization. You have much less need of these higher level language constructs if the compiler is doing it for you under the hood! On VAX this was as simple as the /PARALLEL flag at compile time...


You're missing it. Here's what Joel is saying without saying it: C# 4 is "that language.". Both his companies are built on the MS stack.


Given that the article is from 2006 that'd be some prescient writing.

Also at the time of this article they had their own custom language Wasabi. This article explaining Wasabi is dated a month after the original article:

http://www.joelonsoftware.com/items/2006/09/01b.html

It's based on VBScript, not C#.


C# 4.0 didn't exist when the article was written in 2006.


While you need a lot of syntactic bullshit to get there, Java does have closures.


By the time I am done with the syntactic BS, I pretty much forgot what I was doing and why...

Java is just not very conducive to exploratory programming.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: