1. 10
  1.  

  2. 16

    I feel like this article is conflating several different notions of “safe”. For instance, the author considers Rust’s goals to be “safe”, however Rust does not prevent memory leaks - which the author regards as “unsafe”. Meanwhile, Java - like Rust - is certainly quite “memory safe” (ie, it prevents accessing invalid memory). If you access a null in Java, it doesn’t result in undefined behavior - it crashes with an exception, which is surely safer than what some other languages might do.

    To be useful I think we must distinguish “safety” from things like “sound”, “secure”, “statically verifiable”, etc. They are related but different concerns, and most languages outside of maybe Coq and Spark (even Rust, with its “unsafe” blocks) accept some level of fudge factor with them in the interest of getting work done.

    1. 3

      Yeah I found it to be an odd grab bag. I thought there was a formal definition of “safe” that means that the program either halts or the behavior is predictable from the source text. Java/Python’s exception on null is “safe” in that respect, but C’s undefined behavior is not.

      You can also divide by zero in or write infinite loops in Rust/Swift/etc. You could fail to handle EINTR. Does that make them “unsafe”? The term really does need a definition for this blog post to be meaningful.

      1. 4

        Python and Java aren’t “safe” by that definition: Consider non-domain errors like running out of disk-space, or low-memory conditions. There are languages that are safe by that definition (like Zig) but given how few players there are at that table, I never assume that’s what someone means by “safe”.

        Knowing it isn’t a protected term, I treat the term “safe” like I treat the term “clean”: I appreciate the author is trying to point to something that makes them feel better, and often that thing is useful or interesting, so I can try to understand why that thing would make my life easier instead of worrying about whether MyFavouriteLanguage™ has this particular feature-label with some definition of this feature-label.

        Here, the author has given a definition up-front:

        The prime directive in programming is to write correct code. Some programming languages make it easy to achieve this objective. We can qualify these languages as ‘safe’.

        Ok, so the author measures “safety” as the function of how easy it is for a programmer to write code correctly in this language. And yes, by that definition Java and Python (and other stackoverflow-oriented programming languages) are unsafe because most programmers are unable to write code correctly in those languages. From there, the author suggests four “language features” that a language that is “more safe than Java” has. Hooray.

        I have a very different issue with the article, and that’s that I don’t see the point of talking about these things. I would see the audience going one of four ways:

        • I’m not a Java Developer, and MyFavouriteLanguage™ doesn’t have these features, and “I don’t have any problems” (Blah blah blah) so maybe they aren’t that important after all…
        • I’m not a Java Developer, and MyFavouriteLanguage™ does have these features, so I already know all this HUR HUR HUR
        • I’m not a Java developer, so I can’t use this information to make Java better.
        • I’m in management/eat paste, so I don’t know what any of this means.

        None of them are good, and even if the author “wins” (whatever that means) and convince someone who thought Java was great and now it isn’t, so what? Do they somehow benefit if more people think Java sucks?

        And yet the prevailing response to something like this is to ask for a better definition. After all, we want to understand how MyFavouriteLanguage™ stacks up! We want the debate! But to me, asking for rigour here is just putting lipstick on a pig, and may even cause real harm in (us collectively) trying to understand how to make programmers write correct code quickly that runs fast.

        1. 0

          I’ll add to your list:

          1. I don’t like Java, know about other options, and have to write it since the managers demand that language.

          2. I am a Java developer who is required to write standard Java for maintainability to help future, disposable programmers or come-and-go volunteers. I can’t use better ways to write Java in this company or open project.

          3. I am a Java developer with lots of existing code and use for the ecosystem (esp libraries and IDE). I’m not an expert in compilers or program analysis. I can’t fix these problems while still writing Java even if managers or open collaborators would allow it.

        2. 1

          The idea that anyone would consider a language “safe” which has a type system that doesn’t prevent null pointer exceptions is very strange to me. I mean, surely that’s not enough to qualify on its own, but it’s certainly one prerequisite.

      2. 5

        I agree with academician that it’s not clear what standard of safety this article uses. Some points, like null safety, seem quite sensible.

        However, I wish the author had said more about memory leaks in Java. There are two things that might be meant. There are a handful of ways to create a true memory leak. The obscure include JNI (native code) and sun.misc.Unsafe (unsafe code), while a slightly more common one is class loader shenanigans (this one is more of a practical concern, though most programmers still won’t touch it on a regular basis).

        However, the anecdote makes me wonder whether the author just means the boring case of “I stored a reference to a big object in a member variable/hashmap that I was never going to need again.” In the terminology I know, that’s technically not a memory leak, it’s a space-leak (some computation temporarily uses more memory than it needs). Moreover, I don’t know of any language that prevents it. I’m not even sure if it’s possible to prevent. It seems like for any Turing complete language, it would be undecidable whether some memory might be referenced later.

        1. 5

          Three Kinds of Leaks seems relevant here.

          For I long time I didn’t realize that people also called ‘just keep adding stuff to a hash map’ or ‘changing the object so the hashcode changes and it gets lost in the hash map’ a ‘memory leak’.

        2. 2

          “Almost anyone who has programmed non-trivial Java programs has caused or had to debug a data race. It is a real problem.”

          Most of the CompSci research in detecting concurrency bugs was in fact aimed at Java. Maybe partly due to Java becoming a default language in lots of universities. That said, I think there’s be a lot less tooling developed if Java was good at concurrency. Eiffel’s SCOOP was better by making concurrency more like sequential programming. A prototype port to Java happened at one point.

          1. 0

            Well you can even call create java objects without running their constructor. And afaik some of the bigger libraries use raw-pointers internally via the not-to-be-used internal API of the JVM. So we end up with unsafe code in a language where you don’t have real support for hardening unsafe code. Reflections are powerful but feel like C++ magic, you can do a bunch of things but you can also just shoot yourself in the foot.