MapReduce is written in C++ and has an interface to it in Java. That’s hardly helping your point.
Bringing up COBOL also doesn’t do a heck of a lot for you, given that it’s an archetypal imperative language.
MapReduce is written in C++ and has an interface to it in Java. That’s hardly helping your point.
Bringing up COBOL also doesn’t do a heck of a lot for you, given that it’s an archetypal imperative language.
See also Jane Street Capital, a Wall Street bank who write most of their software in O’Caml.
No, he’s saying your point about the amount of software written in Java is moronic. Popularity of a language is completely independent of how well designed it is.
My point was this: functional programming advocates are constantly arguing that functional languages offered unparalleled benefits in programming efficiency over imperative languages. Those benefits, however, never seem to show up in the marketplace. Saying that one company is using O’Caml to produce their software is a total non sequitor, because I’m not claiming that imperative languages offer any intrinsic benefits over functional languages. You’re making the claim that functional languages give such benefits over imperative, so why aren’t those benefits causing functional shops to take over?
So, essentially, your claim is that Java is bad (“absolute garbage”?) because it doesn’t meet a functional language’s specs? Even though, in meeting those specs, the language would be unusable without “retraining programmers”? And that, statistically, a lot of programmers cannot even hope to master the functional paradigm (as they will not have the requisite “sophistication”)?
In each of the three years I’ve TA’d undergraduates, I’ve found only one person in each class that both “gets” and likes functional languages. In fact, most students actively despise them; the animosity I occasionally encounter towards Java is nothing compared with the rants I’ve heard about Scheme or Lisp.
Personally, I like functional languages. But I think your position succumbs to a baby/bathwater issue. Not only that, but it seems to me that there’s a bias towards theoretical foundations that usurp day-to-day practicality. None of which, IMHO (thus far), takes away from Java’s strengths, nor makes it a “bad” language.
Why did you quote my post where I’m providing reasons for the C family’s dominance when I’d already written a post highlighting the deficiencies of Java? If you want to know what I think’s wrong with Java, read my earlier posting. Java has serious deficiencies irrespective of the features of functional programming languages. The lack of operating overloading, true templates and the ability to metaprogram, class members not being true member functions etc. etc. are deficiencies in Java that even other similar languages get right (C++).
Wait, so you admit your point was a strawman? Who has actually claimed that in this thread?
Sorry about this, but I’m not sure…was this directed at me?
Yeah, although I didn’t read your post correctly - ignore it.
I don’t know that I’d call Java “absolute garbage”; then again, the most worthwhile thing to come out of Java was the bringing of garbage collection into the kicking-and-screaming mainstream…
I see how they’re useful for numerical programming, but then, who does numerical programming in Java? To be perfectly honest, operating overloading is not a feature I’ve ever wanted to take advantage of in any language(with the exception of overriding operator new – and Java’s memory allocation strategy can be a bottleneck, I’m aware).
One problem that I have with operating overloading is that if a programmer isn’t on their toes, they can be fooled into thinking of an operating being virtually free instead of as a function call as they should be. You can actually see a common example of this kind of thing in Java with the overloaded + operator for string concatenation. Programmers can do things like:
logger.debug("My map is " + map);
and all of a sudden lose a bunch of performance.
(on the other hand, it’s not like:
logger.debug(“My map is %s”, map.toString());
would be that much better, so perhaps this isn’t a good example)
Meh. Interfaces can be used for most things one wants a lambda expression for. It’s a bit more verbose, but to be honest verbosity isn’t a huge issue for me. In line lambda expressions are fine until you need to use one in more than one place, at which point you’re going to have to come up with a common definition of your expression anyway.
Would you prefer they had a “namespace” keyword that you could declare your Math functions in instead? I have to admit this is the complaint about Java that baffles me the most. Enforcement of separate namespaces are, in my opinion, a good thing.
Generics only working with objects is a legitimate complaint. However, the alternative would have been C++'s template system, which can really cause a lot of code bloat(to the point that some STL implementation use void* internally to minimize the code bloat – which sort of misses the point of having templates in the first place). I do wish that there was a better way than the wrapper classes to use primitives in generics(just giving us mutable wrapper classes as an alternative would be a start).
Yes, this kind of thing is a favourite in any debate concerning two programming languages. Write one 5-line program in one and challenge the opponent to be as compact in their language. Of course, the whole exercise is pointless, because nobody cares about writing 5-line programs – it’s how you write programs with line counts measured in the tens of thousands(or bigger) that really matters.
To solve the generic type of problem a datatype can solve, you’d obviously use an abstract base class(or an interface) and provide implementations of that class for each of the possibilities you’d have in your function. I much prefer the class-based approach in general because:
a) For a simple 2-line function, your way works better. But, for more complicated functions this starts to get untenable. You’ll end up with all kinds of different cases and each one can get long and all of a sudden your nice 2-line function becomes a much bigger mess. Different classes can keeps the different cases separate, which can be easier to manage.
b) You won have a single function that operates on your data type, you’ll have many. The class based approach keeps the code that operates on the same data together, which is how it belongs logically. The “tree” case doesn’t care how the “Empty” case goes about deciding whether an item is present; all it cares about is that the Empty case is able to handle
c) The class approach is easier to extend. Just create a new class, implement it and use it. You only change code in one place. That last point is especially important, because if you forget to implement a particular case in a particular function, you won’t notice an error until you try to call your function and it decides that it can’t handle your particular case(this can be particular annoying if you have a catch-all defined). The class-based approach gives a compiler error if you forget to implement any pure virtual functions(it still doesn’t help you if you forget to override a normal virtual function, though).
Now, in your example these complaints don’t apply, because a binary tree is too simple an example. Nobody would even bother having separate classes and a base class, they’d just say if(this.isEmpty()) return false; … blah blah blah
For a general solution, though, I prefer classes.
Finally, you mentioned preferring Javascript’s implementation of object orientatation to Java’s. To be honest, I find the object-based approach to be somewhat of a hack. It’s nice for prototyping, I suppose, but prototyping is not a big issue for me; personally I think it’s a waste of time. People could easily use the object-based approach in C++ but I’ve never seen anybody ever bother. It seems to me to be duplicating work that the compiler is going to do for you. What, exactly, do you prefer about the object-based approach?
Ah, I see. So you don’t use operator overloading, so nobody else should, either.
Should such a person even be allowed to write software? No.
I don’t see how. Translate this, for example:
map (fn x => x * x) [1, 2, 3]
No, I’d prefer it if OOP wasn’t enforced.
What? I provided the code to show something that was impossible in one language but possible in another (to the extent that can be so, between two Turing complete languages). Java’s generics are incapable of expressing parametric polymorphism in the way that ML can, for instance.
Wait, what? You propose a “solution” where hundreds of derived classes are written yet my version is untenable? (Note this still doesn’t solve the problem - the whole point about the polymorphic function is that it works on every type - not just ones the programmer deems to implement the function on).
Hardly beyond the abilities of ML, is it?
fun member_empty item Empty = False
fun member_branch item (Branch a b c) = if item = a then true else (member a) orelse (member b)
fun member item tree =
case tree of Empty => member_empty item tree | tr as (Branch a b c) => member_branch item tr
Apart from that doesn’t happen at all, as the compiler warns you that you haven’t covered all cases.
Taking ML on at static analysis? You’re brave!
But these aren’t mutually exclusive. O’Caml is an object oriented functional programming language.
No, I didn’t. I believe that was Derleth.
static void map(List<D> in, Function<D, R> f, List<R> out) {
for(D d : in) {
out.add(f.apply(d));
}
}
interface Function<D, R> {
R apply(D x);
}
map(Arrays.toList(1, 2, 3), new Function<Integer, Integer>() {
Integer apply(Integer x) { return x * x; }
}, new ArrayList<Integer>());
Well, on preview, I may be behind the thread here. Still, here’s what I’ve been trying against the SDMB’s spottiness to post for a little while now:
I’ve never been a huge fan of ad hoc operator overloading, but more disciplined approaches, like that taken with the aid of the type class system in Haskell, are very appealing. Though I don’t consider it a huge strike against Java to lack such a thing.
Well, that depends on the conceptions that the programmer brings, I suppose. I can see what you’re saying, but I wouldn’t say it’s strong grounds for avoiding user-definable operators altogether.
Whys is C++'s template system the only alternative? One of the strongest points to me in favor of languages like Haskell and the ML family is how immensely easy it is to work with data type polymorphism and parametrically polymorphic functions in them, much easier than most mainstream languages. (And let’s not forget just how long it took for Java to get generics in the first place…)
I agree that mere demonstrations of brevity (the Perl golf syndrome) don’t account for much. But I think Dominic’s example does show, to some extent, the sort of thing that Java makes a bit of an unnecessary pain out of, and how simple such things should be (and are, in languages designed properly).
I can only say “Huh?”. Functions which aren’t defined to handle all the cases their input could be cause compiler warnings/errors in languages with Haskell/ML-esque type systems too. That’s the whole point of strong static type systems; to prevent run-time type errors.
It isn’t in Haskell, but honestly that a pretty crappy point, because now that I think about it, the type inferencer should give you an error if you try to use the function on an unsupported case. I think I made that mistake because I was thinking like a C programmer(occupational hazard of being a kernel programmer)
Sure, you’ll only find the error at run-time if there’s a catch-all rule, but the same applies if you forget to override a non-pure function.
I said before that brevity didn’t matter for all that much, but I also said that Java made some things into an unnecessary pain, and this is a decent example. I mean, for this case, it’s not so bad, but in terms of scaling it up, based on this, one shudders at the idea of writing the equivalents of lambda-expressions manipulating higher-order functions with any complexity.
I said before that the clean approach to polymorphism in Haskell/ML-type languages was one of their big niceties. The other one, which applies to functional languages more generally, would be the pure ease with which one writes higher-order functions in such languages (treating functions as first-class values, which can be passed around as parameters to and returned as results from other functions with no more difficulty or remarkability than any other kinds of values). Sure, Java can do these kinds of things too, in a way, with some contrivance, but it seems like such a clumsy and laborious way as to be needlessly discouraging in many cases.
If the cleanness of the approach to those two features from functional programming were adopted by mainstream programming, I’d feel a lot better, a lot more comfortable with such languages.
Yeah, I know; Standard ML. But I did mention ML, after all.
Heh. Yeah, then it really will be an uphill battle to convince you of the merits of functional programming, I suppose.
For the sake of full disclosure, my own perspective is rather ivory tower, true to stereotype. Heaven help us if we ever get into a discussion on the utility of monads.
(Just to be clear, by “ivory tower”, I mean “grounded in academia”, though my love for Haskell started well before that)
Jeez, I guess there is a bunch of softwate types here.
The obvious answer to the OP is that it is way to easy to make cross platform feature creeped bloated pigs with java.
It’s not a compiled language. The bloat is far more obvious. Add in that it absorbs huge data structures to do simple tasks because it is OOP and high level. Add in that my kids are adding new java function to my browser …
Firefox used to be a good browser, but the simple fact is that after I add all the million add-ons that I want and never use, it barely functions. Eclipse has always been to much of a pig for me to use … except for the few java programs that I play with.
I suspect as computer power increases, this is the way of the future.
You’ll have an easier job with me than most kernel hackers. How many of them would stand up and defend Java like this?
Well, you managed to turn a single line program, where the meaning is immediately clear, into an eleven line monstrosity that still lacks most of the benefits of the original, at the very least clarity (which may have been alleviated a little if you could have created a C++ style functor from your Function interface, but this would have required operator overloading) and an inability to perform partial application in any meaningful sense.