Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ladies, look at your code. Now back to mine. (google.com)
281 points by mambodog on Aug 28, 2010 | hide | past | favorite | 74 comments


Perhaps Java8 will get multiline string literals -- an over-9-year-old request:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4472509

Lots of the shortsighted decisions in the historical bug database can be attributed to xxxxx@xxxxx, who dismissed this as "yet another request for a syntactic sugar to save some user from typing... not worth it." I sure hope Oracle has let xxxxx go by now!


Wow, what an ad hominem answer:

shankar.unni

I agree with the Evaluation, completely. This is truly pointless syntactic sugar, unless you're coming directly from the C# or Visual Basic world without ever having worked in any other language, and escape sequences are just too hard for you to comprehend.. (In which case, many other Java features would be, too..)

This is sad, some one offers a great language feature that will reduce bugs and save money and people respond with insults.


I find it ironic that a Java programmer is deriding other programmers (C# and VB) for not being "real" programmers.


That's narrow minded. There are some great Java programmers. It's just that they don't have the same priorities that you do.


I think you misunderstood me: I was saying that the notion of who is a "real" programmer is stupid. I really despise using PHP. Does that make everyone who works at Facebook not a "real" programmer?

However, the notion of a Java programmer deriding others for their language choice is even more ridiculous because of the comparative ease of the syntax. If the argument held any merit (which it doesn't), Java definitely wouldn't be on top of the "real programmer" mountain.


Considering that Javascript, Ruby, Python, C#, Perl, and even PHP have supported anonymous functions or lambda expressions, this advancement is a long time coming.


Oh God it's so much worse than that. You remember who was a coauthor on the original specification? Guy Steele. Yes, "Lambda Papers" Guy Steele. I have no idea how this has taken so long.

Oh and I thought this was hilarious. :)


While Steele's been involved with Lisp and Scheme, he also has a really long history of involvement with imperative languages, which he seems to have kept separate until recently. He's been on the C and Fortran standards committees, for example, and that hasn't caused much noticeable crossover of features like lambdas into those languages, either.


Well, that's true to a certain extent. Closures and such really just don't make sense in a C context, especially with manual memory management. Function pointers are probably the most implementation friendly solution in that problem space. I think Apple's blocks are the closest that we'll come, but I'd be hesitant to use them in certain subdomains.

Java, on the other hand, has a completely different application space and feature set. First class functions and anonymous functions seem like natural additions to the language.


He also co-authored the Java Language Specification (with James Gosling and Bill Joy.)

The wise are not dogmatic.


He's also responsible for^W^Wthe author of http://www.careferencemanual.com/ .


Damn, Fortran with lambdas-- that would be cool.


Guy's words: We were not out to win over the Lisp programmers; we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp.


I think it is also important to remember something else here. Guy Steele certainly had significant influence on Java, but he was far from the final decision maker. I'm sure there are tons of things he would have wished Java to have (or not have) but they weren't his call to make. If anything people should be grateful that he was involved at all, since Java would probably have been a lot worse off it he hadn't been.

And to top it off, Guy seems to have that rare combination of being simultaneously super smart and reasonably humble. I have never read anything he's written or listened to any talk he's given where I was not greatly impressed by him and what he had to say.

I don't think I've ever seen him comment on Hacker News. I wish we could get him to comment regularly here, as his knowledge and insight would be of great value.


Well said. I discovered Guy's work early in my programming career, and am very glad I did.


In 1996 C++ was much more difficult and fragmented, but that quote is from 2003. Today C++ has (much) more abstraction power than Java. On the other hand, almost every programming language has more abstraction power than Java, which knows only about classes, XML and design patterns.


We might be agreeing here already, but my understanding was that the mindset Java fought against -- and finally won -- was: Interpreted, garbage-collected languages, or basically anything with a substantial runtime component, will be too slow and unpredictable to use in serious production environments.

So Java went all-out with (1) a static type system and basic language features that C++ coders could respect, (2) a level of hype and corporate sponsorship/support that PHBs could respect, (3) a portable, eventually fast VM, opening up some nice deployment options. There was no need to introduce really exciting language features, only to keep promoting the OOP concepts that C++ thought-leaders were so enthusiastic about at the time.


> Today C++ has (much) more abstraction power than Java.

> almost every programming language has more abstraction power than Java

Just curious: how does that make C++ stack up against other "fashionable" languages?


Lots of languages are fashionable today, but most of them don't overlap with the use cases that are traditionally handled by C++.

Even so, it fares pretty good. What it lacks in expressive power it makes up in speed, libraries and industry support. C# is in my opinion a realistic C++ alternative or complement.


"In 1994, Steele joined Sun Microsystems and was invited by Bill Joy to become a member of the Java team after the language had been designed, since he had a track record of writing good specifications for existing languages." --Wikipedia


If Java were Haskell, the syntax would be "filter isPartTime".

It's silly to have to type stuff that's easily understood by both the programmer and the compiler.


It's sad that you can't easily chain these methods. e.g.

    employees.filter(predicate1).filter(predicate2).filter(predicate3)
instead of

    Iterables.filter(Iterables.filter(Iterables.filter(employees,predicate1), predicate2), predicate3)


That's what's nice about functional programming, where functions are functions, not thingies inside your object. You would write something like:

   filter predicate1 . filter predicate2 . filter predicate3 $ employees
Where . is function composition.


You still need to hope the fusion optimization kicks in there. It can be done faster with one filter over the list and then checking all three predicates at each element in some cases. I think the following will do the right thing:

  filter (\x -> p1 x && p2 x && p3 x) employees
which can then be made points-free.


Don't just hope, write it yourself!

  {-# RULES
    "filter/filter"  forall f g xs. filter f (filter g xs) = filter (f.g) xs
  #-}
It's a programmable programming language.


Don't you mean

  forall f g xs. map f (map g xs) = map (f.g) xs
?

As for filter, I presume something like

  forall f g xs. filter f (filter g xs) = filter (\x. g x && f x) xs
would work.


Yup,

  forall f g xs . filter f (filter g xs) = filter (\x -> g x && f x) xs
was exactly what I meant, thanks for the catch!


Nice. What's the limit on what you can do with these RULES? Could you extend the language? Write a DSL? Implement a mini-prolog à la On Lisp?


You can do a lot of weird stuff, but it's not the right place for that. Just use Template Haskell.


The beauty is that with Haskell's Lazy Evaluation, this is what would end up happening.


VarArgs usage would be even better:

employees.filter(predicate1, predicate2, predicate3);


Perl 6 would do that like this:

@employees.grep($predicate1 & $predicate2 & $predicate3);

The predicates can be a function, a regex, a type, or anything that can be smart-matched against.

Alternately, if you want to get the employees that match any of the predicates, you'd do the following:

@employees.grep($predicate1 | $predicate2 | $predicate3);

Or, if you want the employees that match only one of the predicates (think of xor):

@employees.grep($predicate1 ^ $predicate2 ^ $predicate3);

These can also be written, respectively, as:

@employees.grep(all($predicate1, $predicate2, $predicate3)); @employees.grep(any($predicate1, $predicate2, $predicate3)); @employees.grep(one($predicate1, $predicate2, $predicate3));

And, if you want things that match none of the predicates:

@employees.grep(none($predicate1, $predicate2, $predicate3));

You can combine these junction constructors. For example:

@employees.grep(all($predicate1, $predicate2) ^ $predicate3);


I think you will be, if they manage to get extension methods into this properly. Also, Google's Iterables could return a FilterableIterator or something like that, so you could at least chain after the first step.


In Scala you can just do:

employees.filter( _.isPartTime )

And it runs in the same virtual machine.


Joining the club, in Python:

[e for e in employees if e.isPartTime()]

You can even push it further:

[e for e in employees if e.isPartTime() or e.lazy() or e.havePassiveIncomeAlready()]

and further:

[e for e in employees if e.isPartTime() or e.lazy() or e.havePassiveIncomeAlready() or e in [exec for exec in BoardofDirector.all() if exec.haveTooManyPortfolio()]]

Above is your friendly neighborhood List Comprehension available since Jython 2.0


Yeah, that improved java is still pretty ugly for a JVM language. In groovy its:

employees.findAll { it.isPartTime() }


And in clojure it would be

    (filter :part-time? employees)


In Ruby:

employees.find_all &:isPartTime


And I liked employees.select {|employee| employee.part_time?}

Crikey, should buy a book...


Personally, I prefer your version; the &: version starts reeking of Perl line noise. Although I believe Ruby would benefit from an _ for not explicitly named block arguments.


As a random note for anyone who's wondering how this syntax came about, this is the Symbol#to_proc [1] method, which was actually a monkeypatch from Rails that ended up making its way back into Ruby proper.

1: http://ruby-doc.org/core-1.9/classes/Symbol.html#M000031


I agree, I also prefer the slightly longer version. OK, enough small talk ... :-)


Thank goodness Symbol#to_proc was introduced in Ruby 1.9, the Rails implementation of it was slow as hell: http://www.lukeredpath.co.uk/blog/optimising-symbol-to_proc....


That was fixed some time ago. It is very marginally slower to use Symbol#to_proc now (a constant time difference to actually create the Proc), but not enough to warrant a change in practical use.


Correct me if I'm wrong but I believe the C# compiler goes a step further and allows you to write those lambda arguments without the type annotation. Is there a technical reason why the Java compiler can't do the same?


C# will infer lambda argument types from context, yes. So the code given:

  return Iterables.filter(employees, {Employee e -> e.isPartTime()});
Would be in C# (Since you'd also omit the { } and use "=>" not "->") something like this:

  return Iterables.filter(employees, e => e.isPartTime());
And it is a better C# idiom to make "filter" an extension method on IEumerable<T>.

  return employees.filter(e => e.isPartTime());
In fact, the existing extension method "Where()" is what you want.

  return employees.Where(e => e.isPartTime());
C# has had this for about 2 years now. And it is good. So, I'm looking at your code, and back to mine. Mine is shorter but still very readable (to me anyway). And it stays readable when you chain methods, e.g.

  return employees.Where(e => e.isPartTime()).ToArray();
I'll stay with mine right now.


There was also a comment to the above saying that instead of writing:

  List<Ticket<ThingYouLove>> tickets = new ArrayList<Ticket<ThingYouLove>>();
You could write:

  List<Ticket<ThingYouLove>> tickets = new ArrayList<>();"
Nice, but I prefer C# there as well where you use the var keyword, like this:

  var tickets = new ArrayList<Ticket<ThingYouLove>>();


   Nice, but I prefer C# there as well where you use the var keyword, like this:

     var tickets = new ArrayList<Ticket<ThingYouLove>>();
Actually, JDK7 is better in this case because it helps developer to "program to an interface".


What do you mean, that you can do something like this?

  List<Foo<Bar>> list = new ArrayList<>();
Programming to an interface is relevant between method calls, not inside the scope of a single method, which is typically where you use the var keyword in C#. This is programming to an interface, in C#, using the var keyword:

  public List<Foo<Bar>> MyMethod(...) {
      List<Foo<Bar>> result = new ArrayList<Foo<Bar>>();
      ...
      return result;
  }

  var list = MyMethod(...); //list will be of type List<Foo<Bar>>
In Java, the above would then look like this:

  public List<Foo<Bar>> MyMethod(...) {
      List<Foo<Bar>> result = new ArrayList<>();
      ...
      return result;
  }

  List<Foo<Bar>> list = MyMethod(...);
You don't save more characters in either case, neither is promoting programming to an interface more than the other, but I still think the var keyword is the better construct, since it removes type declaration consistently. It basically means that the compiler should infer the type of the variable immediately, without me having to spell it out. The Java construct on the other hand means something like: "In the constructor to a generic class, infer the generic parameters from the type of the variable the result is assigned to", which is a weaker construct, a less expressive one, a less flexible one.

Both are still syntactic sugar implemented as compiler tricks, but the C# one simply does more.


Could you expand on what "program to an interface" means to you in this context, I'm not getting it. Assume that I know what it means in the usual context, of depending on the services of an interface type not a concrete type.


With the var keyword the variable will be the exact same type as what you initialize it to, not an interface.

  List<Foo> list = new ArrayList<Foo>();
...is programming towards an interface, whereas

  var list = new ArrayList<Foo>();
...isn't, because the type of list will be ArrayList. I think his point was that with the new Java stuff you could instead do

  List<Foo> list = new ArrayList<>();
...which would then be explicitly programming towards an interface, while still not having to type so bleeding much.


Programming to an interface just doesn't seem so useful within the scope of a method.


It's interesting that the latest Java does not include the var keyword, as JavaFX (which is modeled after JavaScript) uses the var keyword and does type inference on regular Java types.


You have to use => instead of ->. This got me many times too ;)


Good point - this is the first time it's got me, but then I don't look at much java.


Minor nitpick: The lambda operator in C# is "=>"


Whoops, I have fixed that cut-and-paste error. I hadn't noticed that the java code had another gratuitous difference.


I'm really glad that JDK 7 finally has diamonds. (In more ways than one: http://weblogs.java.net/blog/forax/archive/2009/08/27/diamon...)


> I'm on a horse.

And quite possibly very drunk.

edit: oh I get it, he's referring to http://www.blogher.com/im-horse-old-spices-man-your-man-coul.... This is what I get for not watching tv anymore, I guess.


Or even HN? There was a fair amount of coverage of the Old Spice man on here when they were doing their nonstop live commercial shoots.


I spend a fair amount of time reading HN, but this is one of the topics I skipped over.


He should have thrown in the new feature for meaningless underscores in numeric literals. I've always wanted this feature in every language, since 1_000_000 is so much more readable than 1000000 or 106.


Did this strike anyone else as being mildly chauvinistic?


It's a parody of an Old Spice commercial (official version at http://www.youtube.com/watch?v=owGykVbfgUE ).


Wow, nevermind then. That was hilarious.


And since you missed it - about a month ago Old Spice did a great internet level promotion with this ad - answering questions from facebook / reddit / youtube / twitter. And cleverly targeted videos at people like Kevin Rose. It was really impressive. HN had the post about how they did it here: http://news.ycombinator.com/item?id=1516195 And the key discussion about the campaign was here: http://news.ycombinator.com/item?id=1512225

You can see the full list (that does get rather repetitive -- although keep in mind they were coming out about every 20 minutes for 2 days straight) here: http://www.youtube.com/user/OldSpice#p/u


Thanks for speaking up about chauvanism though! :)


"If you want to sound like a creep, just add the word 'ladies' to the end of things that you say" -- Demetri Martin

http://www.youtube.com/watch?v=TBcxwrNTpGg#t=1m38s


Now I want to see the Old Spice guy make a response video to this... or maybe just read this aloud.


Which of those two styles is being presented as superior?


So funny and i'm not even a geek!


Im on a horse. Freaking awesome.


Awesome - love it.


go Java! catching up a little more with Python. Meanwhile, back to my Python hacking session...




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

Search: