Monday, August 17, 2020

Safety and the programming languages - Safety ensured by grammer

I wanted to write a post about the type system of Rust, but it has lots of concepts which are hard to understand if you don't know enough of the possible vulnerabilities and common bugs. The main concept of Rust is safety. It makes hard to create runtime errors, unpredictable outputs and it gives you more confidence about your program. However, this confidence can be dangerious if you don't understand the safety nets you have.
This article series will give you some basic information about the common bugs in programs and the built-in safety features in different languages and environments.
First of all, lets see what kind of safety functions can a language have. As you know by now, Rust is a compiled language, which means that the compiler reads and checks the whole code and creates a binary from it. This compiler is not as comfortable as a Python or JavaScript interpreter, but it gives as the first (however, very thin) safety net. (The real difference between compiled and interpreted languages is not the fast modify-run-modify cycle, but the presence of the compiler in a runtime environment. This topic worths a different post.) To understand this, lets compare these two (wrong) codes:
The first code is a Python code, which runs correctly in the 50% of the cases:

import random

a = random.random()
if a>0.5:
    b = a+c
else:
    b = 2*a
print(b)
And the second code is a Rust code, which is the same, but it won't compile until you remove the usage of undeclared c varibale. (Or declare it. Also, you have to add the line rand = "0.7" after [dependencies] in cargo.toml to have even a chance.)

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let a: f64 = rng.gen();

    let b;
    
    if a>0.5 {
        b = a+c;
    } else {
        b = 2.0*a;
    }
    println!("{}", b);
}
Python is a dynamic language, so its interpreter has no chance to decide that the c variable will exist when the code will need it or not. We can twist the Python code even further:

import random

for i in range(0, 1):
    a = random.random()
    if a>0.5:
        b = a+c
    else:
        b = 2*a
        c = a
    print(b)
Here, if you have luck (or unluck), the first iteration creates variable c and the further iterations will work. Generally speaking, an interpreted language with dynamic variables has no chance to decide if a varibale will exist in a given point of the program or not. Compiled languages on the other hand need to know (almost) everything about a variable in compile time, so they won't let you build an executable file with a possibility of undeclared variable. This is of course not a Rust-specific thing, C/C++, Java and every compiled languages work in this way.
We can generally say, that the first safety layer of a language is its grammer and the compiler itself. A compiler can prevent you to write codes with trivial (or complex) bugs in it. Even Python won't let you run a code with mispelled keywords or wrong indentation. C/C++ won't compile a code with mispelled variable in it. Java compiler makes you to enumerate or handle every possible (non-runtime) exception can be thrown by your code.
The first part of these article series will focus on the safety features provided by compiler These features can prevent the compile or they can produce runtime errors. We will see that different languages have different philosophy. Java (or Rust) in one hand tries to protect you from every possible programming error. C/C++ on the other hand lets you do whatever you want. Please, keep in mind that built-in safety functions in a language are designer decisions and not pros or cons. Just because C++ has different philosophy than Java or Rust, C++ is not inferior or superior to them. You must always select the language suitable for your task. If you have to write a simulator which needs every bit of computation power, you should select C++ (or even Assembly). If your task is to write a safety-critical application, you should choose Rust.

No comments:

Post a Comment