I am saying that the material looks like cherry-picking because it uses some selected arguments that are expected to work in Rust’s favor simply because Rust is a static language. Does Rust offer more type-safety than Julia? Obviously - all together with F#, Haskell, C#, and many other languages.
It is known that the compiler will catch more bugs in static languages. This cannot be used as an argument for “Julia does not solve the two languages problem”.
Also, there is an argument where the material compares two different versions of pop!
function.
A closer comparison to the Rust pop!
version would be this one:
function rustpop!(x::Vector)
isempty(x) && return nothing
pop!(x) |> Some
end
function wrongusage()
x = [1]
rustpop!(x) * rustpop!(x)
end
Now, if you are aware of the Julia ecosystem, you might use JET - which will throw the following - without needing to run the code and encounter the error at runtime:
no matching method found `*(::Nothing, ::Nothing)`, `*(::Some{Int64}, ::Nothing)`, `*(::Nothing, ::Some{Int64})`, `*(::Some{Int64}, ::Some{Int64})` (4/4 union split): (UniLM.rustpop!(x)::Union{Nothing, Some{Int64}} UniLM.:* UniLM.rustpop!(x)::Union{Nothing, Some{Int64}})
Also, there is a good chunk in the blog post showing how to handle enum
in Rust properly:
let mut v = vec![1.0];
let v1 = match v.pop() {
Some(value) => value,
None => 1.0,
};
let v2 = match v.pop() {
Some(value) => value,
None => 1.0,
};
v1 * v2
# the above shows how pattern matching works in Rust,
# the actual production code would be reduced to:
v.pop().unwrap_or(1.0) * v.pop().unwrap_or(1.0)
Why not present the Julia equivalent? It will result in the same level of type-safety:
x = [10.0]
v1 = something(rustpop!(x), 1.0)
v2 = something(rustpop!(x), 1.0)
v1 * v2
Also - presenting an example like the usage of Vector{Any}
as some performance foot gun is not a good idea: Vector{Any}
can work wonders in part of the code where the performance is irrelevant (thus Julia’s flexibility). People will not use Vector{Any}
inside some tight loop where the performance is crucial: and instead of writing v1 = []
, they would use v1 = Int[]
(or whatever type is appropriate in the context).
Some of Julia’s features can indeed be painful points when used in some sub-optimal way because you can switch between a Python-like mask and a more restricted, type-driven mode. And this is an argument favoring the claim that Julia took important “steps towards solving the two-languages problem” - not something to be held against the language when compared with Rust.
I think everybody appreciates a good comparison - and many Julia developers are aware of Rust’s strengths - but I don’t see how this kind of comparison is helpful or even fair.