Why I absolutely love java
gist.github.com
gist.github.com
Judging a language by standards it was never designed to meet is pointless. If you want to decide whether Java is a good language or not, see if it solves the problems it was designed to solve. I'd say it does. I may not like working in Java for small projects, but that doesn't make it a bad language.
You're right, we can't be saying that a language sucks because it doesn't look cool in some coding styles. Is like trying to do fancy OOP in pure scheme or common lisp without the CLOS!
It is a legitimate complaint. Having to write loads of boilerplate makes the code more difficult to read and understand, and increases the surface area for bugs to sneak in. That's true for both one-off scripts and huge enterprisey systems.
However, since Java was not intended to be a scripting language, then it should never have monopolized the material of introductory programming classes like it did. I consider Java to be a very ungentle introduction to programming when compared with Python, Ruby or Scheme.
Emphasis added. Ensuring that students have a sound grounding in the basics and can then focus on the new material in later classes seems far more relevant to the goal of teaching computer science.
Universities focusing on throughput and employability is the problem, not the solution. It shouldn't be 4 more years of high school ...
Although hopefully a dept as engaged in taking CS pedagogy seriously will teach a top-notch course in both.
Actually it was originally designed for embedded system with limited resources [1].
[1] http://www.oracle.com/technetwork/java/javase/overview/javah...
Actually it was designed to run on washing machines, refocused to work for browser applets, and then refocused again to deal with massive enterprise apps. I'm not sure it was ever suited to any of those tasks -- it's merely has a good enough cross section of features. One only has to look over at what Microsoft has done with C# to see that Java could be significantly less verbose.
Judging a numeral by a standard it was never designed to meet is pointless. If you want to decide whether Roman numerals are a good number system or not, see if you can hammer them onto a building. I'd say you can. I may not like working with Roman numerals for grocery receipts, but that doesn't make them bad.
Your way ends conversation and attempts to belittle, my way makes the point in a way that allows for discussion.
In real life I do dislike java and try hard to avoid having to use it, precisely for the reasons highlighted in the OP. I do like Haskell, and many other things. Note: all the real Haskellers are nice and would never be as snarky as I was.
Actually, Roman numerals were designed for counting the men in your army, whereas Arabic numerals were designed for mathematics. Comparing the two isn't a good argument against redthrowaway's point at all, because both are better at the task they were designed for.
Are you saying that Roman numerals are better for counting than Arabic numerals? I suppose you don't mean count (I, II, III, IIII, V...), but show the number of men in the army. I don't see any advantage in using Roman numerals.
Lets say we divide infantry in XXX maniples of CXX men each, supposing they are complete and you haven't lost people yet in battle. How is that better than 30 maniples of 120 men?
Otoh, arabic numerals are a lot easier to multiply/divide. Before the wide adoption of arabic numerals all but the most educated couldn't perform simple multiplication/division.
111
948 948
289 => 289
--- ---
1237
thanCMXLVIII plus CCLXXXIX => CMCCXLLXXXIXVIII => MCLLXXIXVIII => MCCXXXVII
but it may be that it's because what I'm used to.
List even = new ArrayList();
for(int i : new Integer[]{1,2,3,4})
if (i%2==0) even.add(i);
Still larger than necessary, and this doesn't have all the necessary class cruft, but still much smaller.Stolen shamelessly from https://gist.github.com/817635
That's a big difference.
First class functions aren't a feature particular to scripting languages. Many compiled languages also have them, such as Haskell, Ocaml, Scala, F#, C#, D, Go, Forth, Common Lisp, and so on.
> It was never designed to solve quick little problems in a few lines
C# wasn't either, but it manages to be pretty expressive for what it is. I don't think you can argue Java's design precludes it from having basic things like first class functions, when (a) C# operates in the same market and already has them, and (b) Java 7 is going to be getting them.
One of my beliefs is that we shouldn't think about "scripting languages" versus "compiled languages" and just think in terms of what would make for the ideal programming language, period. By that standard, Java is inferior to Python (to pick just one example) because it is so much more verbose and formal when accomplishing the same desired task.
Generally, typing extra stuff to make my code work isn't one of the problems I have.
x86 assembly IS terrible because string concat takes many loc. I use x86 assembly to solve problems where speed is paramount, string concatenation generally isn't one of those problems. Like lets say you need to reformat a little endian RGB pixel into a big endian RGB pixel, then that's something I'd use assembly for.
Java as a language is horrible language because the only problem it solves well is how to inflate a consulting bill, or how to waste developers time figuring out what exceptions a method throws. Only exception a method needs to throw is JavaOutTheDoor.
Solving a problem in java is like winning a race where your legs are hobbled, yes, it's an accomplishment, but wouldn't it have just been smarter to untie your legs? Java was invented in 1994 or something like that, and the scary part is it hasn't changed. Perhaps I should still code my C K&R style?
You hover your mouse pointer over the method call and a pop-up window tells you what exceptions it can throw.
Better yet, right click the method call and tell it to insert the try and catch block(s) for you.
This is how professional Java developers work. It only takes a few seconds.
I routinely interview programmers of all kinds. Extremely few Java programmers ever make it because they simply don't know how to get simple (but non-mainstream) algorithmic tasks done.
1) The chunk of Java code shows a complete program - the others show function definitions 2) The Java is written purposely to be as verbose as possible 3) The Java sends it's output to stdout, unlike the others 4) The Java code is needlessly written using generics
Things the comparison ignores: 1) The Java code is more toolable than the others 2) The Java code will outperform most of the other examples once it has been subject to Hotspot
Here's a more fair comparison, at the function level to level the playing field (and only one import needed: java.util.*):
List trollBait() {
return new ArrayList(){{
for (int i : new int[]{1, 2, 3, 4}) {
if (i % 2 == 0) add(i);
}}};
}
Here's why I absolutely do heart Java:I just ran this 100,000 times in 6 milliseconds on a Core i7 920 (2.67 GHz). And I scanned it with Findbugs, and PMD, and a security vulnerability tool. And I refactored it in my IDE with crazy IntelliJ foo-jitsu. And it's more strongly typed. And it's runtime memory model is safer.
And for clarity: the other ones aren't function definitions, they also build a new list, like your example. The examples are meant to be run in a REPL and that's why they don't send to stdout, although it will be just another function application in most cases (but your example works in beanshell, the stand-alone java quasi-REPL, so we're ok). I think all of them can be considered a full-program in those languages: as a stand-alone chunk of code that can be compiled/interpreted and will produce an executable output, that is. And, yes, the autoboxing was the only reason I chose generics, but I tried for it to be concise, given my limited knowledge of java; the max-verbose mode would have used a Runnable or something evil to simulate a higher order function.
My experience with all the languages in your sampler is that their runtime performance usually lags the Java on the JVM for general purpose programming. This is not an argument not to use them - I would prefer many of them in certain use cases. But if I want a managed runtime, and have some performance critical code that I am OK with being written in an imperative language, it is hard to beat the performance of simple Java on the JVM. There has been so much tuning to Hotspot over the last decade. That's been my experience anyways.
// Learn more about F# at http://fsharp.net
open System
let consume x = ()
let start = System.Environment.TickCount
Seq.init 100000 id
|> Seq.iter (fun x -> [0..4] |> List.filter (fun y -> (y % 2) = 0) |> consume )
let endTime = System.Environment.TickCount
printfn "%f milliseconds" (TimeSpan.FromTicks(int64(endTime - start)).TotalMilliseconds)
Output: 0.014100 milliseconds
Press any key to continue . . .
I'm sure if I added some java line noise I could get it up to 6 milliseconds. Too bad I didn't need a calendar class to figure out how to get from ticks to milliseconds. It's also really unfortunate that System.Environment.TickCount compiles down to a single assembly instruction. I was really hoping to use a factory pattern in there somewhere. Maybe some IOC containers. What good is a language if you can't write half your code in XML.First off, the resolution of TickCount is not less than 500 milliseconds. Are you sure you are actually timing it right? Maybe you should have used DateTime.Ticks which has a higher resolution. (seriously - I think you need to check your code)
But in any case, let's say your test is actually valid. You mentioned "Java line noise" - not really a real explanation for the difference.
So let me guess for you - maybe your F# runtime knows the function is pure and idempotent, and after running it once it probably just cached the output. So your run doesn't actually execute the filter across the list for every iteration, whereas my Java code did.
I could rewrite my Java code to return the same array over and over after it has been computed once, but it sure won't look as clean as a functional language like F#. I grant you that, and that's one of the reasons I prefer functional languages to Java.
Next time maybe put a little more thought into the response if you actually really have no idea why your program said "0.014100 milliseconds".
// Learn more about F# at http://fsharp.net
open System
let consume x = ()
let start = System.Environment.TickCount
let arr = [| 1..4 |]
for i = 1 to 100000 do
arr
|> Array.filter (fun y -> (y % 2) = 0)
|> consume
let endTime = System.Environment.TickCount
printf "%d milliseconds" (endTime - start)I do hope to learn more about F#, I am hearing good things about it.
Great article about how F# can approach the speed of C with some fancy inlining.
I make a living writing and supporting Enterprise Java apps and if it wasn't for these rich set of tools, my job would have been a nightmare. (Before flaming me saying if he wasn't writing code so badly in first place, he wouldn't need those tools - I also support code written by other people and writing complex, well performing code still remains notoriously hard.)
#include <iostream>
#include <algorithm>
int main(int argc, char** argv) {
int src[] = { 1, 2, 3, 4 };
int* end = std::remove_if(src, src + sizeof(src) / sizeof(int),
[](int i) -> bool { return i % 2 != 0; });
for (int* p = src; p != end; ++p)
std::cout << *p << " ";
std::cout << std::endl;
}
I wasn't sure about the lambda function syntax, but this compiles with g++ 4.5 (interestingly, even with the -Wall option, g++ doesn't warn about main not returning a value). Shows that even c++ can be shorter than java... List(1, 2, 3, 4).filter(_ % 2 != 0)
And it's very easy to move to Scala from Java :) Collections2.filter(
Lists.newArrayList(1, 2, 3, 4),
new Predicate<Integer>() {
public boolean apply(Integer i) {
return i % 2 == 0;
}
});
As I understand it, JDK 8 will support lambdas which will make it shorter still. CollectionUtils.filter(new ArrayList(Arrays.asList(1, 2, 3, 4)), new Predicate()
{
public boolean evaluate(Object v)
{
return ((Integer) v).intValue() % 2 == 0;
}
});sequence(1,2,3,4).filter(even());
import static com.google.common.collect.Lists.*;
import static com.google.common.collect.Collections2.*;
import com.google.common.base.*;
public class AdmittedlyNotMuchBetter {
public static void main(String[] args) {
System.err.println(filter(newArrayList(1,2,3,4),new Predicate<Integer>() {
public boolean apply(Integer input) {return input % 2 == 0;}
}));
}
}
btw, how do you preserve source indentation in the comments?
[edit: formatting, thanks] var filtered = new List<int>{1, 2, 3, 4}.FindAll(x => x % 2 == 0);var filtered = (new[] { 1, 2, 3, 4 }).Where(i => i % 2 != 0);
Not bad for a static language. :)
You can drop the parentheses, and int is inferred by the compiler:
var filtered = new[]{ 1, 2, 3, 4 }.Where( i => i % 2 != 0 );
Alternatively:
var filtered = Enumerable.Range( 1, 4 ).Where( i => i % 2 > 0 );
filter even [1,2,3,4]
take 2 (filter even [1..]) // take as many as you want
evens = filter even
<http://wiki.hackerdojo.com/w/page/32992961/Haskell-Hackathon...;
Newbies take special note of the Saturday session.
If nothing else, it's great having a compiler that can catch a large amount of errors without getting bogged down in the type boilerplate that many other static languages require.
Implicit static typing is definitely something I miss when working in other languages.
filter even [1..4]
I've found most of the time when you're trying to get incredibly short expressions that aren't obfuscated, haskell wins.
Others have already pointed out the Google Guava library. This version is almost all just standard Java, just using Guava to create the list of numbers.
ArrayList<Integer> list = com.google.common.collect.Lists.newArrayList(1,2,3,4);
for (Iterator<Integer> it = list.iterator(); it.hasNext(); ) {if (it.next() % 2 == 0) {it.remove();}}
System.out.println(list);
Also, Java does have REPL. It's called the Eclipse scrapbook view. I'm sure Netbeans has something similar (and that is part of one of the standard Java SDK downloads). // create an array list with 4 integer elements
ArrayList<Integer> list = com.google.common.collect.Lists.newArrayList(1,2,3,4);
// get an Iterator from the list, and use it to iterate though the list
for (Iterator<Integer> it = list.iterator(); it.hasNext(); ) {
// check if this element is even.
// If we want the odd numbers, change to != 0
if (it.next() % 2 == 0) {
// remove it if it is even
it.remove();
}
}
// print the list
System.out.println(list);The commenter said they could almost figure out what it's doing. It's not clear from that that comment if it is just the formatting that was the problem (which I agree, isn't very readable).
import static com.google.common.collect.Lists.*;
import com.google.common.collect.Iterables;
[...]
public static void main(String[] args) {
List<Integer> list = newArrayList(1,2,3,4);
System.out.println(Iterables.filter(list, isEven()));
}
private static Predicate<Integer> isEven() {
return new Predicate<Integer>() {
public boolean apply(Integer input) {
return input % 2 == 0;
}
};
}
The lack of closures is seriously felt when creating the "isEven" Predicate. This will be a lot cleaner next year (?), when closures are introduced in the language. For now, we have to live with the verbosity...It's possible to hide some of this verbosity and write clean code. For example, I often extract the function / predicate declarations to utility classes to avoid polluting the code. In this case, I would move the "isEven()" method to a "MathPredicates" utility class. The code ends up looking like:
List<Integer> list = newArrayList(1,2,3,4);
System.out.println(Iterables.filter(list, MathPredicates.isEven())); (1..4).findAll{!(it % 2)}Here is what these code examples are exploiting:
1. Java isn't designed for scripting. All of my Java programs require many classes. I hardly have any main() methods because most things I write are classes invoked by other classes, e.g. in the case of a servlet being invoked by the web application server.
2. It's rare in practice that I need to hard code the contents of data structures inside my own code. Normally they are loaded from data files.
3. Import statements are automatically thrown in by the IDE and most people hardly even notice they're there and type nothing more than Alt-Enter any time there is an import line missing.
So really, what I really am typing in java is only:
List<Integer> result = new ArrayList<Integer>();
for(int i : source) if(i%=2) result.add(i);
Now that's not really all that complicated is it?for (int i:new int[]{1,2,3,4}) System.out.print(i%2==0?i:"");
if(e.intValue()%2 != 0) == >>> if((e.intValue()& 1) != 0)
(filter even? [1 2 3 4])
(filter even? '(1 2 3 4))
(remove-it-not 'evenp '(1 2 3 4)) (remove-if 'oddp '(1 2 3 4))[1..4].filter (x) -> !(x%2)
grep { $_ % 2 == 0 } (1,2,3,4,5);
(While I was using Java, I never even knew there was a need for higher-order functions.)
[X || X <- [1,2,3,4], X rem 2 == 0]the fact that this is called out twice as being "ugly" twice in comparison to the other examples auggests to me that erlang is called out as being ugly purely from hearsay as opposed to actually being ugly.
(I do think erlang can be ugly, I also think thats its biggest strength, but I dont think this example is ugly)
I have no preconceptions about Erlang. I've never seen the opinion that Erlang is ugly, and your code above is the first Erlang I've ever seen. I also know nothing about Haskell, but I found the Haskell example to be the most elegant.
So, a more reasonable conclusion: The fact that two people found the code ugly suggests that it is ugly.
public class filter {
public static void main (String [] args) {
System.out.println("2, 4");
}
}
FTFY, While it may be fun that show off with your favorite language, the Java version is intentionally complex.Edit: In case you missed the point. This version is as absurd trying to be short as the other version is absurd trying to be long. Also, I can guarantee that an "Enterprise" version would be 200 lines long :-P
array_filter(array(1,2,3,4),function($v) { return !($v&1); }); echo '1 2 3 4' | egrep -o '\<[0-9]*[02468]\>' &1/^@4%2!#
Just a guess... [1..4]
|> List.filter(fun x -> (x % 2) = 0)
C# using System.Collections.Generic;
public static class Foo {
public static void Main(string[] args){
Enumerable.Range(1,4).Where(x => (x % 2) == 0);
}
} using System.Linq;
class Filter
{
static void Main()
{
var a = new []{1, 2, 3, 4}.Where(x=>x%2==0);
System.Console.WriteLine(a);
}
}
It's unclear if printing is necessary or not, as the Java one does an explicit print, but the others don't. using System.Linq;
class F {
static void Main() {
new[] {1, 2, 3, 4}.Where( i => i % 2 > 0 ).ToList().ForEach(
System.Console.WriteLine
);
}
}