DEV Community

Cover image for ¿How to make unbreakable code?
Jesus Bossa
Jesus Bossa

Posted on

¿How to make unbreakable code?

Available spanish version here

Suddenly, it sounds weird, at first, unbreakable code, what does it mean.
In short, it is a code that breaks, basically that the compiler or interpreter generates an error.

¿How do we get to something like this?

Well, when we write code, many things that we normally do are exposed to errors, some more than others, even occasions that are not caused by developers or users, for example, let's consider the following example.
Normal flow of an app
A simple request, we want to update our age in a social network, and the back-end receives the request from the front-end, then it checks that the data is correct, changes the database, and tells us that everything went fine. At any of those points, the example could fail, like if the internet connection went out or if the data was incomplete.
So, how we handle error cases, depending on the language, there are several options, try/catch, promise catch, which is basically exception handling.

Let's talk about try/catch

This way of handling exceptions was implemented way back in the 60s, it started in lisp, it was popular enough that the programming languages of the time decided to implement it as well.
Why do I think this is not the best idea? Well, it happens that in this structure.
Try / catch and railway oriented programming
TRY executes the happy path, all that should happen if all goes well, if it doesn't execute CATCH, the exception handler.
CATCH which is what happens when the above process fails.
In the ⁣CATCH we are saying that something happened that we probably don't know what happened. We entered an exception and exited the normal execution of the app. Errors should not be exceptional, at least not in a system or robust development architecture.

¿So if not, then how?

It is always helpful to take charge of knowing what is happening in the code. The best friend in these cases is the compiler, which is a well-informed interpreter of everything we enter into the code. It is always helpful to avoid dynamic typing.

  • Python
def sum_numbers(a, b):
    return a + b
print(sum_numbers(10, 5)) # 15
print(sum_numbers('Bob', 'Mark')) # BobMark
Enter fullscreen mode Exit fullscreen mode
def sum_numbers(a: int, b: int) -> int:
    return a + b

print(sum_numbers(10, 5)) # 15
print(sum_numbers('Bob', 'Mark')) # Error
Enter fullscreen mode Exit fullscreen mode
  • Javascript / Typescript
function sum_numbers(a,b) {
    return a + b
}
console.log(sum_numbers(10, 5)) // 15
console.log(sum_numbers("Bob", "Mark")) // BobMark
Enter fullscreen mode Exit fullscreen mode
function sum_numbers(a: number, b: number) {
    return a + b
}
console.log(sum_numbers(10, 5)) // 15
console.log(sum_numbers("Bob", "Mark")) // Error
Enter fullscreen mode Exit fullscreen mode

In the first example of each language, we see an example of as a common and harmless function, but not knowing the type of each parameter that the function receives could trigger an error in the long or short term.
I would recommend in these cases to use strong typing, we should tell in the example that they are numbers or text or only numbers, whatever you think works for you; we should make sure what we are going to receive in the functions to not receive unknown parameters and trigger an error.

However

This solves the simplest problems, but what happens when the data is optional or is one or the other, simply here we could handle this cases with IF, CASES, to identify if data or an error is coming.
However, there is a more complicated case, which happens when the native functions of the interpreter or compiler fail us; what if we do a division by zero, that the compiler knows that it is going to work with numbers but never what numbers.
There are times that it is not until the execution that we realize, unless we take them into account, the easy one is an IF watching cases of having a zero in both sides to not execute the code, but what if we have no way of knowing this.
There are libraries of safe mathematical operations that take care of this type of validation. Programming languages also tend to update themselves to be more kind to the developer and detect this type of problem in time. For example, they could use TypeScript or Rust to check for potential errors.
In my opinion, there is a language that does this spectacularly, Rust introduces a concept called panic, which is not an error, but it gives us an early warning that what we are doing may fail and almost forces us to handle it; In fact, a curious fact about why Rust is so loved is because it is very difficult to make it fail, since the compiler of this language is excellent, so much that it is effortless to make unbreakable code.

Sometimes technology, like Rust and strong typing, can be more or less complicated depending on the type of the educational moment or company that you are, but at least knowing that these things exist is important, and I hope that someone learned something new today or was encouraged to use some of these technologies. Thank you for reading.

Top comments (0)