Chapter 9
Programming Basics - Conditions and Loops

The basics of an algorithm.
Reading time : 5 minutes


Second and final part of the introduction to programming. Previously, we covered the different types of variables. Some are primitive, representing numbers, strings, or collections of data. The developer can also create custom types to represent the business logic of the company.

We briefly touched on the concept of a function: an algorithm is applied to input data to produce output data.

Example of a function that adds 2 numbers.
function add(a: number, b: number): number {
    return a + b
}

Here, we will learn the basic elements that make up this algorithm: conditions and loops.

The theory is quite simple. These fundamentals and ways of thinking are now taught in schools from an early age. We will see that practice can hold a few surprises!

Conditions

If this is true, do this; otherwise, do that.

A condition is a set of instructions whose result is evaluated as true or false:

  • Is my age less than 35 years?
  • Is my fridge empty?
  • Is my phone an Android?

The keywords used in most languages are if, elseif, and else.
Example: If the weather is nice, I'll go to the park; otherwise, I'll spend the day watching Netflix.

if (weather === 'sunny') {
    goToPark()
} else {
    turnOnNetflix()
}

Instructions can be chained together using logical operators:

  • NOT, written as "!" or NOT. It is used to evaluate the opposite condition.

    Example: If it's not raining, I'll go to the park.
  • AND, written as "&&" or AND. Both parts must be true for the entire condition to be true.

    Example: If I like beer AND my reservation for my trip to Belgium goes well, then: I'll visit a brewery.

    The trap with AND is that as soon as one part is false, the whole condition is false, so the rest is not executed.
    In the example, we thought we were writing "I have a reservation in Belgium, since I also like beer, then I'll visit a brewery." Instead, we wrote "since I like beer, then I'll make a reservation in Belgium and visit a brewery." The trip reservation won't be made for someone who doesn't like beer.

    So be careful with the order in the condition!
  • OR, written as "||" or OR. Only one part needs to be true for the whole condition to be true.

    Example: If I currently have less than €1000 in my account OR after paying myself I have less than €2000 in my account, then: I'll dip into my secret stash.

    The trap with OR is that as soon as one part is true, the whole condition is true, so the rest is not executed.
    In the example, if the action "after paying myself" triggers the action "pay myself," it might not execute, and I end up without a salary.
  • XOR, written as "XOR" or "^". Only one part must be true for the whole condition to be true.

    Example: If ONLY Anne OR ONLY Ben is there, then the evening will be cool. Otherwise, it will be weird because they don't get along.
  • Less common in programming, there are also variations: NOT AND, NOT OR, NOT XOR.

In the previous chapter, we discussed the type that represents "true" or "false" values: booleans. This name comes from mathematician George Boole, the creator of Boolean algebra, which laid the foundation for digital circuit theory and modern computing. Boolean algebra is a branch of mathematics concerning operations on booleans. Developers use it daily!

Some examples:

  • Double negation: the opposite of the opposite of "it's sunny" is "it's sunny."
  • Commutativity: "sunny" and "warm" is the same as "warm" and "sunny."
  • Associativity: I drink Coffee OR Tea OR Water = (Coffee OR Tea) OR Water = Coffee OR (Tea OR Water)

It’s obvious with small examples like this, but it can be a real headache in complex business cases.

Another mathematician, De Morgan, formalized laws on negations that help us a lot to avoid getting confused and simplify conditions:
NOT(A AND B) = NOT(A) OR NOT(B)
NOT(A OR B) = NOT(A) AND NOT(B)

Example 1: the opposite of "I am a web developer and freelancer": NOT(web developer AND freelancer) =
Either I am not a "web developer," or not a "freelancer": NOT(developer) OR NOT(freelancer).

Example 2: the opposite of "I drink coffee or tea": NOT(coffee OR tea) =
I drink neither coffee nor tea: NOT(coffee) AND NOT(tea).


This Boolean algebra can only work if the result of the instructions around the logical operators is a boolean. But that’s not always the case... Some instructions are function calls that can return any type of value. The language interpreter must implicitly convert this data into a boolean. The rule is simple: what is not false is true.

Most languages consider as false: the number 0, an empty string, an empty collection, an uninitialized variable.

We take advantage of this behavior, especially to test the existence of something.

myBooks = findBooksInLibrary()

if (myBooks) {
    // There are books in the library.
} else {
    // The library is empty.
}

Conditions are part of the daily routine for developers. Complex cases with multiple variants force them to reorganize their code to maintain good understanding and avoid bugs.

Loops

Execute this as long as that is true.

A loop is a way to execute the same code multiple times. There are several types:

  • As long as this condition is true.
    Example: as long as I'm hungry, I'll keep eating. The main keywords are "while" and "for".
  • For each element in this collection.
    Example: send the newsletter to each subscriber. Keyword: foreach.
while (!glassIsEmpty) {
    drink()
}
shoppingList = ["Apples", "Bananas"]

shoppingList.forEach((item) => {
    buy(item)
})

Recursion

A recursive function is a function that calls itself. Like loops, it’s a way to execute the same code multiple times. It’s useful for traversing a hierarchy of elements nested within other elements and applying the same process to the entire chain.

Example: I want to know the number of descendants of a person. We will recursively traverse all the branches of their family tree.

function countDescendants(person) {
    children = findChildren(person)

    numberOfDescendants = children.length

    children.forEach((child) => {
        numberOfDescendants += countDescendants(child)
    })

    return numberOfDescendants
}

Some recursions are less direct. Function 1 calls function 2, which then calls function 1. Poor design can easily generate an infinite loop, consuming all the machine's resources and killing production.
So be cautious!



This is the end of this introduction to programming.
You now have all the basic tools to start writing small algorithms and deepen your programming knowledge on your own.