1. 程式人生 > >Rust and the Three Laws of Informatics

Rust and the Three Laws of Informatics

Laws and Languages

The Three Laws of Informatics refer to programs only. Yet programming languages may provide guarantees, constructs, tooling, an execution environment, a community or an ecosystem that help developers make law-abiding programs. Let’s look at some of the players.

System languages

C and C++ share some properties. They’re great to write fast, low-footprint code. Manual memory management leaves safety in the hands of developers (who can barely remember where they left their phone!). C comes with no batteries included, so you often end-up rewriting data structures ; C++ is such a monster that each project defines which part of the language they use or don’t (Google is famous for not using exceptions). Because they are both unsafe, depending on another library increases the risk of security vulnerabilities.

Go filled the void left by C++ scaring developers away. It aims to be fast and to make writing concurrent code easy using routines. It is garbage collected, which makes it safer than C++. It features a simple type system, devoid of generics and algebraic data types, which does not support code reuse as well as other modern languages. Still, it has a very active community, maybe enticed by Google’s aura and following in the footsteps of Docker.

The JVM ecosystem

Java is a reasonably simple, regular language. There is a clear history of reuse in Java, which is probably champion in terms integrating 3rd party artifacts — sometimes making large projects look like Frankenstein’s monster. Java has excellent tooling that is supported by the language and the virtual machine. Modern JVMs compile code “just-in-time” and turn it into rather efficient, native code. There are different garbage collectors that provide different trade-offs. Oh, did I mention the Java community is huge?

Kotlin tries to provide an alternative to Java “the language” by reducing verbosity and providing a stronger, null-safe, type system. It is mainly targeting the JVM and comes with the same benefits as Java there (there is also Kotlin/Native). Created by JetBrains, the tooling is obviously excellent. Now officially supported for Android development, it is here to stay.

Functional Programming — or FP — languages

Haskell and OCaml began their lives as research projects, but have been getting more popular in the industry in recent years. They are safe, provide great design primitives (notably type classes and modules) and a programming model that, in my experience, leads to fewer bugs. They are both garbage collected—GC was invented for LISP, the first FP language. Haskell, in particular, is completely pure which provides great benefits: all effects — such as IO — are explicitly expressed as types, which frees the developer from worrying about side-effects happening unexpectedly, but can become cumbersome. Their communities both include many researchers which help build solid, formal foundations.

And many more languages

I’m not going to go over every other language out there. Some have very obvious strengths in their ecosystem and community. Python has an excellent ecosystem for data analytics, Erlang helps building fault-tolerant distributed systems using actors, Scala is Kotlin’s older, wilder sibling, Clojure and Racket are modern Lisps, and TypeScript tries to make sense of JavaScript!

The Awakening of the Third Law

There are indeed many interesting languages out there. Most of them have their strengths and share of good ideas. How much do they help willing developers to follow the Three Laws of Informatics?

Maintainability is mostly addressed by good design primitives — a.k.a language constructs — , good tooling and community. There are different schools with different opinions on what constitutes a good set of primitives: I personally favor those chosen by modern, strongly typed FP languages.

Leaving maintainability aside, there has been two group of mainstream languages: those with manual memory management and those with garbage collection. Since we developers are imperfect, manual memory management also means unsafety and thus lack of correctness. Garbage collection, while incurring an overhead, has been the de facto standard in new mainstream languages for the last 25 years because safety matters more than absolute performance.

Rust is the first popular language to propose an alternative — automatic memory management and safety without garbage collection — and it comes with powerful FP-inspired design primitives to build high-level abstractions, and much more.

If we can now safely build more efficient software, shouldn’t we? Or should we optimize for development productivity? Could we have both?