
Comparing Rust and Java - Manishearth
https://llogiq.github.io/2016/02/28/java-rust.html
======
levemi
I love both Java and Rust, this is a great write up! I've been writing C++
recently and when I run into unexpected undefined behavior during run time I
very much miss Rust and Java as neither would have happened in either. I'm
just not as good at C++ as I am at the other two so that explains it. It does
feel freeing in C++ to not have to worry about borrow checking, but I know it
will get me into trouble I would have avoided with Rust. I can see the use
case for both. Sometimes you just want some code without worrying about doing
it perfectly, and sometimes you want to build a nice big application where
things are fine tuned and as bug free as possible and in that case I'll
probably want to choose Rust.

Nothing in my mind though really beats the ecosystem around Java of these
three in terms of IDE support, tooling and just simplicity in getting code out
fast when you don't need low level access to things. Netty really brings great
things to Java, and the many mature web frameworks for JVM languages are
probably better than anything available for Rust right now. I'm not sure a
sane person would write backend for a web site in C++. :P

Anyway I love both Rust and Java 8 and it's great to see them thriving.

~~~
truncate
Speaking of tooling, correct me if I'm wrong but one thing I miss when working
on Java (I've not worked much on Java) is intuitive and build/package manager.
Java build tools seems to be painful to use outside IDE. Cargo on other hand,
I can get started working in minute.

~~~
chamakits
I have found the opposite to be true in my experience. IDE's have some level
of trouble with most popular Java build tools (Maven and Gradle), while they
are quite capable command line tools, and they themselves know how to work
well with the IDE's (They each have plugins to create the 'meta' files for the
most popular IDE's)

What issues have you had with which build tool when using it outside the IDE?

~~~
EdwardDiego
IDEA's Maven and Gradle support is pretty good. I haven't had to use any Maven
plugins to generate project files for an IDE since IDEA 7. But yeah, mvn and
gradle are the definitive, the IDE support is a nice to have.

~~~
mavelikara
IDEA's native Gradle support is excellent. I haven't had to use Gradle's
IntelliJ plugin (the Gradle bit that generates the IDE files) for at least two
years now. All I have to do is (on Mac OS X):

    
    
        open -a /Applications/IntelliJ\ IDEA\ 15\ CE.app build.gradle
    

At work, we have a Gradle project with 346 submodules. We have about 200
engineers working on the codebase. Gradle/IDEA combination works well
beautifully.

There are a few rough edges, especially when one uses custom source sets. IDEA
16 is going to get better support for that [1].

[1]: [http://blog.jetbrains.com/idea/2015/12/intellij-
idea-16-eap-...](http://blog.jetbrains.com/idea/2015/12/intellij-idea-16-eap-
starts-the-faster-release-cycle/)

------
merb
Great writeup, especially that you are really fair to both and make good
statements.

> Java has a lot going for it, and I probably will keep using it for some
> time.

Me, too. And I will always keep an eye on rust, especially since I also use
Scala. ;) However the only downside of rust, is that crates.io doesn't has so
powerful things like Java has in maven. However comparing Libraries of a 20
year old language vs a "some" year old language is somewhat unfair. What I
would like would be Java <-> Rust FFI.

~~~
DannoHung
This may make you happy then: [https://github.com/sureshg/java-rust-
ffi](https://github.com/sureshg/java-rust-ffi)

~~~
voltagex_
Heh, I wonder if I could write a Minecraft mod in Rust with this

~~~
kitd
I have written a native extension library for Java in Rust. It's really no
different from doing it in C. Mind you it was pretty simple. The only slightly
bizarre bit is matching the java types to the libc equivalents, and telling
rustc that you don't want to enforce snake naming.

------
catnaroek
> It may be harder to write Rust code than Java code, but it’s _a lot harder_
> to write _incorrect_ Rust code than _incorrect_ Java code.

This. 10x.

And, if Rust's type checker could be integrated with an SMT solver to
statically verify array/vector indexing (instead of performing bounds checks
at runtime, or using unsafe code), that 10x would become 100x.

~~~
david_ar
Like Liquid Haskell?

[http://www.haskellforall.com/2015/12/compile-time-memory-
saf...](http://www.haskellforall.com/2015/12/compile-time-memory-safety-using-
liquid.html)

~~~
pron
Well, yes and no. You can prove all the properties liquid types can without
actually using liquid types, just by running the algorithms that infer them.
Either way (inferring with or without types) the problem of indexing is
undecidable, and cannot be verified in the general case (but it can in many
common usages).

~~~
catnaroek
The point to using types is that they make static analyses more compositional.
Types enforce invariants across module boundaries, without requiring the
entire program to be checked in a single pass.

~~~
pron
Yes, but they may also lose information in the process... As usual, it's a
tradeoff.

------
DannyBee
" so it’s just-in-time compiled" and "As a fully compiled language, Rust isn’t
as portable as Java (in theory)"

Look, JIT and static compilation are just compilation mechanisms. You can
apply them to pretty much any language you want. You can statically compile
java[1]. You can JIT Rust. You can compile java with llvm (Azul does it). You
can interpret java, rust, C++, etc.

You can have hybrids where you start with an optimized statically compiled
form and reoptimize it at runtime.

Don't ever tie current optimization mechanisms to comparisons of _languages_.
If it's really important to gain performance, someone will do it.

For example, JIT of C++ is often not done because it's not worth it compared
to automatic profiling and other reoptimization mechanisms. But it can be done
:)

If you want to compare languages, compare languages. If you want to compare
particular implementations of languages, compare particular implementations of
languages. Don't say you are doing one and do the other, because it's
confusing, and, well, if it matters enough, someone will come along and make
you wrong.

:)

[1] If you are willing to guarantee no class loading. Otherwise, you can
statically compile everything that is loaded or run an interpreter or do what
you want to new code at runtime

~~~
catnaroek
In theory, a programming language only has a syntax and a semantics, and
everything else is an implementation detail. In practice, programming
languages are designed for specific use cases, and lend themselves to specific
implementation strategies. For example:

(0) Type-checking C++ templates requires expanding them. However, nothing
forces a C++ implementor to translate the individual template instantiations
to machine code (or whatever target language is used). A C++ implementor could
use a strategy similar to what is used in Java and C#, and re-instantiate
every template on demand at runtime. Of course, nobody does this, because it's
bad for the implementor (more work, because instantiating templates is more
complex than instantiating generics, so better not do it at runtime if it's
already been done at compile time), bad for the user (worse runtime
performance), and good for noone (except perhaps C++ detractors).

(1) A Python implementor could use whole-program analysis to assign variables
and expressions more useful static types than `AnyObject` - similar to what
STALIN does for Scheme. But, again, this is bad for the implementor (more
work), bad for the user (less interactivity and instant gratification, due to
the constant rechecking of the whole program every time a change is made), and
good for noone (except perhaps Python detractors).

Now, there exist language designs that are less biased towards a fixed
implementation strategy. For example, Common Lisp, Standard ML and Haskell.
But these languages are also markedly less popular, which perhaps suggests
that programmers usually prefer languages that have a concrete story about
what use cases their design optimizes for.

~~~
pcwalton
> A C++ implementor could use a strategy similar to what is used in Java and
> C#, and re-instantiate every template on demand at runtime.

Are you sure? Expanding templates can affect the parsing of subsequent code,
as this example illustrates: [http://yosefk.com/c++fqa/web-
vs-c++.html#misfeature-3](http://yosefk.com/c++fqa/web-
vs-c++.html#misfeature-3) You pretty much have to expand them at compile time.

(This sort of complexity illustrates why I prefer generics to templates,
incidentally.)

~~~
catnaroek
What I meant is:

(0) Expand the templates at compile-time, in order to type-check the code.

(1) Don't generate target language code for each specific instantiation,
though.

(2) Re-expand the templates (or some representation of them) at runtime.

It's a very silly implementation strategy, of course. But I don't see why it's
fundamentally impossible to do this - it's just undesirable.

And, yes, I agree about generics being better.

------
geodel
Many great points. It is interesting to note that Rust IDE, when it comes, is
most likely to have Java based GUI.

> Both Rust and Java keep their generics to compile time.

I thought Rust generics are also available at runtime so they are different
from Java.

~~~
untothebreach
no, you can have "trait objects" in Rust, which are boxed and use dynamic
dispatch instead of static dispatch, but they lose the original type (type
erasure -- another similarity with java :)), so they aren't true generics.

For example, you could use the `Read` trait as a type:

    
    
        fn some_func(a: Box<Read>) { }
    

but then only the `Read` methods would be available on `a`, you wouldn't be
able to access methods from the original type of `a`.

~~~
solidsnack9000
> so they aren't true generics.

Why does type erasure mean they aren't true generics?

------
lmm
If you don't have a hard requirement for manual memory management then there
are good rust-like options on the JVM - Scala if you want java-like maturity
and tool support, perhaps Ceylon if you want rust-like new-language elegance.

------
sremani
[https://github.com/PistonDevelopers/VisualRust](https://github.com/PistonDevelopers/VisualRust)
Rust development in Visual Studio.

~~~
voltagex_
I looked at this but never got past Hello World. Have you used it much?

------
jmgrosen
A minor point on a great article, but "On the other hand, Java’s enum values
are really singleton classes under the hood – so one can define an abstract
method in the enum to implement differently in each value, something that
would require a match expression (or hash-table, whose construction at compile
time some enterprising Rustaceans have built a crate for) in Rust" isn't quite
true -- you can implement methods on enums in Rust, too:
[http://is.gd/M3VJJR](http://is.gd/M3VJJR)

~~~
dbaupp
I suspect the author was talking about defining methods for individual
variants of an enum, something like

    
    
      enum Foo { A, B }
      impl Foo::A { fn method_on_a(&self) {} }

~~~
da4c30ff
There is an RFC[1] for making enum variants first-class types.

[1]: [https://github.com/rust-lang/rfcs/pull/1450](https://github.com/rust-
lang/rfcs/pull/1450)

------
andrewchambers
One language I encourage people to try is myrddin
[http://myrlang.org/](http://myrlang.org/).

