Variables and types

The basics of programming - part 1
Reading time : 10 minutes

👋,

Welcome to The Tech Guide.

I am Nicolas GAUTRON, freelance web developer.

It would help me a lot if you could share the subscription link.
The more of you there are, the more I will attract sponsors, ensuring this newsletter remains free ❤️.


Coding is accessible to everyone.

The real challenge lies in the architecture of the code. It needs to be testable, adaptable in case of new feature ideas, maintainable in the long term, and understandable by the 50 developers who will work on it over time.

Although each language has its specificities, the most well-known ones have huge similarities in concepts and basic syntax. This can be explained by a common ancestor that greatly influenced new languages: the C language. This allows us, as developers, to switch from one to another without too much difficulty.

That's also why cutting-edge companies don't care about hiring devs who already know their technologies. During interviews, they value reasoning, architectural concepts, business skills... Even in a new language, a dev comfortable with these topics will become, in just a few weeks, much better than a mere "code monkey" who has been using the same language for 10 years.

The language is just one of the many tools in a developer's arsenal.
Today, you start learning the basics.

Of course, the goal is not to make you a developer. It will allow you to better understand what we do in our everyday lives and maybe open the door to a different way of thinking. 💪

Examples will use the JavaScript language. It's one of the most used languages in the world, with a syntax inspired by C. Moreover, you'll be able to use your web browser's console to execute JavaScript without installing anything.

All browsers offer a console. On Chrome, you need to press F12 and then go to the “Console” tab.

Variables

A variable is a box in which we store a value for later use.

a = 1 + 2

b = a * 3

The variable “a” is assigned the value 3, so the variable “b” equals 3 * 3 = 9.

As its name suggests, a variable can vary, its value can change.

numberOfTheTechGuideReaders = 200

// You share it with your friends and then:

numberOfTheTechGuideReaders = 220

Conversely, the concept of a constant exists: once a value is stored, it can no longer be changed.

const bestTechGuide = “Nico”

// This causes an error

bestTechGuide = “Someone else”

Variables are physically stored in the machine's memory, mainly in the famous RAM sticks. So, care must be taken not to saturate it.

A variable can hold all sorts of things: text, numbers, and much more complicated stuff. In C language, the developer must master each variable and its content to manually reserve the necessary space in the memory and then free it when it becomes unnecessary.

Imagine a 32 gigabytes memory as a piece of furniture with 32 billion shelves. You want to assign the value "Nico" to a variable. The developer has to count "there are 4 characters in this word, each character takes 1 byte of memory, so I need to reserve 4 bytes". And woe betide him if he tries to store something larger than the space he has reserved!

🥳 Good news for you!

New languages, through the technologies that execute them, manage memory allocation all by themselves.

However, this is not a good reason to not know what's in your variables!

Types

For system consistency and maintainability, it's crucial to master the content of variables. We try as much as possible to explicitly type our variables in the code.

There are all sorts of types. Some are natively integrated into languages, and some are added by developers. The most widespread primitive types:

  • Integer, called int. Examples: 5, 42, -12…

    Some systems require some specifics about the size of the number because they store it differently. Is it a number smaller than 256? Thus, there are more precise subtypes: short int, long int…
  • Floating-point number, called a float. Examples: 3.14, 0.00001…

    Processors are optimized to work with integers but are really bad with floating-point numbers. Languages differentiate them to adjust their processing and their representation in memory.

    For example, in Python, 0.1 + 0.2 is not equal to 0.3 but to 0.30000000004. It's far less anecdotal than it sounds if you're working on millions of bank transactions or aligning planets. Fortunately, the community has developed tools to compensate for the native shortcomings of processors.

    Float also has its subtype: double float. It allows doubling the precision and representing very small or very large numbers. In return, it takes more memory and is slower to process.
  • Character, called a char. Examples: ‘a’, ‘?’, ‘5’…

    Yes, a number is also a character. Here we're talking about its representation as a symbol, for display purposes, for example. It's the same difference between the number 5 and its Roman representation V. A character is surrounded by quotes, thus differentiating 5 and ‘5’.
  • String. Examples: “Nico”, …, “5” 😛.

    Some languages, like Java, make a distinction between a character and a string of characters. They do not offer the same functionalities depending on the type. For example, you can count the number of characters in a string.

    Quotes / double quotes, allow differentiating a character and a string of a single character: ‘a’ vs “a”.

    The concept of a single character tends to fade away in recent languages. The developer directly manipulates strings. So no worries, in JavaScript, you can use quotes or double quotes indifferently.

    Side note: Java and JavaScript, besides four letters in their name, have absolutely no relation.
  • Boolean. It’s true or false. Some systems use true or false, others 0 or 1.
  • Array. It’s a set of values. For example: [1, 2, 3, “toto”].

    They are generally represented by brackets.

    Languages offer numerous structures for manipulating sets of data. Some guarantee the uniqueness of a value, like a dictionary. Some ensure that all values are of the same type. Some allow storing anything and everything. Some link values together so they can be traversed in order. Etc.

    The array in JavaScript is part of the very (too) permissive structures. You can store cabbages and kings in it. I could rant for hours about devs who misuse arrays to transmit sets of data without caring about what they contain.

    In what follows, we will use it to represent a collection of values of the same type.
  • Void: nothingness. When you know there is no value. We will come back to this.

Some languages are strongly typed, meaning the developer must absolutely declare all types explicitly. Java, C++, etc.

Other languages are not, or are very weakly typed. The runtime environment figures out what the variables contain on its own. Python, JavaScript, etc.

Typed languages offer more robustness and often more performance. This is indispensable in critical or embedded environments: airplanes, robots…

Typing also allows for greater maintainability of projects in the long term. It forces the developer to know their data and to construct their code so that it respects contracts. If a piece of code expects a number and you pass it text, it's going to crash!

It’s particularly this weak typing that has given a bad reputation to languages like JavaScript or PHP. They are easy to use, with a quick learning curve, development of projects goes faster... But precisely, it goes too fast! The flexibility of these languages opens the door to bad practices:

  • Unintentional: developers with low skills can build absurd architectures. And since it seems to work, they have no reason to further educate themselves and improve their practices.
  • Intentional: even experienced developers are tempted to take bad shortcuts if they are put under too much pressure with unattainable deadlines.

This largely explains the colossal technical debt encountered in web-based companies using these technologies. Mind you, I'm not saying there's no debt with typed languages, but it is often more limited and more easily repayable because the architectures are, by necessity, better designed.

The communities that, 20 years ago, advocated the flexibility of untyped systems "Hey, it's simpler, why bother for nothing!", have understood their errors and are now trying to introduce typing.

Thus, PHP is natively becoming more typed with each version. There are still some things that annoy me, but it's getting much closer to what strongly typed languages do.

The JavaScript ecosystem now includes TypeScript, an overlay that allows for very solid typing. Personally, I love TypeScript, it’s simple and effective. It will be even better when it becomes completely independent of JavaScript and natively spreads in web browsers.

Python, for its part, has introduced a module allowing explicit declaration of types in the code. For now, it's mainly to make developers' lives easier, it doesn't have a real impact on script execution: there will be no error if the typing is not respected during execution.

All these examples offer a hybrid mode: the developer can type if they wish, but nothing forces them to. This allows keeping a bit of controlled flexibility and for some cases to stay in the philosophy of Duck typing:

When I see a bird that walks like a duck, swims like a duck, and quacks like a duck, I call that bird a duck. <James Whitcomb Riley>

Objects

Developers create their own types representing the business concepts they handle.

That's why it's crucial, before starting a project, to brief developers as much as possible on the business domain: its vocabulary, concepts, organization, the current need, ideas for the future already envisaged... All this can modify the design at the very core of the code.

Domain Driven Design (DDD) is the design approach aiming to mirror the real-life business domain.

If there's a marketing department and a finance department in the company, there will be two separate software modules.

Both departments follow sales. Marketing wants to know the number of payments and the generated revenue. Finance needs the details of transactions to calculate the VAT reversal, the payment partner fees…

As a developer, at first glance:

  • These 2 teams naturally do not use the same vocabulary: payment vs. transaction. Is it really the same concept?

    For example, one possible view: it's time to renew the client's subscription. He has to pay: make a payment. For that, we trigger a bank transaction to debit his account. It fails. In 2 days, we will initiate another transaction. The 2 transactions generated bank fees. In this example, one payment is composed of a set of transactions.

    We will refine to have a consistent system and establish a ubiquitous language: common to everyone.
  • The marketing team seems not interested in refunds, frauds, etc. They only look at sales.
  • The notion of marketing payment contains only a date and an amount. Finance, needs the VAT, the name of the partner used, etc.

This modeling can take a lot of time. Generally, a business team that has been using a vocabulary for years doesn't care to deepen it and correct it if it turns out to be wrong or full of language abuses. For them, it's a waste of time that brings nothing to their daily life. Not always easy to organize sessions, explain to them that they are perverting concepts, and agree so that everyone speaks the same language. In theory, the software should adapt to the business. In practice, if the business is too inconsistent, devs can push a bit to ensure the system's reliability.

My favorite example: product vs. offer. I think I face it at least twice a year 👌.

Once all these questions are answered, we can identify the entities involved, their relationships, and the possible actions. In my example, for finance:

  • I have a client.
  • This client can make payments and get refunds through bank transactions.
  • These transactions have a nominal amount: numerical amount + currency.
  • I have several banking partners.
  • Each partner has a contract.
  • In this contract, there are fees calculated according to rules: 0.01€ for 100 transactions…

To represent all this in the code, we create dedicated types. Thus, we have a Client type, Partner, Transaction, Fee, Contract, Amount, etc.

To create a type, we must describe it. This description, called "a class", will then allow us to build concrete instances: objects.

Imagine an architect who draws a plan for a house. From this plan, he can build an entire neighborhood of almost identical houses.

Languages differ a bit on this part. In most, we will have something like:

Definition of the Client class (the house plan), then construction of robert (the house) using the “new” keyword. A client consists of an array of transactions and their email.
class Client {
    // Declaration of the attribute "email" as a "string".
    email: string

    /*
    * Declaration of the attribute "renewalHistory"
    * which is an empty array of "Transaction" objects.
    */
    renewalHistory: Transaction[] = []

    /*
    * Declaration of the function "requestRefund".
    * It takes an input parameter "transactionToRefund" of type "Transaction".
    * It returns nothing: void.
    */
    requestRefund(transactionToRefund: Transaction): void {
    // Processing to refund.
    }
}

// Creation of the object "robert", which is a "Client".
robert = new Client('robert@gmail.com')

// Creation of a transaction
renewalSubscription = new Transaction(10, '€', '2024-02-04')

robert.requestRefund(renewalSubscription)

This is demonstration code, it does not work as is 😛.
The slashes "//" and stars "/*" are used to comment the code in most languages. Even if in theory, the code should be clear and explicit enough to be read by anyone, in practice comments save many situations.

We see in the example that a client has one possible action: requestRefund. We call the declaration of this action “function” and, more specifically in the context of an object: “method”. I have no idea why we use two different words 🤷🏻‍♂️.

Robert is a client the same way 42 is a number and “toto” is a string.
Moreover, in some languages, primitive types are also represented as objects.
On the string type, you can do things like “toto”.length to directly know the length of a text.


That's all for today 🖖.
In the next edition, we'll talk about conditions and loops. Don't worry, these logics are now taught to children from a young age.


Did you enjoy this content? Then so will your friends!
Don't forget to share the subscription link.


Questions, comments, encouragement? Don't hesitate to send me a message on Linkedin or directly in the comments of this edition.

See you soon.

😘