Why Rust?

Photo by Jay Heike on Unsplash

Why Rust?

What are the reasons for using Rust as a language for developing web applications? Can't we rely on established languages that are already suitable for web development? Here are some justifications for choosing Rust as the programming language for creating web applications:

  1. Safety

  2. No garbage collection

  3. Speed

  4. Multithreading and asynchronous programming

  5. Statically typed

Safety

Although using a system programming language to write applications is advantageous due to its power, such as accessing the fundamental building blocks of a program like allocating computer memory, it is also easy to make mistakes. Traditional system languages lack mechanisms to prevent a program from storing data in memory, creating a pointer to that data, deallocating the data, and then trying to access the data again through that pointer, even though the data is no longer there.

While seasoned programmers may be able to identify such errors in simple programs, larger and more complex applications can make them more difficult to catch. Some companies use static analysis tools to detect such mistakes, but with more sophisticated programming techniques, such bugs can still be found in many applications, as demonstrated by high-profile incidents such as Heartbleed. To avoid such problems, using a memory-safe language like Rust is advisable.

Rust is memory-safe because it has rules that govern how a programmer can write code. For instance, when the code is compiled, it checks the lifespan of a variable, and if another variable tries to access out-of-scope data, the compiler will report an error. Additionally, Rust's built-in data types, such as Option or Result, safely handle null-like behavior.

No Garbage Collector

When it comes to managing memory, programmers have come up with all sorts of wacky techniques to keep things safe. One such technique is called garbage collection. The idea is pretty simple: the program automatically manages memory during runtime, so the programmer doesn't have to stress about it. Just make a variable and forget about it - the program will take care of the rest!

Now, garbage collection is a pretty important part of computing, and there are lots of different techniques out there like reference counting and tracing. But here's the rub: garbage collection is a resource hog. It can take up a bunch of computing power and memory, leaving your poor computer struggling to keep up. Sometimes the memory even leaks and becomes unusable, because of that big pile of garbage (unused memory).

In real-time applications, the stop-the-world garbage collection mechanism can be highly disruptive. This is because the entire program execution is paused while the garbage collector recycles memory, resulting in significant delays and interruptions. As a result, software developers must exercise caution when using programming languages that rely on garbage collection for memory management in real-time applications.

Rust provides a unique solution to memory management through a technique called Resource Acquisition is Initialization (RAII). This approach ensures that objects are automatically deallocated as soon as they are no longer required, without requiring any manual intervention or garbage collection. As a result, when you create a function in Rust, any objects generated within the function are swiftly and seamlessly removed from memory once their usefulness has expired. In other words, Rust applies the KonMari method to programming languages by promoting a tidy and organized memory management system that is sure to bring joy to developers everywhere.

Speed

As a web developer, you may have heard that performance isn't a concern when using an interpreted language or a language with garbage collection. After all, web development is typically I/O bound, meaning that the bottleneck occurs when the application accesses the database, disk, or network. However, this is not always the case and depends on the usage of your application.

For example, if your application processes a lot of JSON or deals with hashing and encryption for security, then it becomes CPU-bound. In cases where you are serving millions of users or creating a backend application for an online streaming service, performance becomes a critical factor.

This is where Rust comes in as a compiled language, where the compiler converts the program into machine code that a computer processor can execute. As a result, compiled languages usually run faster than interpreted languages, which have an overhead as the runtime binary interprets the program into native machine code. While modern interpreters have reduced the speed gap using JIT compilers, dynamic languages like Ruby are still slower than compiled languages.

Multithreading and asynchronous programming

In traditional programming, synchronous programming requires the application to wait for the CPU to complete a task before moving on to the next one. For web applications, this means that the server must wait for each HTTP request to be processed and responded to before handling the next one. This isn't an issue for simple responses, such as plain text. However, it becomes problematic when the application requires time-consuming processing, such as waiting for the database server to respond or for an API call to be completed.

One solution to the waiting problem is multithreading, where a single process creates multiple threads that can share resources. The Rust language has been specifically designed to make it easy to create safe and reliable multithreaded applications. It includes various containers such as Arc to facilitate data sharing between threads.

However, spawning a thread can be expensive in terms of CPU, memory, and OS resources. To mitigate this issue, asynchronous programming provides an alternative approach. With asynchronous programming, a single thread can be used for multiple tasks without waiting for the first task to complete.

Statically Typed

You might know that programming languages can be categorized as dynamically-typed or statically-typed. In a dynamically-typed language, the type of a variable is checked at runtime, while in a statically-typed language, the data type is checked at compile time.

Although dynamic typing can make coding easier, it can also lead to errors. Programmers working with dynamically-typed languages often have to write additional unit tests to ensure the code is functioning correctly. Additionally, dynamic typing can be more expensive because every time a function is called, the routine must check the passed parameters. This makes it challenging to optimize dynamically-typed languages.

On the other hand, Rust is a statically-typed language that helps prevent mistakes, such as passing a string as a number. The Rust compiler can optimize the resulting machine code and significantly reduce programming errors before the application is released.