Ideas from Other Languages that Influenced Rust

In this exploration of Rust, a robust systems programming language crafted by Mozilla, we’ll delve into a fascinating fusion of performance, safety, and expressiveness. Drawing inspiration from a rich tapestry of programming languages, Rust has artfully woven together a distinctive fabric of features.
Let’s uncover the intriguing influences from other languages that have contributed to the tapestry of Rust’s design and functionality.
1. Ownership System — Influenced by C++
I went on a bit of a Twitter rant recently. In one of those daily C++ hate threads, someone listed RAII (Resource Acquisition Is Initialization) as one of C++’s “bullshit features.”
It struck a chord with me because, among the many things one can criticize about C++, they chose to target one of the few features that’s genuinely well-thought-out and beautifully designed. It’s refreshing to see that RAII has found its way into Rust.
A simple example:
struct Foo {
data: i32,
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping Foo with data: {}", self.data);
}
}
fn main() {
let _foo = Foo { data: 5 };
} // _foo goes out of scope here, and `drop` is calledIn the main function, we create a Foo named _foo. When _foo goes out of scope at the end of main, its drop method is automatically called. This is the essence of RAII: when an object goes out of scope, its resources are automatically cleaned up.
This pattern is used extensively in Rust’s standard library. For example, when you open a file with File::open, you get a File object. When the File object goes out of scope, its drop method is called, which closes the file.
RAII helps prevent resource leaks and makes it easier to reason about resource management. You know that once a variable goes out of scope, all of its resources will be cleaned up.
In Rust, RAII is implemented through a combination of ownership, borrowing, and lifetimes, along with the Drop trait.
Rust’s ownership system, a standout feature, is influenced by C++. The idea of ownership and borrowing helps manage memory efficiently without the need for garbage collection.
C++
#include <iostream>
#include <string>
int main() {
std::string s = "Hello";
const std::string& r1 = s;
const std::string& r2 = s;
std::cout << r1 << " and " << r2 << std::endl;
return 0;
}Rust:
fn main() {
let mut s = String::from("Hello");
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2);
} // r1 and r2 go out of scope, but no issues with memory management2. Concurrency — Inspired by Erlang
Rust’s concurrency model, which emphasizes safety without sacrificing performance, draws inspiration from Erlang. The ownership and borrowing system ensures thread safety without the need for a garbage collector. Here’s a snippet showcasing Rust’s concurrency:
Erlang:
-module(main).
-export([main/0]).
main() ->
spawn(fun() -> thread_function() end),
main_thread_function().
thread_function() ->
lists:foreach(fun(I) -> io:format("Thread: ~w~n", [I]) end, lists:seq(1, 5)).
main_thread_function() ->
lists:foreach(fun(I) -> io:format("Main thread: ~w~n", [I]) end, lists:seq(1, 3)).Rust:
use std::thread;
fn main() {
let handle = thread::spawn(|| {
for i in 1..=5 {
println!("Thread: {}", i);
}
});
for i in 1..=3 {
println!("Main thread: {}", i);
}
handle.join().unwrap();
}3. Pattern Matching — Borrowed from Haskell
Pattern matching, a powerful feature in Rust, is influenced by Haskell. It allows for concise and expressive handling of various data patterns.
Haskell:
data Coin = Penny | Nickel | Dime | Quarter
valueInCents :: Coin -> Int
valueInCents coin = case coin of
Penny -> 1
Nickel -> 5
Dime -> 10
Quarter -> 25
main :: IO ()
main = do
let coin = Dime
putStrLn $ "Value: " ++ show (valueInCents coin) ++ " cents"Rust:
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {
let coin = Coin::Dime;
println!("Value: {} cents", value_in_cents(coin));
}4. Traits — Inspired by Haskell Type Classes and Scala Traits
Rust’s trait system, similar to Haskell type classes and Scala traits, enables code reuse and defines shared behavior.
Scala:
trait Greet {
def greet(): String
}
class Person(val name: String) extends Greet {
def greet(): String = s"Hello, $name!"
}
object Main extends App {
val person = new Person("Alice")
println(person.greet())
}Rust:
trait Greet {
fn greet(&self) -> String;
}
struct Person {
name: String,
}
impl Greet for Person {
fn greet(&self) -> String {
format!("Hello, {}!", self.name)
}
}
fn main() {
let person = Person { name: String::from("Alice") };
println!("{}", person.greet());
}Whether it’s the ownership system inspired by C++, the concurrency model influenced by Erlang, or the pattern matching reminiscent of Haskell, Rust stands out as a language that synthesizes the strengths of its predecessors.
Other Readings on Rust:
Rust or Go (heated debate version)
A Rapid Guide to All Rust Features






