Live data from Hacker News

Why I love Common Lisp and hate Java (2012)

kuomarc.wordpress.com

71–80 of 171 posts

Re: Why I love Common Lisp and hate Java (2012)

#71

It's ironic that the author claims that Common Lisp is easier to learn than Java. One of the most common pro-Lisp, anti-Java arguments I hear is that Java is too easy to learn, so that a lot of people who aren't actually very good at programming can get Java jobs. This means that the Java world is populated with not-so-bright people, while the rarefied Lisp world is full of elite wizards.

Java doesn't contain conceptually difficult features. In Rust you have to learn lifetimes and borrow checking, in Haskell Monads... Java just has a huge amount of relatively simple features. Lisp is middle of the road conceptually, but is a small language.

So in that sense I agree with you. Java is favored by people who struggle to learn harder concepts. That's why it's the usual target of the lowest common denominator programmer and loved by large enterprises that can churn Java programmers like mackerel.

Re: Why I love Common Lisp and hate Java (2012)

#72
post #52

Earlier quoted context omitted.

I disagree. Most of the time, I find a debugger just slows me down. It's super helpful in some cases, but good logs can pinpoint problems far before a debugger can. Also, building in debug mode can change everything, so you may not even catch your bug, especially if it's concurrent in nature.

>I find a debugger just slows me down 1st you have to add the useless print statements and after decades of programming a debugger is vastly superios in terms of 'debugging' when compared to printing. (Back in time basic had no debugger even) Also printing is utterly useless for high concurrent code, as printing alters memory visibility, usually adds global sync, etc..

Attaching a debugger will also change the behavior of concurrent code.

Re: Why I love Common Lisp and hate Java (2012)

#73
post #6
post #2

If you are running JDK 9 or later, you can use jshell: jshell> "Hello World!" $1 ==> "Hello World!" https://openjdk.java.net/jeps/222

And lambdas were introduced in 8 making nearly all of the author’s issues mute.

That's the thing though... they aren't real lambdas. They're just syntactic sugar for an interface. If you watch the talk by the head of Java right now at the Clojure conference, he talks about how they're essentially trying to tack on low hanging fruit in hacky ways to keep the language up to date. But secretly it's a mess.

Re: Why I love Common Lisp and hate Java (2012)

#74
post #7

It is a recurring theme for people to point out how verbose a hello world program is in Java: class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } } For argument sake, let's compare it not to Lisp but to Python instead: print("Hello World!") Once you get proficient in a language and start writing larger programs, your perspective can change entirely. What appears to be…

Totally agree with you - I like Java precisely because it's so verbose. I'd rather have to type 20% more than spend 20% more time figuring out other people's code. And honestly, I always feel that the Hello World example is kind of biased. It's more an example of Java's way of launching a program being verbose because every program requires a certain minimal structure. But for the rest of the entire Java language tha…

Java is verbose, but it isn't expressive. In Java you talk a lot without ever saying anything. In an expression based language like Lisp or Rust, you can more compactly write your ideas into code, even though Rust might still be verbose syntactically like Java.

Re: Why I love Common Lisp and hate Java (2012)

#75
post #48

Earlier quoted context omitted.

Totally agree with you - I like Java precisely because it's so verbose. I'd rather have to type 20% more than spend 20% more time figuring out other people's code. And honestly, I always feel that the Hello World example is kind of biased. It's more an example of Java's way of launching a program being verbose because every program requires a certain minimal structure. But for the rest of the entire Java language tha…

I would say that Java has ~50% more code than Python due to types and braces. But I agree with you that it's worth it, because the compiler can check that a programmer satisfied a constraint, instead of relying on informal conventions or comments. You can have a statically typed language without verbosity, via type inference (Haskell, newer Java, etc.). I wouldn't say I enjoy Java's verbosity, but I would take this o…

Most Haskellers write out the types even though they can be inferred. In a pure language, signatures are extremely close to documentation (you know exactly what a function will do by its signature).

Java requires more code than Python or Haskell because it's extremely imperative and statement based. Python on the other hand includes a lot of functional, more expressive idioms like concise list comprehensions.

Re: Why I love Common Lisp and hate Java (2012)

#76
post #48

Earlier quoted context omitted.

Totally agree with you - I like Java precisely because it's so verbose. I'd rather have to type 20% more than spend 20% more time figuring out other people's code. And honestly, I always feel that the Hello World example is kind of biased. It's more an example of Java's way of launching a program being verbose because every program requires a certain minimal structure. But for the rest of the entire Java language tha…

I would say that Java has ~50% more code than Python due to types and braces. But I agree with you that it's worth it, because the compiler can check that a programmer satisfied a constraint, instead of relying on informal conventions or comments. You can have a statically typed language without verbosity, via type inference (Haskell, newer Java, etc.). I wouldn't say I enjoy Java's verbosity, but I would take this o…

Tuples especially, and more specifically how the language supports their unwrapping.

for idx, entry in enumerate(list)

vs. list iterators in Java where you have to repeat complex types at least 3 times and get about 5-10 times more code when it would only have to be about 2 times to achieve static type safety. Lack of typedef and the resulting drive towards dummy classes is exacerbating this problem further.

Re: Why I love Common Lisp and hate Java (2012)

#77
post #4

Beside the REPL, another impressive feat of Common Lisp is meta-programming. You can write software to write software. Say what? Yeah, that was my initial reaction too, but Common Lisp’s macro system allows you to write functions that return code snippets. It completely redefines the word. Or more accurately, re-redefines, since Lisp is much older than MS Office, which is what most people associate macros with, sadly…

Here is something from Clojure that stuck with me as particularly elegant:

The -> macro.

  (-> {}
      (add-person 'servbot)
      add-age
      add-info
      add-to-db
      notify-status-by-email
      log-user-addition
  )
So the threading operator is exactly what you ask. It inserts the results of the previous expression as the first argument as the first argument as the next expression. Note this still supports situations where an expression can take more than one argument.

Additionally, there is the ->> operator which inserts the previous result as the last argument in the next expression and some a library that includes the "magic wand" operator "-" ala

  (- {}
      (add-person 'servbot)
      (add-age 21 )
      (add-info 'servbot  21)
      (add-to-db 'my-db-handle 5432 )
      notify-status-by-email
      (log-user-addition 'dev 'email  'paint-by-numbers)
  )
This particular set of macros seems entirely trivial until you use it, and then it changes your entire perspective of what functions do since your ability to express the computation pipeline changes completely.

Edit: Update for formatting.

Re: Why I love Common Lisp and hate Java (2012)

#78

Earlier quoted context omitted.

I have yet to come across a situation in which it is not worth the effort to figure out how to attach a debugger to a piece of code I'm modifying.

Again, attaching a debugger is occasionally not helpful–for example, if you're trying to figure out why your program isn't loading certain plugins at launch, you trying to attach the debugger may happen after this step occurs. So you don't get to debug this process.

Or if an issue happens in your staging environment but not locally. That happened to me just yesterday, and a simple print statement gave me the information I needed to resolve the issue.

I probably could have attached a remote debugger, and executed the relevant function a few times until my request got routed to the right process in the cluster, but that honestly would have taken me more time than just committing the print statement and letting CI take it away.

Re: Why I love Common Lisp and hate Java (2012)

#79
post #7

It is a recurring theme for people to point out how verbose a hello world program is in Java: class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } } For argument sake, let's compare it not to Lisp but to Python instead: print("Hello World!") Once you get proficient in a language and start writing larger programs, your perspective can change entirely. What appears to be…

These criticisms look to me like you are trying to use your Java programming style in Python.

Prefer to use modules and tables of functions as an organising principle instead of classes.

Use inheritance rarely, and method overriding almost never. Otherwise you can make a really big mess (see Django's Form class hierarchy).

This sort of bad design where you have the flow of control jumping up and down the inheritance hierarchy happens in Java too, but the `abstract` keyword and static typing makes it easier to avoid.

In Java, make your code regular, so someone can understand the piece they're looking at without too much context.

In Python, make your code interesting. Factor out the unimportant repetitive parts, so someone can see a lot of the big picture all at once.

Incidentally, I'm quite happy with print() in the top-level namespace. Java's logging situation (5 widely used logging frameworks and a 6th to abstract over them all) is not better.

Re: Why I love Common Lisp and hate Java (2012)

#80

Earlier quoted context omitted.

You really should be using a logging framework instead though, if you're working on a large application.

You use logging for production, but if you just want to see what a value is while when you run your program in the IDE and might not for a logger imported, print is handy.

Coming from python I like to set a breakpoint, and dive in with pdb. It's super easy to navigate through the stack frame and poke around to see what all the variables are. I get more out of inspecting state from inside of pdb than I do out of print statements.

On the other hand, I tend to use only print statements when I'm roughing in a program in an iPython Notebook. This gives a sort of visual documentation when navigating a library that I'm new to, and allows me to glance back at a verbose description of otherwise opaque data structures.

Post reply on HN