avatarDavid Lee

Summary

Rust is a systems programming language that integrates performance, safety, and expressiveness by adopting influential features from other languages such as C++, Erlang, and Haskell.

Abstract

Rust, a language developed by Mozilla, stands out in the realm of systems programming by combining elements of performance, safety, and expressiveness. Its design is heavily influenced by other programming languages: from C++, Rust adopts the concept of RAII (Resource Acquisition Is Initialization) to manage resource cleanup; Erlang inspires Rust's concurrency model, ensuring thread safety; and Haskell contributes to Rust's pattern matching capabilities and trait system, which is also influenced by Scala traits. These features enable Rust to provide efficient memory management, safe concurrency without garbage collection, and code reuse through shared behaviors. The article highlights Rust's synthesis of strengths from its predecessors

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 called

In 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 management

2. 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

Rust or Go (heated debate version)

A Rapid Guide to All Rust Features

String Secret in Rust and Go

Reference:

https://doc.rust-lang.org/stable/book/title-page.html

Rust
Cpp
Programming
Technology
Web Development
Recommended from ReadMedium