I just started hating Java

By Confusion on Thursday 7 January 2010 15:42 - Comments (32)
Categories: Java, Python, Software engineering, Views: 8.321

A new year, a new hatred. I've just officially begun hating the language in which I do most of my work: Java. The tiresome verboseness finally got to me. Please compare with me:


Java:
1
2
3
4
5
6
7
8
9
10
11
12
private static String joinObjectFields(final List<SomeObject> objects, 
        final Character seperator, final SomeObject exclude) {

        String result = "";
        for (SomeObject object: objects) {
            if (!object.equals(exclude)) {
                result += object.someField + seperator;
            }
        }
        // Strip last ; (and see edit3)
        return result.substring(0, result.length() - 1);
    }




Python:
1
2
3
4
def joinObjectFields(objects, seperator, exclude):

  fields = [object.someField for object in objects if object != exclude]
  return seperator.join(fields)



To prevent "these pieces of code don't do the same thing", an alternate Java implementation, more like the Python one:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static String joinObjectFields(final List<SomeObject> objects, 
        final Character seperator, final SomeObject exclude) {

        final String[] fields = new String[objects.size()];
        for (int i = 0; i < fields.length; i++) {
            if (!object.get(i).equals(exclude)) {
                fields[i] = object.someField;
            }
            else {
                fields[i] = "";
            }
        }
        return StringUtils.join(fields, ';');
    }


Doesn't get much better, even if you would initialize the array to contain "" in every field using a utility method.

For extra hatred, consider the necessary changes to the code to enable the same method to join the contents of a different object field.

Edit: A colleague noted that cloning the list and removing the 'exclude' would make matters slightly better.

Edit2: And before someone starts calling me a Python fanboy: you can also do this in a much shorter fashion in Scheme, Ruby, Perl, Scala, Lisp/Clojure, etc.

Edit3: And of course I stupidly forgot to check whether result.length() is actually > 0 in the first implementation.

Edit4: As JanDM rightly points out, I shouldn't use curly braces in Python :P.

Edit 5: This version in Java, posted by Markus in the comments, is far superior: I wasn't making any sense here: the code does a different thing.

Volgende: Harvesting energy from WiFi and GSM networks? 01-'10 Harvesting energy from WiFi and GSM networks?
Volgende: Debian, aptitude update: segmentation fault. 11-'09 Debian, aptitude update: segmentation fault.

Comments


By Tweakers user YopY, Thursday 7 January 2010 16:08


Java:
1
2
3
4
5
6
7
8
9
10
private static String joinObjectFields(final List<SomeObject> objects, final Character seperator, final SomeObject exclude) {
    StringBuilder builder = new StringBuilder();
    for (SomeObject object : objects) {
        if (object.equals(exclude)) continue;
        if (builder.length() > 0) builder.append(separator);
        builder.append(object.someField);
    }
    return builder.toString();
}
}



Shoter and more efficient. Also, some notes:

* The Python implementation is not declared private or static. From the example, I can't see who can access it and from what scope.
* The Python implementation's parameters are not declared final, although they may be final by default in Python, not sure.
* The second Java implementation adds a semicolon even if the field isn't empty - as far as I can see (read: expect, I don't know Python), the Python implementation doesn't do this.
* Python doesn't have types, so that one is less safe. What if I call joinObjectFields with an object of type Henk that doesn't have a property someField? Type error.

imo, verbose is good. Non-verbose (and uncompiling) java version without types or verbose additional method and parameter keywords:


Java:
1
2
3
4
5
6
7
8
9
joinObjectFields(objects, seperator, exclude) {
    builder = new StringBuilder();
    for (object : objects) {
        if (object.equals(exclude)) continue;
        if (builder.length() > 0) builder.append(separator);
        builder.append(object.someField);
    }
    return builder.toString();
}



Thus. Not saying Java's better than Python, it just works differently. And verboseness isn't something bad per sť - it gives you much more control when you need it.

Also, it makes little sense to me to have a join() method on a character / string object that uses the object itself as separator between the elements of a list. That, or I don't get it.

(Although it's true that I would like a syntactic sugar feature added to Java that allows you to iterate through a certain field (accessor) of a list of objects)

[Comment edited on Thursday 7 January 2010 16:09]


By Tweakers user Kettrick, Thursday 7 January 2010 16:24

Havent got time to do testing for you atm; but this might be usefull :

http://commons.apache.org...ject,%20java.lang.Object)

By Tweakers user Luuk1983, Thursday 7 January 2010 16:25

In C# is het met Linq wel makkelijker geworden, ik kan het namelijk in 1 regel ;)


C#:
1
2
3
4
5
6
7
8
private static string joinObjectFields(List<SomeObject> objects, 
    string separator,
    SomeObject exclude)
{
    return String.Join(separator, objects
        .Where(obj => !obj.Equals(exclude))
        .Select(obj => obj.SomeField).ToArray());
}

[Comment edited on Thursday 7 January 2010 16:26]


By Tweakers user Confusion, Thursday 7 January 2010 16:28

Unfortunately, your code would turn out as follows in most places, so it actually isn't shorter:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static String joinObjectFields(final List<SomeObject> objects, 
    final Character seperator, final SomeObject exclude) { 

    StringBuilder builder = new StringBuilder(); 
    for (SomeObject object : objects) { 
        if (object.equals(exclude)) {
           continue; 
        }
        if (builder.length() > 0) {
            builder.append(separator); 
        }
        builder.append(object.someField); 
    } 
    return builder.toString(); 
} 
}


This is required for readability, but uses costly vertical screen real estate. The point is not just number of lines that is annoying: also the number of characters and operations/keywords/constructs required. A page of Java looks like a mess and is harder to understand than an page of Python or Scheme, once you get used to the syntax.

As for efficiency: I doubt it's more efficient. AFAIK, a moderately recent JVM will use a StringBuilder/StringBuffer anyway.
* The Python implementation is not declared private or static. From the example, I can't see who can access it and from what scope.
Very often I don't care, especially not with these kinds of utility methods. A single visibility of 'public' is just fine with me. If a method should not be called, I'll mark it as such.
* The Python implementation's parameters are not declared final, although they may be final by default in Python, not sure.
In effect they are (because you can't change what the original variable points to), but variables being final isn't very interesting, as the problem is usually the contents of lists, maps and objects being altered. Moreover, 'final' should have been the default in java.
* Python doesn't have types, so that one is less safe. What if I call joinObjectFields with an object of type Henk that doesn't have a property someField? Type error.
Python most definitely does have types, though no compile-time typechecking. However, appropriate unit-tests will catch that, without explicitly checking the type.

I will present a Scala example shortly, to show that type-safety, clarity and terseness can go hand-in-hand.

[Comment edited on Thursday 7 January 2010 17:30]


By Tweakers user JanDM, Thursday 7 January 2010 17:24

I hate to nitpick, but there is a typo in your Python example (curly braces instead of a colon):

Python:
1
2
3
def joinObjectFields(objects, seperator, exclude):
    fields = [object.someField for object in objects if object != exclude]
    return seperator.join(fields)


I agree with your point though, Python is a great language and it still surprises me how clear and concise it looks compared to most other languages.

The last line from your Java code, for example:

Java:
1
return result.substring(0, result.length() - 1);


could be written in Python as:

Python:
1
return result[:-1]


:)

[Comment edited on Thursday 7 January 2010 17:25]


By Tweakers user DexterDee, Thursday 7 January 2010 17:25

Exercise in PHP:

PHP:
1
2
3
function joinObjectFields($objects, $separator, $exclude) {
    return implode($separator, array_diff($objects, $exclude));
}


Unfortunately this requires the magic reflection method __tostring to be set on the objects in the array, returning the someField string. Otherwise the example will be much more verbose, even with the quite powerful array manipulation methods that PHP posesses.

[Comment edited on Thursday 7 January 2010 17:25]


By Tweakers user Confusion, Thursday 7 January 2010 17:29

could be written in Python as:


Python:
1
return result[:-1]

Which also has the nice property that, as long as result was initialized, it doesn't throw an exception, but does what you want in the majority of situations: return an empty string

[Comment edited on Thursday 7 January 2010 17:29]


By Tweakers user RayNbow, Thursday 7 January 2010 18:00

In short, Java sucks at composability.
For extra hatred, consider the necessary changes to the code to enable the same method to join the contents of a different object field.
And this is example scenario shows it. Your original joinObjectFields does several things:
  • Filtering (not processing the exclude value)
  • Mapping (mapping SomeObject instances to a value that's showable)
  • Folding or reducing a list of values to a single value (in this case, a String)
In a language with first class functions (and function composition), a generalized joinObjectFields can be easily composed:

Haskell:
1
2
3
4
5
6
7
joinFields exclude field sep
 = intercalate sep . map (show . field) . filter (/= exclude)
{-       ^             ^                    ^
         |             |                  step 1, filtering
         |           step 2, mapping
       step 3, reducing the list to a single value
-}


This function takes 4 arguments, namely the value to exclude, a field selection function, a String seperator (not a character as in your original function), and finally the list containing the objects.

In case you're wondering where the 4th argument is being mentioned in the above definition, well, it isn't. It has been eta-reduced:

Haskell:
1
2
3
-- equivalent definition without eta-reduction
joinFields exclude field sep objects
 = (intercalate sep . map (show . field) . filter (/= exclude)) objects


(Things of form f x = e x can be eta-reduced to f = e, provided that x does not appear in e)

For completeness' sake, but not necessary in a language with type inference, the type of this function is:

Haskell:
1
joinFields :: (Eq a, Show b) => a -> (a -> b) -> String -> [a] -> String

[Comment edited on Thursday 7 January 2010 18:07]


By Tweakers user Neverwinterx, Thursday 7 January 2010 18:44

The python code is a nice example of overuse of syntactic sugar in a language. Creating separate syntax for every little use case leads to this. It's rather typical for functional languages. May also be one of the reasons why functional languages aren't popular.
Personally I'd rather read and maintain the java code than your python code.

By Tweakers user Phyxion, Thursday 7 January 2010 18:56

Zou net zeggen, met Linq in C# is het wel erg makkelijk geworden :)

By Tweakers user kipusoep, Thursday 7 January 2010 18:59

Helemaal eens met Phyxion, Linq ruleert! :D

By Tweakers user RSpliet, Thursday 7 January 2010 19:16

Spoilt brat! ;)

ABAP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FORM join_objf
    USING pt_objects TYPE ltt_someobject
          pc_separator TYPE c.
          po_exclude TYPE lt_someobject
    CHANGING ps_return TYPE string.

    DATA lo_object LIKE LINE OF pt_objects.
    
    LOOP AT pt_objects INTO lo_object.
        IF NOT lo_object = lo_exclude.
            IF ps_return IS NOT INITIAL.
                CONCATENATE ps_return
                        lo_object
                INTO ps_return SEPARATED BY pc_separator.
            ELSE.
                ps_return = lo_object.
            ENDIF.
        ENDIF.
    ENDLOOP.
ENDFORM.

[Comment edited on Thursday 7 January 2010 19:21]


By Andre, Thursday 7 January 2010 19:16

And to add to the language comparison:


Ruby:
1
2
3
def join_object_fields(objects, separator, exclude)
   objects.delete_if{|o| o == exclude }.join(separator)
end


By Tweakers user Giant87, Thursday 7 January 2010 19:24

I started hating Java when I installed the JDK ^^.

By Tweakers user ToFast, Thursday 7 January 2010 20:19

I dont care you start to hate java :) if you think deeper about your comparing, what will it help you? Go write everything in Python then..

By Tweakers user RayNbow, Thursday 7 January 2010 20:24

The python code is a nice example of overuse of syntactic sugar in a language. Creating separate syntax for every little use case leads to this.
I strongly disagree. List comprehensions are not a "little use case". Why do you think things like set-builder notation, LINQ, SQL, etc. exist? We'd like to be able to clearly and succinctly express operations over collection-like structures.
It's rather typical for functional languages.
I'd classify Python as an imperative OO language with a few functional features, rather than a functional language.

Anyway, I'd like to know how you came to the conclusion that syntactic sugar is typical for functional languages? Syntactic sugar can also be found in imperative languages (e.g. string literals in C, foreach in Java, yield in C# and Python).
May also be one of the reasons why functional languages aren't popular.
Excel is the most popular functional language.
Personally I'd rather read and maintain the java code than your python code.
You're feel free to do so, but I'd rather read something like

Haskell:
1
intercalate sep . map (show . field) . filter (/= exclude)


that clearly shows the function is composed of three simpler things.

[Comment edited on Thursday 7 January 2010 20:26]


By Tweakers user webkiller71, Thursday 7 January 2010 20:55

quote: RayNbow
This function takes 4 arguments, namely the value to exclude, a field selection function, a String seperator (not a character as in your original function), and finally the list containing the objects.
The python example accepts a string as well.

I must say that after the haskell colleges, I started using python a lot more. List comprehesion, lambda functions, higher order functions. Haskell can do those better thanks to currying the arguments, but I like that python can do this stuff as well. Something I really really miss in Java. Just like the example in this blog.

By Tweakers user ChaosR, Thursday 7 January 2010 21:00

And to add to the language comparison:


Ruby:
1
2
3
def join_object_fields(objects, separator, exclude)
   objects.delete_if{|o| o == exclude }.join(separator)
end


Ruby:
1
2
3
def join_object_fields(objects, separator, exclude)
   objects.select{|o| o != exclude }.join(separator)
end



Anders raak je waarschijnlijk objecten kwijt die je niet wil kwijt raken. In ruby is alles een reference ;).

By Tweakers user Confusion, Thursday 7 January 2010 21:05

@RayNBow

It may very well be easy to understand f you're used to Haskell, but at the moment, it's gibberish to me. In Python you could also write

Python:
1
2
3
4
field = operators.attrgetter('field')
def joinObjectFields(objects, seperator, exclude):
  def notExclude(x): return x != exclude
  return seperator.join(map(field, filter(notExclude, objects)))


But then I really prefer the list comprehension :P. I'm not at all convinced that purely functional code, involving the usual maps, filters and reductions, is in fact usually easier to understand.

@Neverwinterx
Scheme is a functional language. You can hardly accuse it of overusing syntactic sugar, now can you? ;) Anyway, the point Lispers always make is: if you need syntax, you can make your own. And in fact: a Python list comprehension is only a few transformations away from a plain S-expression.

[Comment edited on Thursday 7 January 2010 21:21]


By Tweakers user Neverwinterx, Thursday 7 January 2010 21:10

I strongly disagree. List comprehensions are not a "little use case". Why do you think things like set-builder notation, LINQ, SQL, etc. exist? We'd like to be able to clearly and succinctly express operations over collection-like structures.
Of course, but there's a tradeoff of the increased complexity. Which is arguably worth it.
I'd classify Python as an imperative OO language with a few functional features, rather than a functional language.
I'm aware of that, didn't say it was a purely functional language.
Anyway, I'd like to know how you came to the conclusion that syntactic sugar is typical for functional languages? Syntactic sugar can also be found in imperative languages (e.g. string literals in C, foreach in Java, yield in C# and Python).
Notice the link made by "It's" in my sentence. It should be read as "overuse of syntactic sugar is typical ...". I'd like to add that by this i mean obscure syntactic sugar with all sorts of special symbols.
For example this scala code:

code:
1
2
3
for(tpTerm <- typeOf(term);
            (from, to) <- isTArr(tpTerm);
            _ <- isEqual(from, to, "some text")) yield from


Add any more syntactic sugar and your language starts to resemble Brainfuck.

Name the most popular languages of recent decennium/decennia:
C
C++
Java
C#
(and even older stuff that has to be maintained, can be ignored further)
See what they have in common?
The C-like syntax amongst other things. Ever noticed how the C-like syntax is easy to read? It's almost English. Try to read functional languages (or the parts of other languages with functional features) out loud: you'll understand what i mean.
The right amount of sugar is the key to a good language: not too much, not too little, not too verbose, not too symbollic.
Excel is the most popular functional language.
You are well aware of the fact that this is ridiculous. 99% of the functions in Excel is just basic math and doesn't even come close to what a functional programming language does differently from imp languages. A3 = A2 * 5/9 works in a non-functional imp language as well.
Haskell example
Give people a course in Java and Haskell and show them that code and the java equivalent. Have a guess which version will be understood faster. I am willing to bet plenty of money on java. :p

@Confusion
typical != always

[Comment edited on Thursday 7 January 2010 21:14]


By Tweakers user Confusion, Thursday 7 January 2010 21:20

@NeverwinterX
Of course typical != always, but I doubt whether Python really has a relatively large amount of syntactic sugar. When considering all 'common' languages (in which I include things like Haskell, OCaml, AWK and R), then I expect Python to be in the lower regions qua amount of syntactic sugar. Also, I wonder whether there is truly a clear difference between functional and non-functional languages (as far as that difference can be made). If anything, a functional language generally needs less syntactic sugar to attain the same level of expressivity?

[Comment edited on Thursday 7 January 2010 21:25]


By Tweakers user Apache, Thursday 7 January 2010 22:00

Yes, hate Java because of a little verboseness/lack of syntactic sugar.

I'm also a fulltime J2EE developer and there is a lot more that makes java interesting to do, the frameworks for example. High quality, nice concepts, flexibility, dotnet just seems to get poor ripoff's of what java has (nhibernate?) ...

And the tooling is also good, eclipse and all the plugins/projects they offer, mylyn rocks and has no equivalent. (afaik)

Nice architectures with ESB's, fault tolerant clustered systems, combined with nice powerfull databases, usually pretty fancy hardware, focussing on stuff like this just seems a bit too nitpicky, even for my taste ;)

(btw java7 will get some more advanced methods for collections)

By Tweakers user RoadRunner84, Thursday 7 January 2010 22:10

>The python code is a nice example of overuse of syntactic sugar in a language. Creating
>separate syntax for every little use case leads to this.

I strongly disagree. List comprehensions are not a "little use case". Why do you think things like set-builder notation, LINQ, SQL, etc. exist? We'd like to be able to clearly and succinctly express operations over collection-like structures.
It is syntactic sugar, and it is a good thing. Whether or not it is overuse bepends on your expectations of a language. If your applications do a lot of list manipulation (or even do things to arrays) this function is not bloated, it may be too easy on you, but it is very useful.
I might say that call-by-reference in c++ is an overuse of syntactic sugar, because the very same thing can be accomplished using dereferenced call-by-value (ie.: use &a to feed int* pa to a function works just as fine as feeding "a" to a function expecting int& a).
I might say that SQL overuses syntactic sugar because it supports JOIN, which could be done using lookup loops in my frondend on a table retrieval. But it being overuse is not an opinion you're gaining much friends with.

By Tweakers user Confusion, Thursday 7 January 2010 22:25

@Apache

I'm doubting the added value of all these popular frameworks more and more. I spend way too much time figuring out how to do a certain thing in a framework, when I could have written the necessary code in half the time. Spring, Hibernate, Struts: these aren't flexible enough. If you want something nonstandard, you can only do it through an arcane invocation, instead of providing the ability to drop back to a lower level to do it. I've started preferring more lightweight frameworks.

By Tweakers user Herko_ter_Horst, Thursday 7 January 2010 23:45

Don't worry: closures are coming in Java 7.

By Tweakers user TeeDee, Friday 8 January 2010 00:30

@Apache: wait what? All the things you say Java has over .net, you can say that .net has. I don't know what the latest version is you've compared, but ever since 2.0, maybe 3.0 and up, .net is just a breeze to work with. Sure it has it's quirks, so does Java. .net has a poor ripoff like nhibernate? Couldn't agree more, but that's just the implementation of (n)hibernate. If you look at LLBLGen it just works.

Tooling? Did you work with Visual Studio? Not the crappy 2001 version, but 2003 and up.

And a 'nice powerfull database' has what to do with the language/framework you're working with?

Regarding the Frameworks: every language has it's own framework. They all do cool stuff. I've been working with Silverlight a year or more and all frameworks I've tested and tried look cool at first, but whenever you want to do that little extra: give up, drop the framework, do it yourself, skip the framework and conclude it's faster than the awesome cool framework you're using.
One of the basic principles: the right tool for the job!

By Dave, Friday 8 January 2010 10:12

Another thing that I dislike about Java is BigDecimal:

BigDecimal pct = item1.multiply( new BigDecimal( "100" ) ).
divide( item2 ).
setScale( 2, BigDecimal.ROUND_HALF_UP );

Why don't they include a decimal type in the language? And why don't they allow numbers to be used as parameters (so you don't have to wrap the string "100" in a BigDecimal)?

By Markus, Friday 8 January 2010 10:23

Languages with build-in list comprehension have somewhat of an advantage in this case. Still, a somewhat better Java implementation might look like this:
public void testJoinExclude(){
assertEquals("1, 2, 4", joinExclude(Arrays.asList(1,2,3,4), 3, ", "));
}

public <T> String joinExclude(final List<T> objects, final T exclude, final String separator){
List<T> rs = new ArrayList<T>(objects); // don't touch the original
rs.remove(exclude);
return StringUtils.join(rs, separator);
}

By Tweakers user Arfman, Friday 8 January 2010 10:48

Java sucks donkeyballs.

By Tweakers user Confusion, Friday 8 January 2010 11:22

@Markus

That's not just better: it's far superior. Originally, I excluded one item based on a field value, so I needed to iterate over the list anyway. I later changed that (by implenting a proper equalsI() on SomeObject) , but didn't reconsider to realize that would allow simpler version. I guess I was too busy thinking how easy it would be in other languages >:)

I'm not making any sense: your version concatenates the object(.toString)s, while the original problem is concatenating field values.

[Comment edited on Friday 8 January 2010 13:58]


By Tweakers user RayNbow, Friday 8 January 2010 13:33

@Confusion
It may very well be easy to understand f you're used to Haskell, but at the moment, it's gibberish to me. In Python you could also write

*snip*

But then I really prefer the list comprehension :P. I'm not at all convinced that purely functional code, involving the usual maps, filters and reductions, is in fact usually easier to understand.
In Haskell list comprehensions are also possible:

Haskell:
1
intercalate sep [show (field obj) | obj <- objects, obj /= exclude]


It depends on the situation whether you want list comprehensions or explicitly use filter and map. In Python list comprehensions are often preferred since you can't do function composition in a clean way like in math or Haskell:

code:
1
2
3
4
5
6
7
8
9
-- usual math notation:
(f . g)(x) = f (g(x))

-- Haskell eschews parentheses and uses 
-- juxtaposition instead for function application:
(f . g) x = f (g x)

-- (Math on the other hand eschews multiplication 
-- operators and uses juxtaposition instead)


Since you don't have function composition in Python, you are forced to write things like f(g(h(x))) when you want to glue 3 functions together. In Haskell you can write (f . g . h) which is much cleaner. Or in case you don't want to read from right to left, you could use a flipped composition operator (from the Arrow module):

code:
1
(h >>> g >>> f) x


Now, if you also want the argument to appear on the left side, you could easily write a flipped function application operator:

code:
1
2
infixl 0 |>
x |> f = f x  -- NB: this pipeline operator is predefined in F#


And then you could write the following code:

code:
1
x |> h >>> g >>> f




@Neverwinterx
Notice the link made by "It's" in my sentence. It should be read as "overuse of syntactic sugar is typical ...". I'd like to add that by this i mean obscure syntactic sugar with all sorts of special symbols.
With all due respect, but that's not syntactic sugar. Syntactic sugar are constructs that can be desugared to a "simpler" constructs that already exist in the language. Some Haskell examples:

Haskell:
1
2
3
4
5
6
7
8
9
-- Syntactic sugar         Desugared
----------------------------------------------
[1,2,3,4]             =    1:(2:(3:(4:[])))
[1..4]                =    enumFromTo 1 4
[1..]                 =    enumFrom 1

(+4)                  =    (\x -> x+4)
(4+)                  =    (\x -> 4+x)
-- (NB: the slash stands for lambda)


A simple C# example:

C#:
1
2
3
4
5
6
7
var foo = from n in ns 
          from m in ms 
          select n + m; 

// is equivalent to:
var foo = ns.SelectMany(n => ms, 
    (n, m) => n + m);

For example this scala code:

*snip*

Add any more syntactic sugar and your language starts to resemble Brainfuck.
I'm not familiar with Scala, but that code reads perfectly fine. Parentheses and semicolons are not uncommon in C-style languages, so that can't be the problem if you don't understand the code. All that remains is the <- symbol. It doesn't take too much imagination to see it represents a left arrow. Arrows have been used in plenty of languages and computer science textbooks to mean some form of assignment.
Name the most popular languages of recent decennium/decennia:
C
C++
Java
C#
(and even older stuff that has to be maintained, can be ignored further)
See what they have in common?
Without any given criteria and sources, I'm not convinced that your list is a faithful representation of popular languages.
The C-like syntax amongst other things. Ever noticed how the C-like syntax is easy to read?
It isn't. I can quite remember well from my youth (coming from BASIC) that I despised the C syntax at first. It takes time to get used to a different syntax, but then again, it might be human nature to be afraid of unknown things.
It's almost English.
Nice try, but BASIC and Python resemble English more than C-style languages.
Try to read functional languages (or the parts of other languages with functional features) out loud: you'll understand what i mean.
Sure, let's try this example:

code:
1
[show (field obj) | obj <- objects, obj /= exclude]


"The list containing the values show (field obj), for which obj comes from objects and obj is not equal to exclude."

Really, it is just an ASCII version of math.
You are well aware of the fact that this is ridiculous. 99% of the functions in Excel is just basic math and doesn't even come close to what a functional programming language does differently from imp languages. A3 = A2 * 5/9 works in a non-functional imp language as well.
First of all, a program written in a purely functional language like Haskell is nothing more than a bunch of equations. An Excel spreadsheet is, guess what, nothing more than a bunch of equations.

Secondly, while you could write "A3 = A2 * 5/9" in an imperative language, variables in imperative languages often have a different meaning. In imperative languages variables are a name for a memory location, a box to store stuff in. That line written in an imperative language would be a statement: "The box labeled A3 now contains the value obtained by taking the contents of box A2 and multiplying it by 5/9".
In math and in purely functional languages, that line is an equation. No matter what the value of A2 is, A3 will always be equal to 5/9 of A2.
Give people a course in Java and Haskell and show them that code and the java equivalent. Have a guess which version will be understood faster. I am willing to bet plenty of money on java. :P
People who have been taught Haskell ought to know what function composition is. With a blink of an eye they can see the three transformations that take place. The only difficulty of my code example is when your vocabulary is lacking and you don't know what the word intercalate means. In that case, I could use the fact that the following equation holds

code:
1
intercalate x = concat . intersperse x


and substitute this into my original code fragment:

code:
1
concat . intersperse sep . map (show . field) . filter (/= exclude)


Assuming intersperse and concat are well-known words, this piece of code is even easier to read than my original version.

@Herko_ter_Horst
Don't worry: closures are coming in Java 7.
When? ;)

By superfav, Friday 12 November 2010 23:29

In the meantime, you have lambdaj.
http://code.google.com/p/...jFeatures#Joining_strings

Using Markus code as a base, I think something like this should work using lambdaj:

public <T> String joinExclude(final List<T> objects, final T exclude, final String separator){
List<T> rs = new ArrayList<T>(objects); // don't touch the original
rs.remove(exclude);
return joinFrom(rs, separator).getSomeField();
}

Comments are closed