141 comments

[ 3.1 ms ] story [ 123 ms ] thread
You cheated. Do it without the fancy schmancy lists.
No C#?
I don't do C#, but feel free to fork the gist and add it :)
(comment deleted)
In fairness to the Java version, you should probably add all the additional stuff.

   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.
The other ones are meant to be run in a REPL, but java doesn't have one (lest you count beanshell, which ships with a really old version of java, one before generics) so I had to print it explicitly

  using System.Linq;
  class F {
    static void Main() {
      new[] {1, 2, 3, 4}.Where( i => i % 2 > 0 ).ToList().ForEach( 
        System.Console.WriteLine 
      );
    }
  }
It's always irritated me that ForEach isn't available on IEnumerable<T>
I know it's fun to rag on Java, but this is a meaningless comparison. Java isn't a scripting language, and it wasn't ever intended to be one. It was never designed to solve quick little problems in a few lines, it was designed to deal with massive enterprise apps with complicated dependency trees over multiple architectures, and it does that job pretty damned well. Stop complaining that Java isn't Python/Ruby. It's like saying that x86 assembly is terrible because string concatenation takes so many loc.

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.

Oh, this is just a tongue-in-cheek joke; java has really cool stuff, I actually code in java every morning and I really like the JVM and the JIT, without it, clojure, jruby and jython wouldn't exist, and jruby is way cooler than Cruby!

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!

I know, and I both get and appreciate the joke. There are, however, a lot of people who think Java's (substantial) verbosity is a legitimate complaint against a language intended to do what it does. It's really neat to be able to accomplish something cool with list comprehension in Python, but when you're working on a massive codebase that might have 60 people working on the same code, it's nice to have the abstraction that Java was designed for, and the most basic syntax that a C-like language will allow.
Yep, in an environment like that the serious architecture java enforces is a good thing, especially with heterogenous groups of not-necessarily-hackers-but-good-coders.
How is that nice? (Serious question...)
There are, however, a lot of people who think Java's (substantial) verbosity is a legitimate complaint against a language intended to do what it does.

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.

Where it all went wrong was when someone said Java is what the web should be developed with, we then got JSP, servlets and later Struts. Java web was brain dead on arrival and thankfully new style development trends are rectifying that evil. With JavaScript and Mobile apps taking over the UI from Java (as well as the other web frameworks for that matter), it becomes evident that Java when weighed in the balance is not that wanting, sure it does not do some things well and it can be a bit verbose, but as a back end language, I see no reason to abandon Java for purely technical merits. I do have concerns about Oracle's stewardship but that is another topic for another day.
Yes, you're exactly right.

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.

I agree, and my university is currently doing a 2-year A/B test where half the undergrads will get intro CS in Java, and the other half in Python. After the two years are up they'll see what group performs better in 3rd year classes. I think it's a great idea.
I'd rather they checked 1 year after graduation and determined which was better for employability.
> my university

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 ...

That's right, nobody goes to school so's they can make more money, it's all about expanding their minds.
That's true, and although I don't hate java or the technologies it has spawned (the JVM is a neat one, just look at it's finest offspring, clojure), trying to teach basic programming with it just seems bad. Maybe for an intermediate course on OOP, it does a good job if one wants to teach C++ or C afterwards; but as a first language, I have against it that it forces to spend too much time in syntax and inexplicable cruft (unless you're willing to explain the concept of class and static method the first day), and magic is never good for teaching if it's never explained. Just look at the classic SICP lectures: the syntax is done with in half an hour, then recursion and then higher order functions, and it doesn't feel like a brainfuck at all!
Care to share who is doing this, I wish to suggest this to my workplace/university.
UVic. I can't find find anything about it on the CS website [1], but this is what I've heard from speaking to faculty and grad students.

[1] http://www.csc.uvic.ca

Pity the poor students who are stuck taking the Java one due to scheduling or other administrative constraints.

Although hopefully a dept as engaged in taking CS pedagogy seriously will teach a top-notch course in both.

My 1st year profs were all fantastic, and the intro Java courses that I took did a fairly good job scaling from Hello World and FizzBang to a visual calculator processing pre-, in-, and post-fix arithmetic in a binary tree, so it wasn't too bad. Granted, first year was really easy and passed most students. Second year has, iirc, a 60% pass rate, and the program overall has a 40% pass rate. I'm not sure if that means it's rigorous or the profs are lousy, but I at least feel it means my degree is worth something when I graduate.
It actually happened to me, my first programming language in college was java and it made programming look really hard. I actually hated programming until the very end of my third year, when I learnt python in my first job. Ironically, later, when taking a compilers course -when I already knew how to program- I was quite happy with java+flex+cup, it felt powerful and fast.
This is not a meaningless comparison; it points out one of the main deficiencies of java: lack of first-class functions. The closest you can come is using anonymous inner classes, which is kind of kludgy.
it was designed to deal with massive enterprise apps with complicated dependency trees over multiple architectures

Actually it was originally designed for embedded system with limited resources [1].

[1] http://www.oracle.com/technetwork/java/javase/overview/javah...

Well, at least the JVM was. Java the language was designed to lure C++ shops and not scare them too much. So in that respect, it was designed to be an enterprise class language.
Sorry to be pedantic, but wasn't Java designed initially for set-top boxes, when it was still called Oak, and was repeatedly re-purposed for running code in web pages (as applets) and then for enterprise-friendly server-side web apps (J2EE)?
> It was designed to deal with massive enterprise apps with complicated dependency trees over multiple architectures

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.

(comment deleted)
I thought the example was a little terse, he didn't even bother to include an XML configuration file for his IOC container, or a bunch of maven dreck to import a couple libraries. He also forgot to name the file correctly so it might not even compile. As well the batch file/shell script so it will actually execute and pass a bunch of arcane -XMemory flags to java.
I know it's fun to rag on Roman numerals, but they were never intended for totaling receipts. They were never designed for quick little sums, they were designed for engraving on massive long lasting objects like buildings and copyright notices on feature films, and they look pretty darned good there. Stop complaining that Roman numerals are not Arabic numerals. It's like saying counting on fingers is terrible because nobody has more than X them (That's 10 to you youngsters, or 0b1010 to you real smart alecks).

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.

Hello Reddit. Welcome to HN.
That's much snarkier than simply saying, "how does Java differ from Roman numerals?"

Your way ends conversation and attempts to belittle, my way makes the point in a way that allows for discussion.

Complain if you must, but there is a serious point involved. People get invested in technology and they start to adopt certain patterns of argument that stem more from their own investment than anything else. I tried to highlight the pattern using humor. Nothing personal intended.

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.

> They were never designed for quick little sums, they were designed for engraving on massive long lasting objects like buildings and copyright notices on feature films, and they look pretty darned good there. Stop complaining that Roman numerals are not Arabic numerals.

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?

Actually, roman numerals are easier to sum than arabics. To sum two roman numerals you just write all the digits together and collapse them as much as possible. There is no carrying over of digits and such.

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.

You may have a point, but I still find easier to do

         111
 948      948
 289  =>  289
 ---      ---
         1237
than

CMXLVIII plus CCLXXXIX => CMCCXLLXXXIXVIII => MCLLXXIXVIII => MCCXXXVII

but it may be that it's because what I'm used to.

(comment deleted)
It's perfectly reasonable to rag on it for this. What's not reasonable is that the code can be written in a much more compact way by not trying for an "applicative" style.

    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

Many of the other languages write this in functions that are first class citizens. The functions are ready to be used. In Java you would still need to put this inside another class to make it run and other classes would need to instantiate that class to run it.

That's a big difference.

This is admittedly better, note, tough, that I was trying to do it in the mindset of the other languages included (just having one explicit list and filtering out instead of in); however, as it was stated before, it's never good to try to write code in the idiomatic style of other languages if the end result is something not idiomatic at all, it's like trying to play the bach chaconne for violin in a tuba or <put better analogy here> : it can be done but it's just forcing it.
I completely agree, though this is where I take issue with both the Java community and with managers and architects who have pushed for Java to be standard outside of the enterprise realm. I don't hate the language, I dislike the people who try to fit the square plug into the round hole. It's taking a lot of explaining to a lot of people at my workplace/university (a Java school naturally) that when developments teams are segregated into 1/2 person teams, have high turnover, and spread widely across an organization, using Java just doesn't make sense. It makes a lot more sense to use an easily approach scripting language such as Python or PHP in this case. But yet I had several Java evangelists literally screaming at me over our decision to go with PHP. In the end we won out, we built a solution that has run flawlessly (knock on wood) and the Java evangelists were moved to other departments.
> Java isn't a scripting language, and it wasn't ever intended to be one.

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.

> Java isn't a scripting language, and it wasn't ever intended to be one.

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.

Actually judging a language by standards it was never designed to meet is not pointless. I judge languages by how well they solve problems I need to solve. I don't care if it was intended to solve that problem.

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?

"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."

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 find this sort of argument frustrating. "Java doesn't solve the problems I want to solve in the way I want to solve them, therefore Java is a horrible language and shouldn't be used by anyone." Fine, Java isn't the language for you; but other people have different problems or different ways to solving those problems and some of those people find Java to be a perfectly good language. Just because you don't like it doesn't mean everyone should hate it. To each his own.
Filtering a list of numbers by a criterion is not a standard. It's a simple task. The discussion does have relevance - it shows why Java programmers need to rely so heavily on cookie cutter libraries: writing something from scratch is a huge bear.

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.

perl (because I feel like it):

grep { $_ % 2 == 0 } (1,2,3,4,5);

even shorter: grep { $_ % 2 == 0 } 1..5;
-- Haskell

filter even [1,2,3,4]

Or

take 2 (filter even [1..]) // take as many as you want

This is true, I forgot to mention that the haskell version trivially scales to infinite lists. You can use partial application to encourage code reuse as well:

evens = filter even

Even better.
this looks really nice, gotta learn me some haskell
I'm currently in the process of learning it, and I'd definitely recommend it.

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.

Save some characters:

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.

I don't know about the other lisp dialects, but the anonymous function is actually not needed in the Clojure version:

(filter even? [1 2 3 4])

Same for the others.

    (filter even? '(1 2 3 4))
    (remove-it-not 'evenp '(1 2 3 4))
Oh, right! even? is already a function, d'oh!
I think you mean 'remove-IF-not.
Or:

    (remove-if 'oddp '(1 2 3 4))
Scala

  List(1, 2, 3, 4).filter(_ % 2 != 0)
And it's very easy to move to Scala from Java :)
(comment deleted)
C#: var filtered = (new int[]{1,2,3,4}).Where<int>( i => i%2 != 0 );
This is what really shows the problem with Java.
Alternatively:

    var filtered = new List<int>{1, 2, 3, 4}.FindAll(x => x % 2 == 0);
As C# has some type inference, you can reduce it further:

var filtered = (new[] { 1, 2, 3, 4 }).Where(i => i % 2 != 0);

Not bad for a static language. :)

Hi David :)

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 );

Or you can just use groovy and get the best of both worlds :) [1,2,3,4].findAll {it % 2 == 0}
PHP

  array_filter(array(1,2,3,4),function($v) { return !($v&1); });
-- Groovy

  (1..4).findAll{!(it % 2)}
(comment deleted)
(comment deleted)
coffeescript

[1..4].filter (x) -> !(x%2)

That's the problem of java developers, they dont use the bitwise operations:

if(e.intValue()%2 != 0) == >>> if((e.intValue()& 1) != 0)

There's no problem here. You can be pretty sure simple calculations like this (and multiplications with a power of 2 vs. shifting etc.) will run the same machine code in the end.
I think you are right in this case - I updated my example code above to use bitwise and it is running in the same amount of time. (100,000 iterations in about 6 milliseconds)
Erlang

    [X || X <- [1,2,3,4], X rem 2 == 0]
umm is that supposed to show off Erlang? Maybe it's just me but for such a simple task that looks bad.
it was just for completeness, certainly not to show off, however list comprehensions are virtually identical to python and much more comprehensible than the line noise introduced in ruby list comprehensions.

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)

ugly is subjective - an opinion.
erlang is called out as being ugly purely from hearsay

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.

Ugh. Thanks for convincing me not to learn Erlang.
(comment deleted)

  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]
Put leading whitespace on the lines, with blank lines before and after.
J solution anyone?

  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

this misses the point, if you hard-code the result then still the other languages are more concise.
"Enterprise" developer at work here, folks!
The other examples filter from an existing list, essentially used as a placeholder. It could be substituted with any other list and the code sample would work. Your example use some hardcoded values - strings at that, not integers - hence not the same thing at all.
If you want to love Java - love it for the tooling. IDEs are bloated but the integrated features they provide - like built in profiler(Netbeans), postmortem analysis tools (Eclipse MAT), the ease of debugging it provides - remote attach, JConsole type stuff where you can visualize loads of interesting stuff while the JVM is still executing your program, things like EProf that comes with HP JVMs - it can be turned on and off dynamically with low overhead and no changes required - the sort of data it gives makes it a piece of cake to figure out what is going wrong (it even tells you during the profile which exceptions were thrown and how many times!).

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.)

This can be a lot shorter using Google Guava [1]:

        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.

[1] http://code.google.com/p/guava-libraries/

Or apache collections:

		CollectionUtils.filter(new ArrayList(Arrays.asList(1, 2, 3, 4)), new Predicate()
		{
			public boolean evaluate(Object v)
			{
				return ((Integer) v).intValue() % 2 == 0;
			}
		});
(comment deleted)
JAVA

for (int i:new int[]{1,2,3,4}) System.out.print(i%2==0?i:"");

hehe, clever! although we are building a new list in the other languages, we're never using it, so this is just as good in the immediate context.