
When Rust Makes Sense, or The State of Typed Languages - lmm
http://m50d.github.io/2015/09/28/when-rust-makes-sense.html
======
gmjosack
I'm personally interested in Rust for a couple reasons.

As an SRE/SysAdmin I struggle to believe that C or C++ can be written safely.
It is very common that I see software being emergency patched because of
memory unsafety from very experienced engineers in ubiquitous software.

Why would I need the performance/efficiency of C in the first place? Well, I
regularly write software that runs on thousands to tens of thousands of
machines in production. This software runs below the service. I feel a certain
sense of pride in minimizing my observer effect on the system. With Rust,
compared to Python, I can write software that has more functionality with a
fraction of the memory and CPU utilization.

Another thing that has become more appealing to me is the strong static type
system. Not having a formal background in CS I fell in love with Python for
how it enabled me to move quickly, and Python is still my go-to language for
most things, but after years of supporting large production sites plus running
my own code in production I'm a bit tired of runtime exceptions. We have great
exception logging and there are entire classes of bugs we'd just never see
with Rust's type system and error handling.

Essentially, Rust gives me new super powers and the borrow checker is my
sidekick making sure I don't shoot myself in the foot.

~~~
lmm
This is exactly the scenario I found so confusing, and why I wrote this. I can
understand not wanting to use F# or Scala for sysadmin work, but OCaml or
Haskell would give you the safely and 95% of the performance (i.e. much better
than Python) without the need for manual memory management.

Did you consider either of those? Were your reasons for preferring Rust
similar to what I put in the article?

~~~
gmjosack
I answered a similar question to a sibling comment but I think it boils down
to, I didn't come to Rust for functional features but I definitely enjoy them.
The languages you mention in the post have a much higher learning curve coming
out of Python. I spent a few tries "learning" Haskell and I really didn't
enjoy it. In general when I've looked at Scala/Haskell/F# they use so many
multi-char operators that it starts to look like line noise. OCaml always felt
a bit too niche for me too I think, though that may be bias of the industry
I'm in.

~~~
MichaelGG
It's important to note that F# doesn't really have many operators at all. The
one most people see, |> which "pipes" an argument, is defined in an F#
library, not in the compiler or part of the core language. You can define it
yourself to be anything you like, or not use it at all. The language is
unaware of it and treats it like anything else. The definition is just:

    
    
      let (|>) x f = f x
    

That's literally function application, in reverse. That's all. It comes in
handy for type inference and to make things look nice, but isn't special in
any way. I mention this as one comment as to why Rust doesn't have such an
operator was that "Rust uses channels for data flow" which is a non-sequiter.
Rust just doesn't value conciseness as much, and I'm guessing the safety/perf
restrictions might complicate matters.

In fact, even the + and - operators are implemented in F# and shouldn't count
as part of the language (just very commonly used bits of the stdlib). I fear
that perhaps not enough intros to F# focus on the relatively simple underlying
language, and that everything else on top is just an application of said
language.

With the type system, it's actually easy to figure out the operators, based on
the type alone. Looking at |> for instance, we see a type of:

    
    
      'a -> ('a -> 'b) -> 'b 
    

This makes it entirely obvious. There's only one implementation for such a
type definition. This holds true for so much of the stdlib that the "noise"
quickly fades away. This is relevant as magic cannot hide, and misuse will
quickly be identified by the compiler.

But it's a valuable comment as it illustrates that the simplicity is not being
marketed correctly and turning away potential users.

------
skimpycompiler
Rarely do I ever manage memory in C++. As much as I adore Haskell there's a
bunch of stuff you cannot do fast enough in any of the languages described
above, as easily as you can do it in C++.

Try writing a fast A* (without any pointers and memory management, easily done
in C++), maybe a travelling salesman problem -- simple 2-opt heuristic (easily
done without memory management). If you find these suitable for libraries, and
not something you would write on your own, there's not a single fast matrix
library implementation in Java or Haskell. If something that "simple" can't be
done, then, in my case, I cannot use these languages as easily as I can use
C++.

A simple principle, a simple idea of copy and move semantics enabled me to
write C++ code without worrying much about memory at all. When allocations
become a problem, I just move the container out of that heavy loop, or change
my malloc implementation with a simple flag, and it's still 10x if not 100x
faster than what Haskell/Scala/Java could accomplish in the same amount of
time it took me to write the C++ code.

~~~
eru
I agree, especially for mere mortals. However, a talented writer, like Don
Stewart and a few others, can write high performance Haskell code.

The high performance part of your Haskell code might not look much like
idiomatic Haskell in the end, but you can write abstractions around that. (The
holy grail is high performance idiomatic code. If you befriend the compiler
just right, it's possible for many problems.)

Text.Bytestring is a good example in Haskell land.

~~~
Patient0
small correction: Don StewarT not Steward

~~~
eru
Hah, I even looked it up, because I wasn't sure, but forgot to change it.
Edited now.

------
MichaelGG
It is confusing to me, too, why a Ruby or Python user would look at Rust (for
the same use cases). Unless they want it to replace C for native extension
libraries: then it makes a lot of sense. But I'd expect a Python user to pick
up Go before Rust, simply because Go is more like Python (managed runtime).

Rust comes up a bit short, I think, when looking at some functional styles.
Function composition doesn't look very easy in Rust, so a lot of the concise
code you might expect in a functional language is much more work to express
(no custom operators either). Not that I blame them: having no-overhead (no
GC, but also no spurious code/allocations in general) yet fully safe as a core
design goal is a huge constraint that no one else has had success under.

~~~
lambda
I'm coming from having written mostly Python, Ruby, and Scheme for my past
three jobs.

I am not looking at Rust merely for replacing C for native extension
libraries.

I'm looking at Rust for having a good static type system; I'm getting very
sick of dealing with "hashly-typed" data in Python, or all those places where
I forget a yield and so never actually block on a deferred, causing errors at
runtime rather than just not compiling (sometimes type errors, if I try and
access that value, but sometimes just things executing out of order, which are
much harder to debug).

I'm looking into Rust for having a good multi-threading story. I've been doing
plenty of event-driven programming in Python (using Twisted), which is great
for non-blocking network I/O, but there are other ways to block on long
computations, disk I/O, blocking in native libraries, and so on. At some
point, you really do need good multi-threading, and Python falls fairly short
in that department. You can hobble by, but it's not pretty.

Go doesn't solve either of these problems. It has slightly more static typing
than Python, but without generics, it's pretty limited. It doesn't really do
anything to prevent nasty race conditions with shared data structures in
multithreaded code. Sure, if you are disciplined and use only message passing
of immutable data structures, you can avoid some problems, but part of the
point is that when programming in the large, with multiple people working on
something over multiple years, it's easy for some mistakes or bad assumptions
to creep in an wind up causing problems.

I've taken a look at Go, and it never really appealed to me as a direction to
move in. If I want message passing concurrency in a GC'd language with a
runtime, I can use Erlang/Elixir. If I want just simple, pretty code without
much multithreading, I can use Python. If I want raw performance and low level
access, I can use C or C++.

Rust actually does offer advantages over all of these. It does have it's
complexity, so for quick and dirty scripting tasks I'm likely to stick with
Python. But especially once Rust gets an easier to use non-blocking I/O story
(since event based non-blocking is great for networking), I'm going to be
seriously considering it simply as a replacement for Python for any large
project that will be worked on by several people over several years, just due
to the additional safety and static guarantees it offers.

~~~
lmm
Have you looked at the other four languages I mentioned, e.g. OCaml?

~~~
lambda
Yes, I discussed those in another comment:
[https://news.ycombinator.com/item?id=10290874](https://news.ycombinator.com/item?id=10290874)

In this comment I just discussed Go, since that's what the parent comment
mentioned.

Haskell and OCaml are both great languages, but to a lot of people, they come
off as much more "academic" or "ivory tower," and require a lot more effort to
learn to use effectively for people who are not used to functional
programming.

Couple that with the fact that they still use GC, so are a lot harder to get
consistent low-latency performance as well as being a lot more difficult to
use for any applications where you need to embed them in other applications,
and they just don't offer enough of a reason to move to them over the current
combination of "Python for high-level stuff, C or C++ for low-level,
performance sensitive stuff".

Rust, on the other hand, promises to be effective for the low-level,
performance sensitive stuff, is good for embedding in other languages, offers
the additional benefit of giving statically checked memory safe multithreading
with shared mutable data structures, and provides a powerful static type
system for effective programming in the large.

~~~
runeks
> Haskell and OCaml are both great languages, but to a lot of people, they
> come off as much more "academic" or "ivory tower," and require a lot more
> effort to learn to use effectively for people who are not used to functional
> programming.

I think the problem is that people who are used to C++ and Python approach
Haskell as if it were just another language, in that category of languages.

You need you learn some new stuff in order to really understand Haskell, but
that's hardly a fault. I actually think non-programmers would have an easier
time learning Haskell than experienced programmers. There really isn't
anything inherently difficult in Haskell. It just requires a different
approach.

It can be annoying to write Haskell programs sometimes, because it's so hard
to get it to just compile. But that's the entire point: the fact that the
compiler can do so much when we restrict ourselves to pure functions. It also
forces us to figure out exactly what our program needs to do, before we can
implement it, rather than build on top of proof-of-concepts, as is typical
with Python.

~~~
kazinator
> _It also forces us to figure out exactly what our program needs to do,
> before we can implement it._

Note that the pronoun "it" in your sentence could easily have antecedents such
as "assembly language" or "Brainf __* ".

------
rwmj
OCaml _" writing a first-rate concurrency-friendly runtime would require
massive investment"_. Except it's already being done in OCaml 4.03 [1]. I
still don't think this is actually a problem, since in many cases (NUMA,
distributed systems) it's better to use other approaches. If the article is
serious about safety, then it wouldn't encourage people to use threads with
shared memory.

[1] [https://sympa.inria.fr/sympa/arc/caml-
list/2015-05/msg00034....](https://sympa.inria.fr/sympa/arc/caml-
list/2015-05/msg00034.html)

------
yokohummer7
As a Rust proponent, the reasons listed in this article match my sentiment
surprisingly well, although the author seems to think Rust isn't ideal for my
use cases. I'm also from Python, which I've used for more than 10 years, and
chose Rust as my next weapon.

\- Haskell: While pervasive laziness does have its merits, I believe it is not
the best choice in general, especially for performance-wise. Having to use
streaming libraries to do even a simple I/O is just ridiculous. Its syntax was
also a big obstacle to me, but thankfully I overcame it. But I'm not sure I
can also persuade my colleagues to do the same thing.

\- Scala: If I have a JVM requirement, Scala would be a really good fit.
(Un)fortunately I don't have such a limit, so what Scala provides are less
appealing to me. It also seemed way too gigantic to me at a glance, probably
to be interoperable with Java. But I've not tried it deeply.

\- F#: I've only heard good things about that, and it was quite a great
experience learning through its great IDE. The problem is that even though
MS's recent moves I'm still not completely sure if I could retrofit myself to
the .NET ecosystem. But the future is bright.

\- OCaml: OCaml always felt a bit "obsolete" to me. AFAIK it even didn't have
multi-core support until very recently (no parallelism, concurrency only), and
they seem to have no resources for a decent Windows support. It has also a
funny syntax. I definitely agree Rust's syntax is ugly at best, but OCaml's
is... I just can't describe it. Hopefully I can get used to it someday, like I
did to Haskell.

And I met Rust and instantly fell in love, even though it requires me to do
manual memory management. While manual memory management makes a certain data
structure harder to implement, what I realized is that for my daily job,
especially for "boring" works (e.g. CRUD apps), it is OK to use manual memory
management. If there's a need, I can always borrow libraries from others to
accomplish my job. And it is fast by default, less need to optimize the code
by myself, as seen in Haskell.

That said, what I have as a "best" language in my mind is, probably a strict
version of Haskell. Yeah, that would be Idris, like the author suggests. I
really hope that Idris will take off in the near future.

~~~
groovy2shoes
OCaml's syntax is really not that different from F#'s. This isn't surprising,
since F# was originally just "OCaml for .NET".

------
osullivj
The author wonders why Rust is getting attention in 2015, despite lacking GC.
The answer is concurrency, a much more difficult problem than avoiding null
ptr derefs. C++ advocates are right to say that with Boost libs and C++ 11 and
14 it's much easier to avoid mem mgmt problems. Concurrency remains hard, and
Rust's borrow mechanism is the biggest step forward since the late 90s IMHO.

~~~
lmm
How does borrowing help with concurrency? You can only borrow on the same
stack, no?

~~~
osullivj
[http://blog.rust-lang.org/2015/04/10/Fearless-
Concurrency.ht...](http://blog.rust-lang.org/2015/04/10/Fearless-
Concurrency.html)

------
Drup
In all the section related to OCaml, replace "concurrency" by "parallelism".
OCaml has an excellent concurrency story (through libraries like Lwt and
Async) and a decent story for message-passing parallelism. The issue appears
with (GC-managed) shared memory.

Incidentally, the work on the GC is on its way.

------
diminish
If someone writes a nice summary of what is missing/failing in each one of
those typed languages, would be very fruitful. At the end why don't we see a
flood of people quitting C/C++ or dynamic languages to jump to those
challengers?

~~~
conceit
inertia. Observers are waiting for a killer app to sway the masses. Obviously
memory safety isn't a killer feature in many eyes, because they trust their
abilities, would have to go all out using the unsafe environment or they don't
see the benefit of one less class of bugs over other concerns. If they did any
of that, they would at least be using e.g. java already - on another note I'm
only waiting for rustc's first security relevant bugs to be reported, that are
supposedly impossible.

I heard the name was a play on words on a one-of-error concerning Trust.

~~~
kibwen
Nobody pretends that bugs in rustc are impossible. :P Go peruse the issue
tracker if you don't believe me, though many of the soundness bugs there are
so obscure that I think you'd have a hard time exploiting them in theory, let
alone in practice (and they're also liable to be fixed well before Rust starts
getting deployed en masse).

------
heinrich5991
The text is somewhat hard to read for me. Upon a closer look it seems that the
text has different font sizes in it. I tried to mark some inconsistencies:
[http://i.imgur.com/ECUBQA5.png](http://i.imgur.com/ECUBQA5.png)

Is this intentional? If so, what purpose does it serve?

~~~
yokohummer7
The page renders well in my browser, and lookup at the generated HTML there
doesn't seem to be something suspicious... Maybe one of the fonts doesn't
render in your browser?

------
moomin
I think people who've experienced the awfulness of cabal should give Haskell
another try with stack.

------
graffitici
Can somebody expand on the "social issues" with Scala?

~~~
kod
It's really just the blog author's subtle way of saying that a particular
individual (probably Tony Morris) is an asshole.

------
moomin
Worth mentioning that footnote [2] also applies to Haskell, but not to the
same extent.

------
sagichmal
Reformatted to be readable:
[https://gist.github.com/anonymous/296f6c90dcbc9033d97c](https://gist.github.com/anonymous/296f6c90dcbc9033d97c)

~~~
walrus
Do you have HTTPS Everywhere installed or JavaScript disabled? The site tries
to load a Markdown-rendering JS library over HTTP, so if you visit
[https://m50d.github.io/](https://m50d.github.io/) instead of
[http://m50d.github.io/](http://m50d.github.io/), your browser won't render
the Markdown.

~~~
emn13
I think it's sort of weird how people have latched on to markdown. Minimalist
html is hardly any wordier than markdown, and at least that works everywhere,
and works the same everywhere (unlike xyz-flavored markdown of the month), and
it allows an escape hatch into complex layout when you really need it.

~~~
d_theorist
Markdown is fine, but I can't understand why you would want to render it in
the browser. Why get the client to do the work with every request? Just render
it once on the backend and deliver the html.

~~~
emn13
Sure, it's "fine" \- it's just unnecessary, less portable, less future-proof,
and more complex to render (as this article demonstrates). What's the point?
Why opt for that complexity when you don't need to? Just to save a very low
percentage of key-strokes? That strikes me as being penny-wise & pound
foolish. And much as most text is fairly bare-bones, sometimes you do want
extra layout control - and then markdown is really in your way.

~~~
d_theorist
I don't see why it's either less portable or less future proof.

It's a different markup. One that many people find easier and more natural to
write. Of course, different people have different opinions on that.

For people who find writing and reading markdown nicer than HTML it makes
sense to use markdown as the base format that you write everything in, and
then convert to different formats as needed (html, pdf, whatever).

For you, HTML may play that role. Personally I find HTML ugly to read and
write.

~~~
emn13
I agree that markup is easier to write - it's shorter. And typical html is
much messier. But if you wrote html the way you did markdown the difference is
much smaller. In fact - look at the OP's text. That article in html would be
barely longer.

To summarize: markup is better to read+write. But the difference is almost
zero. Anything other than trivial markup is a mess; exceptional layout often
impossible (and I value the ability to creatively use layout to get my point
across). It doesn't support wysiwym editing (very well). It isn't trivially
statically hostable - and if you try it's fragile and flashes uglily. Many
flavors exist that are slightly different.

I prefer flexibility, consistency and simplicity over micro-optimizing source
readability.

