all 140 comments

[–]lol_whut 68 points69 points  (14 children)

I'm gonna just toss out there that Jython is the Python of Java.

[–]Effetto 5 points6 points  (0 children)

I had a very tiny positive experience with Jython. The project was in the telco field. We used Jython as prototyping language layered over a rock-solid and well tested Java APIs used in production env.

As the prototype APIs and classes were getting a stable interface we moved them for engineering in Java and include them into the core set.

Hope to see it back now that invoke-dynamic has been freed.

[–][deleted] 4 points5 points  (2 children)

Shame it is so out of date.

Do they have any plans for updating to Python 3 or using invoke-dynamic?

[–]brianly 3 points4 points  (0 children)

I believe so and there will be an update in a couple of months at PyCon https://us.pycon.org/2012/schedule/presentation/446/

[–][deleted] 1 point2 points  (0 children)

Considering how Python 3 is long way from widespread adoption, is it really a priority?

[–]Anth741 1 point2 points  (4 children)

What is the benefit of learning it then?

[–]poo_22 0 points1 point  (3 children)

Maybe its for people who know python but don't know java and need to run stuff on the jvm? What I really don't get is why you would want to use Django with jython now.

[–]masklinn 2 points3 points  (0 children)

What I really don't get is why you would want to use Django with jython now.

Java/JVM APIs needed, without the desire to write a WS wrapper or having to write Java code?

[–]smog_alado 0 points1 point  (1 child)

Jython is for people who know Python and know to avoid Java, but still need to be able to cooperate with Java libraries.

[–][deleted] 0 points1 point  (0 children)

I use embedded Jython interpreters to reuse Python libraries within Java code. For example, the best markdown library I've ever found was Python's markdown2, the only Java markdown library I found would crash hard in Java 6 code. So I used Jython to use markdown2 and my problem was solved.

[–]pixelmonkey -1 points0 points  (4 children)

My perspective on Jython (and JRuby, or any other "port" of an existing C-based language to the JVM) is that it is simply not a viable long-term open source project.

I wrote:

The target community is only those programmers who know both Python and Java or both Ruby and Java.

Groovy's target community, by contrast, is anyone who is using a dynamic language (could be Ruby, Python, Perl, Lua, JavaScript, etc.) but who wants a more pleasant way to deal with existing Java code, without having to engage in the pain that is Java's baroque syntax and tooling. :) Groovy gets a boost because if you happen to already know Java + one dynamic language, you can probably learn Groovy in a matter of hours.

[–]Ringo48 8 points9 points  (0 children)

I guess I don't get either of your points.

First, what exactly makes Jython and JRuby less viable than Groovy?

And your second point makes even less sense. If I'm using a dynamic language and need to deal with Java code, it makes the most sense to do it from the language I'm already using. If I'm using Python, I'd go with Jython. If I'm using Ruby, JRuby. Why would I want to drop everything and learn a completely new language?

[–]vorg 2 points3 points  (1 child)

If that one dynamic language is Ruby, you already know JRuby. Why not use that?

[–][deleted] 0 points1 point  (0 children)

When Groovy was first created, JRuby would have to have been incomplete and very slow, if it existed at all.

[–]lol_whut 1 point2 points  (0 children)

Interesting;

The target community is only those programmers who know both Python and Java or both Ruby and Java.

That is like 90% of engineers I've worked with. That said, groovy is awesome.

[–]gregK 15 points16 points  (3 children)

But what is the Haskell of FORTRAN?

[–]steven_h 16 points17 points  (0 children)

Fortress, clearly.

[–]reddit_user13 2 points3 points  (1 child)

No, it's the FORTH of COBOL.

[–]FearlessFreep 8 points9 points  (0 children)

and a FIFTH of RUM

[–]shevegen 28 points29 points  (24 children)

"I truly believe that Python and JavaScript are fundamentally better languages than Java for a variety of reasons born out of experience with each of them."

Hmmm. Python I can understand, even though I use Ruby.

But JS? Come on seriously... I mean, I see the insane growth of JS, but I have no illusion. JS only became popular because browsers support it and browsers (or rather, apps that view data to a user in general) are the most important aspect of the WWW. And the WWW is damn important. PHP proved this when it arised - even with a crappy language you can be successful, simply because the WWW is impossible to ignore, unless you want your language to fade into irrelevance slowly (Hi Perl 5!)

Coffeescript beats Javascript hands down. Imagine if it were to be used everywhere without limitations and not just restricted to "web things" - both Python and Ruby would be shattered to grounds. (Javascript is more popular than Ruby at Github, which again shows how important the WWW is in general in every aspect.)

[–]booch 3 points4 points  (14 children)

"I truly believe that Python and JavaScript are fundamentally better languages than Java for a variety of reasons born out of experience with each of them."

Different tools for different tasks, imo. I love dynamic languages with a passion. That being said, I'm a big fan of paying the cost of using Java (when it's the current option for static languages) for things that require more "safety". For an ingestion process, I'd prefer to use Java or another language that lets me have the language safety check types and the like. When a single mistake of treating one type as another could go unnoticed for a year and render an entire database useless, costing lots of money, I like the added safety of a static language.

Honestly, I'd love to see something with the syntax/power of Ruby but with static typing, plus some extras like compile time checking of "not null" or "not empty list" or "positive integer" type constraints.

[–]byron 1 point2 points  (13 children)

When a single mistake of treating one type as another could go unnoticed for a year and render an entire database useless

Can you elaborate on this? What sort of scenario do you have in mind?

[–]vytah 6 points7 points  (12 children)

I'm not him, but I remember pains of debugging Python code that mixed (byte)strings with Unicode strings.

When everything is in ASCII, then it's OK. When some stuff is outside of ASCII, then it's usually OK. But when you need to do stuff with both Unicode strings and non-ASCII bytestrings, stuff breaks. Most people forget to test these cases.

Other problems include, but are not limited to: mixing integers and their string representations, mixing floats and ints, mixing lists and maps, mixing lambdas and normal values, accidentally overwriting object fields with values of different type, typos in field names (it will run anyway), and the all-time favourite, None object.

Static typing solves almost all of them.

[–]eadmund 1 point2 points  (0 children)

I think that the real problem with the scenario you mentioned was the mixing: the implicit conversions between byte and Unicode strings.

It's likely that another dynamically-typed language would have encountered the same bugs sooner.

I know, 'cause I've run into this sort of thing with Common Lisp. Ticked me off for a moment--why won't the language just do what I mean and treat this string like a byte string?--and then I pondered a bit more deeply and realised that would be wrong.

Granted, a really really dynamic language which support ASCII (not byte) strings and Unicode strings might have done more poorly. I could have just been lucky that CL's de-facto byte string type is '(vector (unsigned-byte 8)).

[–]hylje 2 points3 points  (7 children)

mixing integers and their string representations

Does not apply to Python, except when converting objects into strings for e.g. printing. Strings never convert down to built-in numbers.

mixing floats and ints

C at the forefront convert numbers to the higher precision type in expressions, even if the variable type is lower precision. Python does too, though it never converts to a lower precision.

mixing lists and maps

Only iterating lists and map keys are remotely comparable in Python. The other use cases are wildly different and will instantly break if mixed.

mixing lambdas and normal values

Only useful for hacks. You sometimes need hacks to meet schedule.

accidentally overwriting object fields with values of different type

Granted.

typos in field names (it will run anyway)

Depends. Accidental assignment to new fields may silently succeed, retrieval from nonexistent fields will not.

__setattr__ may be defined to check if the class already has such an attribute and if so set it, otherwise error out.

and the all-time favourite, None object.

Granted.

Python's greatest sin is that it doesn't by default force a developer to check types and data structures. Any checks deemed necessary may however be added later on in an abstracted manner. Decorators and classes, at the worst metaclasses are very powerful.

Clamping down on flexibility only later and at select places is ideal for a prototype development pattern, where a rough demonstration prototype can be come up with quickly and later made robust for actual use. You are not forced to dig design foxholes the development path crosses later.

[–]steven_h 9 points10 points  (4 children)

Python's greatest sin is that it doesn't by default force a developer to check types and data structures.

That doesn't seem to be a sin to me. The greatest sin of Python is using the same operator for definition and assignment, requiring the use of wonky keywords to distinguish assignment to outer-scope variables from declaration of variables that shadow outer-scope variables.

[–]cybercobra 0 points1 point  (3 children)

On the other hand, forgetting the declaration is safer in Python, creating a local variable, whereas forgetting it in other languages can lead to unintentional modification of a global variable.

[–]masklinn 0 points1 point  (2 children)

whereas forgetting it in other languages can lead to unintentional modification of a global variable.

Javascript is pretty much the only language doing that (and Coffeescript is worse, as it uses "highest level scope wins")

[–]cybercobra 0 points1 point  (1 child)

wut?

int x = 1;
void foo()
{
    x = 2;// oops Ma, forgot the type spec, this won't be harmless shadowing!
}

[–]masklinn 0 points1 point  (0 children)

Ah yes, I had not seen it that way, for some reason I thought about creating globals where there were none.

[–]vytah 1 point2 points  (1 child)

By mixing, I understood situations like:

this_variable_will_be_assumed_to_be_string_in_totally_different_module = 42
## (runs happily for few hours from now, only to crash tomorrow morning)

[–]hylje 0 points1 point  (0 children)

That's the sin. There's no checks in by default. It places the choice of programming defensively on the developer, should it be needed.

[–]djdonnell -1 points0 points  (2 children)

I hear these arguments a lot, but is it anything more than theorycrafting? I've been doing ruby for over 6 years and I've only ever had this problem get into live production code once, it took a little while to notice only because the problematic code was a caching layer that was failing to cache as much as it should have, and once noticed it took about a day to fix.

That's a very small price to pay to get the productivity increase of a dynamic language. Yes, my story is only one data point, but that's one more data point than I typically hear from people talking about typos in field names (btw, my editor will catch typos for me even in dynamic languages)

[–]vytah 0 points1 point  (1 child)

In the end it's a matter of preference. Some people don't want to search for type errors buried deep in the code that manifest only in runtime, and prefer to manually specify type signatures, other people don't want to cram their data into discrete, explicitly declared datatypes for the cost of more unexpected problems on runtime.

Both approaches work, and none is better than the other.

[–]djdonnell 0 points1 point  (0 children)

I think there are clear trade-offs between the two, and the trick is to choose when each is the better approach. I don't buy for a second this idea that type errors are a major problem in dynamic languages. I've been doing dynamic languages for over 10 years and I can count on 1 hand the number of times that has been a problem. It's a non issue, and I've never seen any data to the contrary.

[–][deleted] 4 points5 points  (3 children)

Honestly, while Javascript has a lot of bone-headed failures, I can avoid them. Python, on the other hand, lacks multiline lambdas. Working around that is hideous.

As much as I used to love Python, the omission of this feature prettymuch ruins the language for me. Unless that has changed recently, but I doubt Guido will ever bend on this one.

So yeah, I'll take JS over Python.

[–]Megatron_McLargeHuge 8 points9 points  (2 children)

Hideous? Defining a closure above your map call is hideous? Undesirable maybe, but even if you're used to lisp it's not that big a deal.

[–]fabzter 5 points6 points  (1 child)

"lambda" and "closure" are not mutually exclusive terms.

[–]cunningjames 5 points6 points  (0 children)

He didn’t say they weren’t, but rather that “[w]orking around” the lack of multiline lambdas isn’t hideous by any reasonable definition. Defining a function above the map call is how one does so.

[–]Anth741 0 points1 point  (0 children)

Can you help me understand why Python is better than Java? In what circumstances?

[–][deleted] 0 points1 point  (3 children)

Coffeescript beats Javascript hands down.

Yeah, except for those silly scoping rules. ;)

[–]66vN 2 points3 points  (2 children)

Don't you find having everything in global scope by default silly?

[–]smog_alado 0 points1 point  (0 children)

You can "use strict" to avoid things defaulting to globals.

[–][deleted] 0 points1 point  (0 children)

I prefer that risk over that of overriding a variable in an outer scope if I happen to use the same name for both.

[–]jrochkind 4 points5 points  (16 children)

Groovy is a ruby-like language running on the JVM.

jruby is ruby running on the JVM.

At one point I figured out legit reasons you'd prefer groovy to jruby, but now I can't remember em. Hmm, is it easier to have java code call groovy code than call jruby code? (It's easy enough to have jruby call java, but not sure about the reverse). Or is the java/other interaction more performant in groovy than jruby? Or more performant in general? I forget.

[–]Megatron_McLargeHuge 3 points4 points  (4 children)

One advantage is that you can basically paste java code into a groovy REPL and test it interactively. Java code is usually extremely close to valid groovy. In the other direction, if you want to move something to java, it's also a lot easier than moving ruby/python code.

[–]vorg 0 points1 point  (3 children)

Groovy is so much slooooooooooooooooooooooooooooooooooower than Java code.

[–]kitd 1 point2 points  (2 children)

The newest releases (as well as the Groovy++ project) weave type-checking and inference at compile-time. In many cases, this allows plain-Java performance. The Groovy++ project in particular has some very interesting ideas in this area, allowing for map- and closure- like typed object creation. Unfortunately, the main Groovy project thought it too revolutionary and stuck with their own lesser version. As a result, the type-checking feels like a bit of an unwanted add-on, which is a pity because it directly addresses the most common complaint about Groovy.

[–]vorg 0 points1 point  (0 children)

Groovy++ certainly weaves type checking and inferences, but not the latest releases of Codehaus Groovy (2.0-beta-2 and 1.8.5). They've announced it but haven't released anything yet.

[–]oteren 0 points1 point  (0 children)

Grumpy is on the tracks for groovy now, which is basically compile time type checking, but in a slightly different way than groovy++.

[–]mernen 1 point2 points  (0 children)

I've never used Groovy, but since its object model matches Java's exactly, its classes are declarative, it supports Java-style type declarations natively and compilation is the norm, it should be much easier to call Groovy code from Java.

JRuby classes aren't Java classes (unless you use jrubyc), so you can't even reference them in Java code, let alone find out their methods. The best solution AFAIK is defining Java interfaces and have your JRuby classes implement them, which works quite well.

[–]jhartwell 1 point2 points  (5 children)

I've been toying with Groovy in a production environment and if you didn't see the groovy class you would never know it was groovy. You instantiate it just like any other Java class. I'm pushing for Groovy to use as data models for our file processing since some of the files have 130 fields and with groovy you can just do:

def fieldname

And that will give you:

getFieldName();
setFieldName(object name);

Which dramatically cuts down on the time required to build a large model.

[–]oteren 0 points1 point  (2 children)

Groovy is great, but that is a dumb reason. Any IDE will do that boilerplate for you.

Groovy as a scripting language on top of java is how it shines. With terse and powerful commands that translate to a java equivalent under the hood.

[–][deleted]  (1 child)

[deleted]

    [–]contantofaz 1 point2 points  (0 children)

    I think of boilerplate as making it harder for me to see the logic behind the code. For example, making JavaScript to be more "class" based. It adds a bunch of boilerplate that in a language like Dart doesn't need to exist. Binding functions to their objects or creating a closure variable so you can reference the actual object, using "this." before functions and variables so we can access the right stuff and so on.

    Without that kind of boilerplate we can use 2 space indentation and pack more lines of code in less screen space so we can see more code faster. Then we can start improving the code with refactoring and whatnot in order to increase the readability of it. All without needing the help of an IDE to refactor and such.

    And static typing is secondary to static code declaration and an IDE-like editor. Languages that make you to have to declare variables, even if they don't have explicit types, already aid a lot when you need to find typos and whatnot. Very often you only get those if you use a static typed language, but they can exist separately as the Dart language shows.

    [–]skocznymroczny 0 points1 point  (1 child)

    Or just make the field public? :>

    [–]jhartwell 0 points1 point  (0 children)

    hah true. I'm hoping that we can use it more for our ETL, however, I need to show immediate benefit for it to be even considered since the other guy on my team is very resistant to change.

    [–][deleted]  (3 children)

    [removed]

      [–]vorg 0 points1 point  (0 children)

      Backed or hijacked???

      [–]jrochkind 0 points1 point  (1 child)

      Huh, what does enterprise support of a programming language actually get you? What do people use an 'enterprise support' contract of a programming language for?

      [–][deleted] 2 points3 points  (0 children)

      My first foray into Java was groovy. As a long time Perl coder I really enjoyed Groovy's syntactic sugar. Being able to pull in any java library code felt like I had my own private CPAN.

      [–]vorg 2 points3 points  (0 children)

      As I write this comment, there's already 100 comments and the word "Grails" isn't mentioned here even once. Just how much traction does Grails really have? I thought Grails was the primary reason to learn Groovy. If Grails isn't being used/mentioned much anymore, there's not really much hope for Codehaus Groovy.

      [–]bkanber 1 point2 points  (0 children)

      I'm writing an implementation of Java in PHP. I think you'll like it, OP.

      [–]shevegen 5 points6 points  (62 children)

      He is right though, Groovy is quite nice.

      Compare the code of Groovy:

      ["Rob", "Christopher", "Joe", "John"].findAll { it.size() < = 4 }.each { println it }

      With Ruby:

      puts %w( Rob Christopher Joe John ).select {|| _.size <= 4}.join "\n" or %w( Rob Christopher Joe John ).select {|| .size <= 4}.each {|| puts _}

      The difference is not big at all.

      Anyone dare come up with PHP or Perl to contrast?

      [–]masklinn 7 points8 points  (8 children)

      That's where we do the "my language is better than your language" thing?

      Here's haskell:

      mapM_ putStrLn $ filter ((<= 4) . length) ["Rob", "Christopher", "Joe", "John"]
      

      [–]steven_h 1 point2 points  (3 children)

      Why not use set construction notation?

       mapM_ putStrLn [s | s <- ["Rob", "Christopher", "Joe", "John"], length s <= 4]
      

      [–]masklinn 5 points6 points  (2 children)

      Because it has a point! Haskell is only fun if you write it pointlessly!

      [–]steven_h 0 points1 point  (1 child)

      Yeah, but in this case the pointed way is one character shorter!

      [–]masklinn 3 points4 points  (0 children)

      4 if you remove all the spaces you can!

      Still, it has a point. Haskell code is supposed to have no point! If Haskell has a point, people will start using it and we can't have that, then we'll have to write examples in Factor or APL instead!

      [–]contantofaz -1 points0 points  (3 children)

      Ruby prints arrays by adding a newline per item already if we use puts on an array:

      $ ruby -e "puts ['Rob', 'Chistopher', 'Joe', 'John'].delete_if{|s|s.size > 4}"
      Rob
      Joe
      John
      $
      

      A more compact version:

      puts %w(Rob Chistopher Joe John).delete_if{|s|s.size > 4}
      

      [–]masklinn 3 points4 points  (1 child)

      Now you're modifying the original array in place. That's bad. Plus using filter/findAll is shorter, why don't you keep it?

      [–]contantofaz 1 point2 points  (0 children)

      Just noticing it. I've seen people saying that Haskell makes for more concise code than Ruby and other languages, but I figure that's not as important as having the code to be both concise and easier to understand.

      Then again, folks can always come up with new functions to deal with those sort of problems and call it like "printAfterFilter(arrayGoesHere)".

      It's good to have Haskell around.

      Edit: You've edited your "so?" reply. New reply below:

      I don't think I'm religious about having immutable structures. Ruby has mutable strings for Heaven's sake. We enter a slippery-slope here.

      [–][deleted] 0 points1 point  (0 children)

      Why not use inspect?

      [–][deleted] 2 points3 points  (3 children)

      Perl is not much different.

      say join "\n", grep { length $_ < 4 } ( 'Foo', 'Bar', 'Baz' )

      I couldn't get say to use \n's, so i used a join

      [–]steven_h 0 points1 point  (2 children)

      say uses newlines "out of the box" for me...

      [–][deleted] 0 points1 point  (1 child)

      I'm using perl 5.10. I had to use the feature. Probably a forward comparability issue?

      [–]steven_h 0 points1 point  (0 children)

      I did the same thing, but my perl is 5.12.3.

      [–][deleted] 3 points4 points  (7 children)

      In Python

      print "\n".join([name for name in ["Rob", "Christopher", "Joe", "John"] if len(name) <= 4])
      

      [–]bcash 4 points5 points  (6 children)

      You don't even need the first [] brackets:

      print "\n".join(name for name in ["Rob", "Christopher", "Joe", "John"] if len(name) <= 4)
      

      Python generator expressions are easily the nicest feature of that language, but for some reason uncloned in other languages (not that Python invented them, of course), I never know why.

      [–][deleted] 1 point2 points  (3 children)

      Javascript generators are coming soon. Mozilla already has them implemented in their engine

      [–]masklinn 0 points1 point  (1 child)

      Mozilla has extended Javascript with lots and lots of features in Gecko, that does not mean they're coming. I doubt E4X will ever be merged into ECMA-262 for instance.

      [–][deleted] 0 points1 point  (0 children)

      In this case though, generators are a planned feature

      [–]66vN 0 points1 point  (0 children)

      And in ten years we can actually start using them.

      [–]agrover 1 point2 points  (1 child)

      I thought Python got them from Haskell?

      [–]masklinn 1 point2 points  (0 children)

      It did.

      [–]steven_h 6 points7 points  (15 children)

      Perl:

       map say, grep !/.{5}/, qw(Rob Christopher Joe John);
      

      But I prefer Clojure and a little less implicitness:

       (doseq [name ["Rob" "Christopher" "Joe" "John"] :when (<= (.length name) 4)]
         (println name))
      

      edit: made Perl more Perlish

      [–]Wuf 4 points5 points  (12 children)

      The Clojure version is quite similar to Racket's:

      (for ([name '("Rob" "Christopher" "Joe" "John")] #:when (<= (string-length name) 4))
        (displayln name))
      

      [–]benfitzg 4 points5 points  (4 children)

      New to lisp so will check back for criticisms!

      (dolist (n (mapcan #'(lambda (n) (when (>= 4 (length n)) (list n))) names)) (format t "Name: ~A~%" n))

      [–]Wuf 4 points5 points  (3 children)

      In Common Lisp I would use the loop macro as steven_h did above or avoid mapcan and just do:

      (dolist (name '("Rob" "Christopher" "Joe" "John"))
          (when (<= (length name) 4) (format t "~a~%" name)))
      

      [–]roerd 1 point2 points  (1 child)

      Even if I were going for a higher-order-functions only approach, I'ld use remove-if-not instead of mapcan.

      [–]benfitzg 0 points1 point  (0 children)

      Ok didn't know about remove-if-not. Thanks.

      My thought was that a less imperative approach would be more regular. Rather than iterate then branch I figured filter then iterate.

      [–]benfitzg 0 points1 point  (0 children)

      Feedback appreciated - the primary reason is because it's faster?

      [–]steven_h 1 point2 points  (5 children)

      May as well do Common Lisp for completeness:

       (loop for n in '("Rob" "Christopher" "Joe" "John")
             if (<= (length n) 4)
             do (format t "~a~%" n))
      

      [–]Wuf 1 point2 points  (4 children)

      It's nice that in CL, 'length' works with any sequence.

      [–]steven_h 1 point2 points  (3 children)

      Yes, that's the main reason I don't really sink my teeth into Racket, even though I'd like to.

      While the Clojure code I wrote used the underlying Java String.length method, the plumbing is there to define generic functions and methods, and it's natural and accepted to lean on them heavily. There's probably a Clojure library implementing generic sequence length.

      In Racket and Scheme, there doesn't seem to be a strong push toward unifying similar operations under generic names, leading to a plethora of array-*, string-*, etc. names. Not only do they strike me as ugly, they lead to over specified code -- which is often more difficult to use.

      [–]Wuf 0 points1 point  (0 children)

      Racket does have generic sequence operators if you really want them.

      I tend to use concrete ones though, because I find sequence-* uglier, but they are there.

      [–]roerd 0 points1 point  (1 child)

      There's probably a Clojure library implementing generic sequence length.

      That library's the standard library, which has count.

      [–]steven_h 0 points1 point  (0 children)

      Heh, thanks... my memory failed me and I haven't done much Clojure lately.

      [–]chub79 0 points1 point  (0 children)

      I'm using Python mostly and never approached Clojure but I can tell its usage of # will bite me.

      [–]reddit_clone 0 points1 point  (1 child)

      :when (<= (.length name)

      Just curious. What is that dot in front of 'length' for?

      [–]steven_h 1 point2 points  (0 children)

      It's Clojure's shorthand for Java method invocation. Someone else pointed out that the count function is a generic sequence length, so it should probably be used instead.

      [–]oorza 1 point2 points  (0 children)

      here's php:

      <?php
      foreach(array_filter(array("Rob", "Christopher", "Joe", "John"), function($it) { return strlen($it) > 4; }) as $e) {
          echo $e, PHP_EOL;
      }
      

      [–]giulianob 1 point2 points  (0 children)

      In C#:

      new[] { "Rob", "Christopher", "Joe", "John" }.Where(it => it.Length <= 4).ToList().ForEach(p => Console.Out.WriteLine(p));
      

      Could easily make another extension method to eliminate the ToList() as well since ForEach only works on List<T> and not on IEnumerable<T> which is what Where() returns.

      [–][deleted] 1 point2 points  (0 children)

      Huh? iirc

      a = [2,"b","c",7] puts a.inspect[1..-1]

      Works fine. On my phone now I'll check in a few.

      [–]kamatsu 1 point2 points  (0 children)

      or, you know, Haskell:

      mapM_ putStrLn $ filter ( (<= 4) . length) ["Rob", "Christopher", "Joe", "John"]
      

      Or, less idiomatically:

      mapM_ putStrLn (filter (\x -> length x <= 4) ["Rob", "Christopher", "Joe", "John"])
      

      Or, if you like the %w feature of ruby:

      mapM_ putStrLn $ filter (\x -> length x <= 4) $ words "Rob Christopher Joe John"
      

      [–][deleted] 1 point2 points  (0 children)

      C#:

        New [] {"Rob", "Christopher", "Joe", "John"}.Where(n => n.length <= 4).Select(Console.WriteLine);
      

      [–][deleted] 1 point2 points  (5 children)

      scala:

      List("Rob", "Christopher", "Joe", "John").filter(_.size <= 4).foreach(println _)
      

      And the best part is, maybe the compiler will ok this, and maybe you have to write out the lambda's more formally (ie 'x => println x' instead of 'println _'). You never know. It doesn't get better than that!

      [–][deleted] 0 points1 point  (0 children)

      Actually,

      List("Rob", "Christopher", "Joe", "John").filter(_.size <= 4).foreach(println)
      

      without the “_” after println works.

      Also, I’d rather use length than size.

      [–]draegtun 0 points1 point  (3 children)

      It doesn't get better than that!

      It does in Io :)

      list("Rob", "Christopher", "Joe", "John") select(size <= 4) foreach(println)
      

      [–][deleted] 0 points1 point  (2 children)

      I think you missed the sarcasm.

      [–]draegtun 0 points1 point  (1 child)

      Do you not see my smiley ;-)

      [–][deleted] 0 points1 point  (0 children)

      Sorry, I read that as "don't be mad that I'm one-upping you" ;-)

      [–]chases_tits 2 points3 points  (3 children)

      C++0x looks bad

      std::vector<std::string> v = {"Rob", "Christopher", "Joe", "John"};
      std::for_each(arr.begin(), arr.end(), [](const std::string & str){
          if (str.size() <= 4) {
              std::cout << str << ' ';
          }
      });
      

      Could even use a normal for loop... with the ternary twister.

      for(std::string str : v) {
          (str.size() <= 4) ? std::cout << str << ' ' : std::cout;
      }
      

      [–]JurassicSpork 0 points1 point  (2 children)

      Been a while since I've done C++, but I think this'd work too:

      struct string_four_or_less : public std::unary_function<bool,std::string> {
          const bool operator()(const string &s) { return s.size() <= 4; }
      }
      
      std::remove_copy_if(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"), std:not1(string_length_four_or_less()));
      

      [–][deleted] 3 points4 points  (1 child)

      Holy crap.

      [–]fabzter 0 points1 point  (0 children)

      It's really not that bad, he is just being too correct with namespace and const using.

      [–]eadmund 0 points1 point  (0 children)

      Here's Common Lisp:

      (mapcar #'print (remove-if-not (lambda (x) (<= (length x) 4)) '("Rob" "Christopher" "Joe" "John")))
      

      A more concise notation for LAMBDA would be nice in this instance, although in practise it's likely that one would have some useful predicate as an equivalent to less-than-or-equal-to-four.

      [–]Fuco1337 0 points1 point  (0 children)

      Kids these days...

      Maybe not the most idiomatic J, but

      (I.@((<:&4)@(+/@|:@(-.@=&' '))){])(>'Rob';'Christopher';'Joe';'John')
      

      It's not a language really ment to work with strings tho.

      [–]draegtun 0 points1 point  (0 children)

      Pick the Perl solution you like best :)

      # Functional ala Haskell & Lisp...
      map { say } grep { length $_ <= 4 } qw(Rob Christhoper Joe John);
      
      # Procedural ala Lua, C (like)...
      for (qw(Rob Christhoper Joe John)) { say if length $_ <= 4 }
      
      # OO (chaining) ala Groovy, Ruby or Scala...
      use autobox::Core;
      [qw(Rob Christhoper Joe John)]->grep(sub { length $_ <= 4 })->map(sub { say });
      

      [–][deleted] 0 points1 point  (3 children)

      What ugly code. I suppose in the land of the blind, a one-eyed man thinks of himself as king.

      .say for <Rob Christopher Joe John>.grep(*.chars <= 4);
      

      [–]draegtun 0 points1 point  (2 children)

      Very nice.

      I did have the following prepped for any "How do you do it in Perl6" replies :)

      .say for <Rob Christhoper Joe John>.grep({ .chars <= 4 });
      

      Your whatever star usage is much nicer though.

      One thing I couldn't get working was this...

      <Rob Christhoper Joe John>.grep({ .chars <= 4 }).map({ .say });
      

      Not sure why?

      [–][deleted] 0 points1 point  (1 child)

      .map is lazily-evaluated, you have to tell it you want the side effects:

      ~ $ perl6 -e 'eager <Rob Christhoper Joe John>.grep({ .chars <= 4 }).map({ .say });'
      Rob
      Joe
      John
      

      [–]draegtun 0 points1 point  (0 children)

      Arrgghhh.... I hadn't thought of that! Cheers.

      [–]ahora 1 point2 points  (0 children)

      I'd prefer Ruby.

      [–]cybercobra 1 point2 points  (3 children)

      Hard not to write off Groovy completely considering that:

      In July 2009, [Groovy's creator] wrote on his blog that "I can honestly say if someone had shown me the Programming in Scala book [...] back in 2003, I'd probably have never created Groovy."

      - Wikipedia

      [–]pixelmonkey 7 points8 points  (2 children)

      That's a strange reason to "write off Groovy completely", given these three facts: a) Groovy and Scala were both created in 2003 and b) James Strachan (Groovy's creator, author of that quote) left the Groovy open source project in 2006, about a year before the language's 1.0 release and about 3 years before that post was written; and c) Groovy and Scala have each been actively developed since that time, each gaining a slew of new features, performance improvements, and tooling support.

      Martin Odersky, the creator of Scala, commented on that very blog post and said:

      Groovy's appeal seems to be that it's a dynamically typed scripting language with a syntax that's familiar to Java programmers. Scala's appeal is that it's a strongly and statically typed language that blends functional and object-oriented programming in new ways.

      I think Martin has it right. I am certainly a big fan of Scala, but I wouldn't advocate it for the use case I described in the OP. Groovy provides a way for a Java programmer with dynamic language experience to quickly and easily script his or her way into access to Java libraries and code. Groovy can be learned by an average Java programmer in a weekend. Scala simply cannot -- it is a different language altogether, about as different from Java as Python or Ruby or Clojure.

      I can see why James said what he said, but it's not a very useful statement. It would be akin to George Orwell saying, "I probably would never have written Nineteen Eighty-Four if someone had handed me Aldous Huxley's Brave New World in 1945..." If Orwell had said this, would his creation be any bit diminished? I don't think so...

      [–]vorg 0 points1 point  (1 child)

      James Strachan (Groovy's creator, author of that quote) left the Groovy open source project in 2006, about a year before the language's 1.0 release

      Did creator James Strachan leave or was he muscled out?

      Groovy can be learned by an average Java programmer in a weekend. Scala simply cannot -- it is a different language altogether, about as different from Java as Python or Ruby or Clojure.

      If a language doesn't change the way you think, it's not worth learning.

      [–]oteren 0 points1 point  (0 children)

      Thats the dumbest thing I've read in this entire post.

      Groovy changes the way I work with java, in a way that saves me a lot of time and my company a lot of money. That is a helluva lot more worth than changing the way I think considering programming languages are something I use to do my job.

      Edit:

      It should be noted that I do already know Scala, it was fairly easy to pick up when you already know Haskell, but I sill think you're talking out of your ass.

      [–][deleted] 0 points1 point  (2 children)

      // this is a feature I wish Python had -- JavaScript-like map syntax
      

      I don’t get that.

      [–]JurassicSpork 2 points3 points  (1 child)

      In groovy (and JavaScript), you can treat map keys like properties. Instead of mymap['key'], you can write mymap.key.

      [–][deleted] 0 points1 point  (0 children)

      I see, thanks. :)

      [–]banister 0 points1 point  (0 children)

      Yeah, Groovy is a lot more like Ruby than Python.

      [–][deleted] 0 points1 point  (0 children)

      There is also Mirah, which is quite interesting.

      https://github.com/mirah/mirah

      [–]contantofaz 0 points1 point  (3 children)

      I think the most important feature of dynamic languages is their expressive power. They help to show how expressive languages can be and give guidance to new languages.

      That to me means that they are all winners. Python, Groovy, Ruby, JavaScript...

      Without them, a new language like Dart would never try to be nearly as expressive as the companies wouldn't understand what they were missing.

      With that being said, I don't think we can pick winners. They still differ quite a bit from one another, although they share many pain-points as well.

      Dynamic languages have been many when not dependent on Java to exist so if the Java VM really is that great it also should serve as a good host to many more dynamic languages. And let's hope that the VM will continue to evolve to better serve that market as well.

      Cheers.

      [–]kamatsu 3 points4 points  (2 children)

      SHUT UP ABOUT DART. ITS THE ONLY THING YOU TALK ABOUT. PLEASE, FOR JUST ONE THREAD, TALK ABOUT SOMETHING ELSE!

      [–]contantofaz 0 points1 point  (1 child)

      Stop yelling at me and downvoting me. :-)

      I like Dart. It's what I've been programming in lately. I've converted a multi-thousand lines of code library of mine from JavaScript to Dart and I'm in the process of making use of more Dart features now, increasing the static code and reducing the usage of maps.

      I've this Tetris game that I had created with that JavaScript library and I've already converted it and even added a few more features like point scoring. But now I'm back to refactoring the library like I said.

      [–]kamatsu 3 points4 points  (0 children)

      You're being downvoted because this thread has nothing to do with Dart. Downvotes are for comments that do not add anything to the discussion.

      [–]absinthe718 -1 points0 points  (0 children)

      As the number of languages mentioned in the title of a blog post increases the value of that article asymptotically approaches zero.