1. 16
  1. 5

    I like python, I even like javascript but java is just “easy”. Strong, static typing saves me so much time and mental effort it’s phenomenal. I tried becoming more of frontend focused “full stack” developer for a few years but I found I worked far harder, expended more mental effort with dynamic languages than I ever did with java. Of course javascript isn’t python but I experienced that same thing with a python application as well. I tend to work more on extending and maintaining existing applications than green field development. Even then if one takes the time to learn Spring, it’s really really good to.

    I’m at the point in my life where “easy” counts for a lot. And as the fine article says, java is pretty nice nowadays. The tooling is exceptional. I’m glad for it.

    1. 1

      I heard Python can do static types with an extension or something. Found this that shows how. Also claims PyCharm IDE catches the type errors for you. Some info might be out of date since it’s from 2017.

      Maybe try some of that tooling with Python to see if it gets better.

      1. 3

        Yes, type checking with mypy is quite good nowadays, and provides quite a bit of peace of mind. It’s not perfect, and it’s nowhere near the level of what static types in Java give you, but it’s a good middle-ground, and it improves the Python dev experience noticeably. You loose some of the readability of Python (if you are not used to type hints), but I think it’s worth it, esp. for libraries.

    2. 3

      I’ve written mostly Java for the last 15 years. I write Java code every day. I kept up with the latest and tried to take part in the community up until about Java 8. I love Java. But there are just some things that I miss. I’d love to have tuples, like in Python or Rust. I’d love the pattern matching feature of Rust. There are some generics type information that I simply cannot get during run-time (I.e. using lambdas for generic static functions) And last, but not least, I always run into problems working with char[] and strings.

      In some ways I think being so adamant on always being backwards compatible has held Java back a bit. I’d love. I’d be totally fine with the major LTS releases not being backwards compatible.

      1. 4

        I recommend taking a look at Kotlin. You get access to the whole Java ecosystem with a very concise and expressive language without making a class for every little thing.

        1. 1

          Kotlin is a nicer language than Java but Java has much better static analysis tools.
          I would stick with Java if static analysis is important to you.
          Here are some examples of IntelliJ Java inspections that aren’t yet available in Kotlin:

          • Class metrics
          • Concurrency annotation issues
          • Control flow issues
          • Data flow
          • Dependency issues
          • Error handling
          • Finalization
          • Internationalization
          • JUnit
          • Logging
          • Method metrics
          • Performance
          • Portability
          • Serialization Issues
          • Threading Issues
          • TestNG
            The Kotlin language design fixes some issues but many of these inspections would apply to Kotlin.
          1. 1

            No static analysis tool in the world would make me stick with Java. I read the same code more often than said tools do, and Java is more code doing less.

        2. 2

          I recommend taking a look at Scala. You get access to the whole Java ecosystem with a very concise and expressive language with a REPL, allowing you to mix functional and imperative styles however you see fit.

          1. 2

            Disclaimer: My experiences are about five years dated. Updates on the state of Scala are appreciated.

            I have learned the basics of Scala, but I found the complete experience underwhelming.

            • The tooling was slow and a bit unwieldy.
            • I found the language and libraries to use excessive amount of cryptic operators. To me it was a hieroglyph language, akin to APL. Same inline operators with English words would have been friendlier.
            • I appreciate the idea of making illegal states unrepresentable, but I saw some advanced generic code in Scala, and it seemed just as hard to understand as with complex OOP inheritance hierarchies, and it did not seem to simplify understandability and maintainability of the code.

            My impression was that me maybe too much OOP is left in it, and it combines the complexities of OOP anti-patterns with the complexities of a very strict type system.

            Right now I’m experimenting with F# (mixed paradigm similarly to Scala) and I find the ML based syntax friendlier, and my impression is that its type system is simpler (more limited maybe), but it doesn’t encourage to do so overly complicated types. I’ll see, when get to dive into medium size projects which I saw with Scala, what will my impressions be.

            Also I feel it has lost traction. Kotlin is the thing now, backed by the most important players. It is not such a radical step forward(?)[^1] like Scala.

            [^1]: or sideways, to different paradigm

          2. 2

            I recommend taking a look at Clojure. You get access to the whole Java ecosystem with a very concise and expressive language with a REPL driven workflow that’s not available in any mainstream language.

            1. 1

              The concrete problems would really interest me, especially about the runtime genetic type informations.

              C#, which I have been working mostly in the last few years, generally provides most things you mention. You should really go with Kotlin instead, as that lets you take advantage of your knowledge of the JVM ecosystem. I’m just curious if apart from that C# would address your pain points. Most are explicitly available features in new versions (C# 8.0 being the latest I think), but the generics are a bit different, due to the lack of type erasure, which is sometimes a bliss, sometimes a curse.

              It has its own flaws, around async/await being incomplete, and having messed up some patterns imho, but that is a different case.

              C# is very similar to Java, but has been less obsessed about backward compatibility, but I can see that it has now always worked out fine. (Most novelties are nice and useful alltogether)

              1. 1

                Here is an example I ran into the other day. I have a generic helper function for memoization:

                Private static final Map<Object, Map<Supplier<?>, Object>> cache = new ConcurrentHashMap<>()
                public static <T> T memo(Supplier<T> o) {
                        return (T) cache
                                .computeIfAbsent(o.getClass(), k -> new ConcurrentHashMap<>())
                                .computeIfAbsent(o, k -> o.get());

                I’d like to use something else than o.getClass() as key, as it will return something different each time if I call it with a lambda like so:

                Util.memoize(() -> longCalculation(1));

                Instead I’d like to get some kind of signature. For example the return type, the actual runtime type T. As far as I know, this cannot be done.

              2. 1

                To be honest, the main reason I used Python is the huge documentation on getting started with it. How to write new modules, the zen of python, libraries very well explained when you start with the language…

                I’ve tried Java, but it always felt very “magic” to me each time I’ve tried to use recommended frameworks like Spring or Akka… Do you have resources to learn about the JVM, and the Java ecosystem in general?