<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>wigum::website - Computer Sciences</title>
    <subtitle>William Guimont-Martin’s research in robotics, AI, and 3D perception, alongside software projects, technical articles, papers, and creative writing.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://willguimont.com/tags/computer-sciences/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://willguimont.com/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-15T00:00:00+00:00</updated>
    <id>https://willguimont.com/tags/computer-sciences/atom.xml</id>
    <entry xml:lang="en">
        <title>Recovering Windows After Wiping GRUB for Limine</title>
        <published>2026-05-15T00:00:00+00:00</published>
        <updated>2026-05-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/omarchy-windows/"/>
        <id>https://willguimont.com/blog/omarchy-windows/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/omarchy-windows/">&lt;p&gt;I had a working dual-boot setup: Manjaro on one SSD for work, Windows on another for leisure, with GRUB acting as the selector between them.
GRUB would chainload Windows at boot.
Everything worked fine – until I decided to replace Manjaro with &lt;a rel=&quot;external&quot; href=&quot;https://omarchy.org&quot;&gt;Omarchy&lt;/a&gt;, which uses the Limine bootloader instead of GRUB.&lt;/p&gt;
&lt;p&gt;I wiped the Manjaro SSD, installed Omarchy, and promptly lost access to Windows.&lt;/p&gt;
&lt;p&gt;Here’s what happened and how I fixed it.&lt;/p&gt;
&lt;h2 id=&quot;what-actually-broke&quot;&gt;What Actually Broke&lt;/h2&gt;
&lt;p&gt;The setup had a hidden dependency: my UEFI firmware was booting GRUB, and GRUB was chainloading Windows.
When I wiped Manjaro, GRUB disappeared – and with it, the only thing pointing at Windows.&lt;/p&gt;
&lt;p&gt;Windows itself was completely untouched.
The NTFS partitions on the Windows SSD were fine.
But the EFI System Partition (ESP), the FAT32 partition that holds bootloaders, was on my NVMe drive alongside Omarchy, and the Windows EFI files (&lt;code&gt;\EFI\Microsoft\Boot\&lt;/code&gt;) were simply gone.&lt;/p&gt;
&lt;h2 id=&quot;disk-layout&quot;&gt;Disk Layout&lt;/h2&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sdb (931 GB)          ← Windows SSD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├─ sdb1  16 MB        Microsoft Reserved Partition&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├─ sdb2  930 GB NTFS  Windows C: drive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└─ sdb3  817 MB NTFS  Windows Recovery&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nvme0n1 (1.8 TB)      ← Omarchy NVMe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├─ nvme0n1p1  2 GB vfat   ← ESP, mounted at /boot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└─ nvme0n1p2  1.8 TB LUKS → btrfs root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No EFI partition on the Windows SSD at all.
The ESP was shared on the NVMe, and Manjaro’s wipe had taken the Windows EFI files with it.&lt;/p&gt;
&lt;h2 id=&quot;step-1-configure-limine&quot;&gt;Step 1: Configure Limine&lt;/h2&gt;
&lt;p&gt;Omarchy uses Limine, so the first task was adding a Windows entry to &lt;code&gt;/boot/limine.conf&lt;/code&gt;.
The key lesson here: &lt;strong&gt;match the path syntax of your working entries&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/Windows&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    protocol: efi_chainload&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    path: boot():/EFI/Microsoft/Boot/bootmgfw.efi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;step-2-copy-the-efi-files-from-the-windows-partition&quot;&gt;Step 2: Copy the EFI Files from the Windows Partition&lt;/h2&gt;
&lt;p&gt;The Windows bootloader (&lt;code&gt;bootmgfw.efi&lt;/code&gt;) wasn’t on the ESP, but it &lt;em&gt;was&lt;/em&gt; still sitting on the Windows partition itself, under &lt;code&gt;Windows/Boot/EFI/&lt;/code&gt;.
So I mounted the Windows SSD and copied it over:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; mkdir&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /boot/EFI/Microsoft/Boot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; cp&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /mnt/Windows/Boot/&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /boot/EFI/Microsoft/Boot/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allowed me to finally boot Windows from Limine, it could now find and launch &lt;code&gt;bootmgfw.efi&lt;/code&gt;.
But Windows then hit a different wall:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Recovery&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The Boot Configuration Data for your PC is missing or contains errors.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;File: \EFI\Microsoft\Boot\BCD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error code: 0xc000000f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;step-3-rebuild-the-bcd-with-bcdboot&quot;&gt;Step 3: Rebuild the BCD with bcdboot&lt;/h2&gt;
&lt;p&gt;The BCD (Boot Configuration Data) is a binary database that tells the Windows bootloader where the OS actually lives.
It’s not part of the &lt;code&gt;Windows/Boot/&lt;/code&gt; folder – it gets generated by a Windows tool called &lt;code&gt;bcdboot&lt;/code&gt;.
You can’t create it from Linux.&lt;/p&gt;
&lt;p&gt;This required a Windows installation USB.
After booting it and hitting &lt;strong&gt;Shift+F10&lt;/strong&gt; to open a command prompt, the fix was:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;bat&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;diskpart&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;select disk &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;          :: NVMe &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1863 GB&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;select partition &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;     :: the &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2048&lt;/span&gt;&lt;span&gt; MB ESP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;assign letter=S&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;select disk &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;0&lt;/span&gt;&lt;span&gt;          :: Windows SSD &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;931 GB&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;select partition &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;     :: the &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;930&lt;/span&gt;&lt;span&gt; GB primary partition&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;assign letter=C&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;bcdboot&lt;/span&gt;&lt;span&gt; C:\Windows /s S: /f UEFI&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;bcdboot&lt;/code&gt; regenerated the BCD store on the ESP, pointing it at the Windows installation on the other SSD.
One reboot later, Limine showed the Windows entry and it booted cleanly.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SilvaScenes</title>
        <published>2025-10-13T00:00:00+00:00</published>
        <updated>2025-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/silvascenes/"/>
        <id>https://willguimont.com/blog/silvascenes/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/silvascenes/">&lt;p&gt;Co-authored paper: &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/2510.09458&quot; target=&quot;_blank&quot;&gt;SilvaScenes: Tree Segmentation and Species Classification from Under-Canopy Images in Natural Forests&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interest in robotics for forest management is growing, but perception in complex, natural environments remains a significant hurdle. Conditions such as heavy occlusion, variable lighting, and dense vegetation pose challenges to automated systems, which are essential for precision forestry, biodiversity monitoring, and the automation of forestry equipment. These tasks rely on advanced perceptual capabilities, such as detection and fine-grained species classification of individual trees. Yet, existing datasets are inadequate to develop such perception systems, as they often focus on urban settings or a limited number of species. To address this, we present SilvaScenes, a new dataset for instance segmentation of tree species from under-canopy images. Collected across five bioclimatic domains in Quebec, Canada, SilvaScenes features 1476 trees from 24 species with annotations from forestry experts. We demonstrate the relevance and challenging nature of our dataset by benchmarking modern deep learning approaches for instance segmentation. Our results show that, while tree segmentation is easy, with a top mean average precision (mAP) of 67.65%, species classification remains a significant challenge with an mAP of only 35.69%. Our dataset and source code will be available at &lt;a rel=&quot;external&quot; href=&quot;https://github.com/norlab-ulaval/SilvaScenes&quot;&gt;this https URL&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Docker Workshop</title>
        <published>2025-09-07T00:00:00+00:00</published>
        <updated>2025-09-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/docker-workshop/"/>
        <id>https://willguimont.com/blog/docker-workshop/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/docker-workshop/">&lt;p&gt;Docker and containerization have revolutionized the way applications are developed, deployed, and managed.
Containers provide a lightweight and efficient way to package applications and their dependencies, ensuring consistency across different environments.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;p&gt;The original workshop was designed to use with a virtual machine (&lt;a rel=&quot;external&quot; href=&quot;https://github.com/willGuimont/IFT2001-Docker&quot;&gt;willGuimont/IFT2001-Docker&lt;/a&gt;).
While you can follow the instructions below to set up the virtual machine, you can also choose to follow the workshop using Docker.&lt;/p&gt;
&lt;p&gt;Follow these steps to prepare your environment.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https://docs.docker.com/engine/install/ubuntu/&quot;&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run -it --rm ubuntu:latest bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the Docker container, run:
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt install -y git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir .atelier &amp;amp;&amp;amp; cd .atelier &amp;amp;&amp;amp; git clone https://github.com/willGuimont/IFT2001-Docker ateliers-iftglo-2001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd ateliers-iftglo-2001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./helper/install.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python3 ./helper/prepare_bashrc.py &amp;amp;&amp;amp; source ~/.bashrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy the files in your home directory: &lt;code&gt;cd ~/.atelier/ateliers-iftglo-2001/files &amp;amp;&amp;amp; cp -r . ~/&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;instructions&quot;&gt;Instructions&lt;/h3&gt;
&lt;p&gt;The instruction above sets up your environment for the workshop.
The grading commands are of the form &lt;code&gt;correction_nn&lt;/code&gt;, where &lt;code&gt;nn&lt;/code&gt; is an integer representing the exercise number, for example &lt;code&gt;correction_03&lt;/code&gt; for exercise 3.
Instructions for validating commands will be provided with the first question that has an expected result.&lt;/p&gt;
&lt;p&gt;To complete this workshop, you must perform each exercise directly in the terminal.
You will use the &lt;code&gt;nano&lt;/code&gt; text editor to modify the requested scripts.
To open a file with nano, run the following in the terminal.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nano&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; test.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then edit the file; enter&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello world&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To exit nano, press &lt;kbd&gt;CTRL&lt;/kbd&gt;-&lt;kbd&gt;X&lt;/kbd&gt;, then answer &lt;code&gt;y&lt;/code&gt; to save the changes.
Run the following commands to validate that everything works:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chmod&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; test.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;./test.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These commands should print &lt;code&gt;Hello world&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;&lt;strong&gt;Adventurers only&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are comfortable with the command line, we encourage you to try completing this workshop using &lt;code&gt;vim&lt;/code&gt; as your text editor.
A brief introduction to &lt;code&gt;vim&lt;/code&gt; commands is available on &lt;a rel=&quot;external&quot; href=&quot;https://missing.csail.mit.edu/2020/editors/&quot;&gt;MIT’s The Missing Semester&lt;/a&gt;.
&lt;code&gt;vim&lt;/code&gt; offers many shortcuts to edit text and code very efficiently.
As a programmer, you will spend a lot of time writing code, so investing in learning &lt;code&gt;vim&lt;/code&gt; is worthwhile for the rest of your career.
There are plugins emulating &lt;code&gt;vim&lt;/code&gt; commands for most IDEs: &lt;a rel=&quot;external&quot; href=&quot;https://marketplace.visualstudio.com/items?itemName=vscodevim.vim&quot;&gt;Vim for VS Code&lt;/a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https://plugins.jetbrains.com/plugin/164-ideavim&quot;&gt;IdeaVim for JetBrains products&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please note that no assistance regarding &lt;code&gt;vim&lt;/code&gt; will be provided during this workshop.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;solutions&quot;&gt;Solutions&lt;/h3&gt;
&lt;p&gt;Proposed solutions to the exercises in these workshops are available in the following GitHub repository: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/ulavalIFTGLOateliers/IFT2001-Docker&quot;&gt;ulavalIFTGLOateliers/IFT2001-Docker&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;docker&quot;&gt;Docker&lt;/h2&gt;
&lt;p&gt;After your success with &lt;a href=&quot;https://willguimont.com/blog/bash-workshop/&quot;&gt;Bash&lt;/a&gt;, your manager has given you a new mission: find a solution to the application deployment problem.
Your company frequently encounters outages due to incompatibilities between different dependency versions.
Indeed, each developer can choose the operating system they wish to work on.
Consequently, some developers use different Linux distributions (Ubuntu, Arch, Gentoo), while others prefer Windows.&lt;/p&gt;
&lt;p&gt;This situation often leads to version issues, as dependencies vary from one OS to another.
And worse, the versions used differ from those deployed on the production server.
The recurring excuse “It worked on my machine” when a developer causes a production outage has finally exasperated your manager. He is asking you to find a solution.&lt;/p&gt;
&lt;p&gt;That’s how you discover Docker, a platform that lets you build, deploy, and run applications in lightweight, isolated containers.
With Docker, you can create a specific container for each microservice, including all required libraries and dependencies.
This approach ensures that each application will run consistently, regardless of library versions used by individual developers.
Moreover, Docker allows you to reproduce the development environment on the production server, thereby eliminating issues stemming from environment differences.&lt;/p&gt;
&lt;p&gt;With Docker, you will tackle the challenge of running your company’s three main microservices.
Here are the microservices you must get working:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a web server health monitoring application written in Haskell;&lt;/li&gt;
&lt;li&gt;a document management API written in Rust, requiring a PostgreSQL database; and&lt;/li&gt;
&lt;li&gt;a Python application for visualizing web server health.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;wide-crt&quot;&gt;
&lt;div class=&quot;crt scanlines&quot; aria-hidden=&quot;true&quot;&gt;
	&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;┌────────────────────────────── MICROSERVICES (ARCH OVERVIEW) ───────────────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  (3) python_app (CLI)                                                                  │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Image: python_app                                                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Mode: --network=host (workshop)                                                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      BACKEND_URL = http://localhost:8080                                               │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Uses: list/add endpoints, view uptime stats                                       │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │ HTTP (JSON)                                                               │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            ▼                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  (1) status-checker (Haskell)                                                          │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Image: status-checker                                                             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Port: 8080                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Storage: monitoring.sqlite (SQLite)                                               │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │ HTTP health probe (/documents or /health)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            ▼                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  (2) rust_api (Actix Web)                                                              │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Image: rust_api (multi-stage)                                                     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Port: 8081                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Env: DATABASE_URL=postgres://postgres:postgres@db                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            │ SQL (Diesel)                                                              │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│            ▼                                                                           │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      PostgreSQL                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Image: postgres                                                                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Port: 5432                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│      Volume: db:/var/lib/postgresql/data                                               │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  Data Flows (top→down):                                                                │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│    python_app ──HTTP──▶ status-checker ──HTTP──▶ rust_api ──SQL──▶ PostgreSQL          │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  Summary:                                                                              │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│    - python_app only contacts status-checker.                                          │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│    - status-checker pings rust_api for availability.                                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│    - rust_api persists documents in Postgres.                                          │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│  Ports: 8080 (status-checker) | 8081 (rust_api) | 5432 (Postgres)                      │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└────────────────────────────────────────────────────────────────────────────────────────┘&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;why-containerization&quot;&gt;Why containerization?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Isolation&lt;/strong&gt;&lt;br /&gt;
One of the main advantages of containerization is isolation.
It often happens that different applications require specific dependency versions.
With Docker, you can install different dependency versions in distinct containers, without risking conflicts or compromising other applications.
Furthermore, if you need to run applications on different operating systems, such as Ubuntu and Arch Linux, you can simply wrap them in Docker containers, avoiding the need to rewrite applications for each system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Portability&lt;/strong&gt;&lt;br /&gt;
Portability is another key advantage of Docker.
Once you have set up a development environment with all required dependencies, reproducing that configuration on other machines or for new team members becomes tedious.
Thanks to Docker, you can create an image that contains all required dependencies and configuration, which can be easily distributed and run on different platforms, whether Linux, Windows, or others.
This enables a new team member to start quickly without spending weeks configuring their environment.
It’s also an advantage when deploying applications to a server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reproducibility&lt;/strong&gt;&lt;br /&gt;
Reproducibility is also simplified with Docker.
Docker images are versioned, which means it is easy to reproduce builds identically, ensuring that development, test, and production environments are consistent.
You just need to specify the version of the Docker image used to guarantee consistency and avoid issues related to variations across environments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Efficiency&lt;/strong&gt;&lt;br /&gt;
In terms of efficiency, Docker offers a significant advantage over virtual machines (VMs).
Unlike VMs, Docker does not need to run a full operating system for each container, which greatly reduces resource consumption.
Docker containers share the host kernel, making them lightweight and quick to start.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Community&lt;/strong&gt;&lt;br /&gt;
Docker’s surrounding community is very active and offers a multitude of preconfigured images for various popular tools and technologies such as Node.js, Python, and many others.
These preconfigured images facilitate deployment and usage of these technologies, saving developers time by avoiding manual environment setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Industry&lt;/strong&gt;&lt;br /&gt;
Finally, it’s important to emphasize that Docker has become a de facto standard in the software development industry.
Many companies use Docker for development, testing, and deployment of their applications.
Docker is now an essential tool for software developers.&lt;/p&gt;
&lt;h3 id=&quot;what-is-containerization&quot;&gt;What is containerization?&lt;/h3&gt;
&lt;p&gt;Docker is an open-source software platform that lets you create, deploy, and run applications in lightweight, isolated containers.
A Docker container is a runtime unit that encapsulates an application together with all of its necessary elements, such as libraries, dependencies, and configuration files.
These containers are self-contained and portable, meaning they can run consistently across different systems, whether a development, test, or production environment.&lt;/p&gt;
&lt;p&gt;Docker is similar to a virtual machine that isolates an application from the host system.
However, Docker is much more efficient than a VM, which requires a full operating system for each instance.
Docker instead shares the host operating system’s &lt;code&gt;kernel&lt;/code&gt;, saving resources and making containers faster to start and run.&lt;/p&gt;
&lt;p&gt;Here is some Docker terminology.
You do not have to read the advanced sections to complete this workshop.
As a supplement, you can watch the video &lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=J0NuOlA2xDc&quot;&gt;“Never install locally”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker Image&lt;/strong&gt;&lt;br /&gt;
An image contains the filesystem and user-space components required by the application: binaries, libraries, dependencies, configuration files, and often a Linux distribution’s userland.
It does not contain its own Linux kernel.
Docker images are typically created from files called &lt;code&gt;Dockerfile&lt;/code&gt; that specify the steps to build the image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;br /&gt;
A Dockerfile is a text file that contains the instructions to build a Docker image.
It specifies the image layers, dependencies to install, files to include, and commands to run during image construction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker Container&lt;/strong&gt;&lt;br /&gt;
A Docker container is a running instance of a Docker image.
It is an isolated environment that runs the application with its dependencies.
Containers are lightweight, portable, and self-contained, which makes them easy to deploy across different machines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker Registry&lt;/strong&gt;&lt;br /&gt;
A Docker registry is a centralized repository that stores and manages Docker images.
The default public registry is &lt;a rel=&quot;external&quot; href=&quot;https://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt;, where you can find many ready-to-use images.
You can also create and use your own private registry to store your own images.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Union filesystem (advanced concepts)&lt;/strong&gt;&lt;br /&gt;
The &lt;em&gt;Union Filesystem&lt;/em&gt;, also known as &lt;em&gt;UnionFS&lt;/em&gt; or &lt;em&gt;OverlayFS&lt;/em&gt;, is a technology used by Docker to manage images and container layers efficiently.
The &lt;em&gt;Union Filesystem&lt;/em&gt; allows you to overlay multiple file systems into a single logical view without physically merging them.
This means Docker images and containers can share and reuse common file layers, saving storage space.
It also speeds up image builds by caching layers already built.
When a container starts, a new read-write layer is added on top of the image layers, enabling container-specific changes without affecting others.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;cgroups (advanced concepts)&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;cgroups&lt;/code&gt;, or &lt;em&gt;control groups&lt;/em&gt;, are a Linux kernel feature used by Docker to limit and manage system resources used by containers.
&lt;code&gt;cgroups&lt;/code&gt; allow control of resources such as CPU, memory, disk bandwidth, and network, ensuring balanced and fair resource usage among containers.
Docker uses &lt;code&gt;cgroups&lt;/code&gt; to set limits and quotas on resources allocated to each container, ensuring isolation and predictable performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Namespaces (advanced concepts)&lt;/strong&gt;&lt;br /&gt;
Namespaces are a Linux kernel feature that isolates system resources among processes.
Docker uses several types of namespaces to provide isolation between containers, including the PID namespace (process isolation), the network namespace (network isolation), the user namespace (user isolation), and the mount namespace (mount point isolation).
These namespaces ensure that each container has its own isolated view of the system, preventing processes in one container from interfering with others or with the host system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Chroot jail (advanced concepts)&lt;/strong&gt;&lt;br /&gt;
Chroot, or change root, is a Unix/Linux feature that changes a process’s root directory and limits its access to the file system.
Docker uses chroot to create an isolated environment inside the container, where the container’s root directory becomes the starting point for all file paths.
This limits the container’s access to files and directories outside its isolated environment, thereby strengthening security and isolation.&lt;/p&gt;
&lt;h2 id=&quot;containers-manually&quot;&gt;Containers manually&lt;/h2&gt;
&lt;p&gt;To clearly illustrate what Docker does, we will manually build a simplified container without using Docker.
This section is inspired by &lt;a rel=&quot;external&quot; href=&quot;https://github.com/p8952/bocker&quot;&gt;p8952/bocker: Docker implemented in around 100 lines of bash&lt;/a&gt;.
In a terminal, enter the following commands:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Verify that neofetch is not installed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The following command should raise an error; do not install the package&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;neofetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Folder for containers&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/containers&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/containers&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Build the container&amp;#39;s filesystem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; apt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; update&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; apt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; debootstrap&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; debootstrap&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; jammy&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; http://archive.ubuntu.com/ubuntu/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Create an isolated environment (namespace)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; unshare&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-uts&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-pid&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-mount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-ipc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-fork&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Mount process, system, device, and temp folders&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; proc&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; none&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/proc/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; sysfs&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; none&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/sys&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bind&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bind&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /tmp&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/tmp/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /etc/apt/sources.list&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/etc/apt/sources.list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Use chroot to launch a shell in the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chroot&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./ubuntu-container/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; and there you go, you&amp;#39;re in an isolated container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Install neofetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;apt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;apt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; neofetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Test neofetch; the command works!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;neofetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; You can run commands in the container here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Exit the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Exit unshare&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; If we try neofetch again, the command is not found.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We have indeed isolated the container!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;neofetch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, there is no magic in containers.
There is no magic in a container: at its core, Linux provides mechanisms such as namespaces, filesystem isolation, and cgroups.
Docker packages these mechanisms behind a convenient image, networking, storage, and lifecycle-management interface.&lt;/p&gt;
&lt;h2 id=&quot;docker-basics&quot;&gt;Docker basics&lt;/h2&gt;
&lt;h3 id=&quot;exercise-01-running-a-prebuilt-image&quot;&gt;Exercise 01 – Running a prebuilt image&lt;/h3&gt;
&lt;p&gt;Run the Docker image &lt;code&gt;hello-world&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To run a Docker image, use the &lt;code&gt;run&lt;/code&gt; command.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; image-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the command works, you will see a message displayed.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; hello-world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To execute a command in the container, specify the command at the end of &lt;code&gt;run&lt;/code&gt;.
In the following examples, we pass &lt;code&gt;bash -c &#39;echo &quot;Hello world&quot;&#39;&lt;/code&gt; which interprets the string in the Bash interpreter.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Prints &amp;#39;Hello world&amp;#39; in an ubuntu container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ubuntu&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;echo &amp;quot;Hello world&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Prints information about the host system&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /etc/os-release&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Prints information from a container running Arch Linux&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; archlinux&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cat /etc/os-release&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To launch an interactive command (such as a shell), use the &lt;code&gt;-it&lt;/code&gt; flag.
The &lt;code&gt;--rm&lt;/code&gt; flag removes the container once it exits.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; archlinux&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;exercise-02-container-management&quot;&gt;Exercise 02 – Container management&lt;/h3&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To see running containers: &lt;code&gt;docker ps&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To stop a container: &lt;code&gt;docker stop container_id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note that the command may take some time to run.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tasks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Launch an interactive terminal with Docker;&lt;/li&gt;
&lt;li&gt;Open another terminal and inspect running containers;&lt;/li&gt;
&lt;li&gt;Stop the Docker container from the second terminal.&lt;/li&gt;
&lt;/ol&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; In the first terminal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; archlinux&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; In the second terminal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ps&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; stop&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-03-inspecting-a-running-container&quot;&gt;Exercise 03 – Inspecting a running container&lt;/h3&gt;
&lt;p&gt;Containers often run in the background.
Docker provides several commands to inspect and interact with running containers.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To display the output produced by a container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; logs&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; container_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To execute a command inside a running container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; exec&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; container_name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; command&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, to open an interactive shell:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; exec&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; container_name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, docker inspect displays detailed information about a Docker object, including its network configuration, mounted filesystems, environment variables, and process configuration:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; inspect&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; container_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Launch an nginx container in the background:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 8080:80&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tasks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify that the container is running.&lt;/li&gt;
&lt;li&gt;Display the container’s logs.&lt;/li&gt;
&lt;li&gt;Open an interactive shell inside the running container.&lt;/li&gt;
&lt;li&gt;From inside the container, inspect the files in /usr/share/nginx/html.&lt;/li&gt;
&lt;li&gt;Use docker inspect to find the container’s IP address.&lt;/li&gt;
&lt;li&gt;Stop and remove the container.&lt;/li&gt;
&lt;/ol&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Verify that the container is running&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ps&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Display its logs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; logs&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Execute Bash inside the existing container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; exec&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Inside the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /usr/share/nginx/html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Inspect the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; inspect&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Find the IP address&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; inspect&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-format&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;    web-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Stop and remove it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; stop&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;docker run&lt;/code&gt; creates a new container, whereas &lt;code&gt;docker exec&lt;/code&gt; executes another process inside an already running container.
This distinction is useful when debugging services running in the background.&lt;/p&gt;
&lt;/details&gt;
&lt;h3 id=&quot;exercise-04-postgresql-database&quot;&gt;Exercise 04 – PostgreSQL database&lt;/h3&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To set environment variables in a container, use the &lt;code&gt;-e&lt;/code&gt; flag.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HELLO=hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; archlinux&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; sh&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;echo $HELLO&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To open a network port, use the &lt;code&gt;-p host:docker&lt;/code&gt; flag, where &lt;code&gt;host&lt;/code&gt; is the port number on the host and &lt;code&gt;docker&lt;/code&gt; is the port number inside the container.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 127.0.0.1:8080:80&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; nginx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; You can access the port via the URL http://localhost:8080/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; http://localhost:8080/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Launch a PostgreSQL database with Docker.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Image name: &lt;code&gt;postgres&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set the environment variable &lt;code&gt;POSTGRES_PASSWORD=postgres&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Map Docker port 5432 to host port 5432&lt;/li&gt;
&lt;li&gt;Leave this container running.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; POSTGRES_PASSWORD=postgres&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5432:5432&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; POSTGRES_PASSWORD=postgres&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5432:5432&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h2 id=&quot;dockerfile&quot;&gt;Dockerfile&lt;/h2&gt;
&lt;p&gt;Dockerfiles are configuration files used to create custom Docker images.
They allow you to define, reproducibly and automatically, an application’s runtime environment inside a Docker container.&lt;/p&gt;
&lt;p&gt;A Dockerfile contains a series of instructions that specify the steps needed to build a Docker image.
These instructions include actions such as selecting the base image, installing dependencies, configuring environment variables, copying files, running commands, and more.&lt;/p&gt;
&lt;p&gt;Here is an annotated example Dockerfile for a Python application.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Use the Python 3.9 slim base image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; python:3.9-slim&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Set the working directory inside the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Specifies the directory for RUN, CMD, ENTRYPOINT, COPY, and ADD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Copy requirements.txt from the host into the Docker container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; requirements.txt .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Run a Bash command to install Python dependencies&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Copy the source code into the Docker container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Set the default command when the container starts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;app.py&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To build the image, use &lt;code&gt;docker build -t &amp;lt;tag&amp;gt; .&lt;/code&gt;.
The &lt;code&gt;-t &amp;lt;tag&amp;gt;&lt;/code&gt; argument gives the image the name &lt;code&gt;&amp;lt;tag&amp;gt;&lt;/code&gt;.
For the previous application, you could use &lt;code&gt;docker build -t python-app .&lt;/code&gt;.
Note that the order of instructions matters.&lt;/p&gt;
&lt;p&gt;It is crucial to define the order of operations in a Dockerfile due to how Docker builds images.
Each instruction in the Dockerfile creates a new layer in the Docker image, and the order can significantly impact build efficiency and performance.&lt;/p&gt;
&lt;p&gt;Docker uses a cache to speed up image builds.
When you run an instruction, Docker checks whether that instruction has already been executed in a previous layer.
If so and the parameters are identical, Docker reuses the cached layer instead of rebuilding it.
This saves build time.
However, if you modify an instruction higher up in the Dockerfile, all subsequent instructions will have their cache invalidated and must be rebuilt.
&lt;strong&gt;For example, if you perform resource-intensive operations such as compiling code that changes whenever you modify the source, it can be preferable to place those steps towards the end of the Dockerfile to benefit from caching as much as possible.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;exercise-05-haskell-service-dockerfile&quot;&gt;Exercise 05 – Haskell service Dockerfile&lt;/h3&gt;
&lt;p&gt;Use the &lt;code&gt;README.md&lt;/code&gt; in the folder &lt;code&gt;~/Applications/status-checker&lt;/code&gt; to write a Dockerfile that runs the Haskell application.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Base image &lt;code&gt;haskell:9.0-buster&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;stack setup --install-ghc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Workdir &lt;code&gt;/app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy the source code into &lt;code&gt;/app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;stack build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Launch the server with &lt;code&gt;stack run&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, start the container exposing port 8080.
If everything works, you should be able to run:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; http://localhost:8080/endpoints&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Expected response&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Leave this container running.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;p&gt;Dockerfile:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; haskell:9.0-buster&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; stack setup --install-ghc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; stack build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Execution:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; status-checker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 8080:8080&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; status-checker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-06-python-application-dockerfile&quot;&gt;Exercise 06 – Python application Dockerfile&lt;/h3&gt;
&lt;p&gt;Use the &lt;code&gt;README.md&lt;/code&gt; in the folder &lt;code&gt;~/Applications/python_app&lt;/code&gt; to write a Dockerfile that runs the Python application.&lt;/p&gt;
&lt;p&gt;Then, launch the application interactively and with the correct network mode.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;This application will need to access your computer’s local network to make requests to the container from the previous exercise; to keep this exercise simple, use &lt;code&gt;--network=&quot;host&quot;&lt;/code&gt; when running the container.&lt;/p&gt;
&lt;p&gt;Host networking makes the container share the host’s network stack.
This is convenient here, but it reduces network isolation and is not the usual way for containers to communicate with each other.
Later, Docker Compose will place the containers on a shared Docker network, where services can communicate directly using their service names.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If everything works, you should be able to use the application to add URLs to monitor and see the results.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;p&gt;Dockerfile:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; python:3.9-slim&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; requirements.txt .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;main.py&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Execution:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; python_app&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-network=host&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; python_app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h2 id=&quot;advanced-docker&quot;&gt;Advanced Docker&lt;/h2&gt;
&lt;p&gt;Sometimes, you may need to create more complex Docker images.
Here, we will explore two advanced Docker features: multi-stage builds and volumes.&lt;/p&gt;
&lt;h3 id=&quot;multi-stage-image-builds&quot;&gt;Multi-stage image builds&lt;/h3&gt;
&lt;p&gt;Multi-stage builds are an advanced Docker feature that enables optimized image creation using several distinct stages in the build process.
This separates build and production stages, often resulting in final images that are lighter and more secure by minimizing what remains in the final image.&lt;/p&gt;
&lt;p&gt;For example, for a JavaScript React application, we can split the build into two stages.&lt;/p&gt;
&lt;p&gt;Create the application:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;npx&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; create-react-app&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; my-app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dockerfile:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Stage 1: Build the application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Use `as build` to name this build stage&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; node:14-alpine &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;as&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; package*.json ./&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; npm install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; npm run build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Stage 2: Prepare the server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Here, we start a new image from scratch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; nginx:alpine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Copy the compiled app from the previous stage&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; --from=build /app/build /usr/share/nginx/html&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;EXPOSE&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;nginx&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;-g&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;daemon off;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To run:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-app&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 80:80&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; web-app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;exercise-07-rust-multi-stage-build&quot;&gt;Exercise 07 – Rust multi-stage build&lt;/h3&gt;
&lt;p&gt;Use the &lt;code&gt;README.md&lt;/code&gt; in the folder &lt;code&gt;~/Applications/rust_api&lt;/code&gt; to write a Dockerfile that runs the application.&lt;/p&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launch the PostgreSQL database from a previous exercise;&lt;/li&gt;
&lt;li&gt;Create a first stage to compile the Rust code;&lt;/li&gt;
&lt;li&gt;Create a second stage to run the code;
&lt;ul&gt;
&lt;li&gt;Start this image from &lt;code&gt;debian:bullseye-slim&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Install the package &lt;code&gt;libpq-dev&lt;/code&gt; with &lt;code&gt;apt update; apt install -y libpq-dev&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Set the environment variable &lt;code&gt;DATABASE_URL=postgres://postgres:postgres@localhost&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;/app/target/release/rust_api&lt;/code&gt; from the previous stage;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Run the container with &lt;code&gt;--network=host&lt;/code&gt; and expose the correct port;&lt;/li&gt;
&lt;li&gt;Test that everything works with &lt;code&gt;curl http://localhost:8081/documents&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; rust:latest &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;AS&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; cargo build --release&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; debian:bullseye-slim&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; apt update; apt install -y libpq-dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; --from=build /app/target/release/rust_api ./rust_api&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;ENV&lt;/span&gt;&lt;span&gt; DATABASE_URL=postgres://postgres:postgres@db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; ./rust_api&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Execution&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; POSTGRES_PASSWORD=postgres&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5432:5432&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rust_api&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-network=host&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rust_api&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Validate that the server works&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; http://localhost:8081/documents&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;volumes-and-bind-mounts&quot;&gt;Volumes and bind mounts&lt;/h3&gt;
&lt;p&gt;Containers have a writable filesystem, but this filesystem belongs to the container.
If the container is removed, the data written inside it is also removed.
Docker provides mounts to store data outside the container’s filesystem.&lt;/p&gt;
&lt;p&gt;There are two common types of mounts: &lt;strong&gt;volumes&lt;/strong&gt; and &lt;strong&gt;bind mounts&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;volume&lt;/strong&gt; is storage managed by Docker. You give the volume a name, and Docker decides where the data is stored on the host:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; database-data:/var/lib/postgresql/data&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, &lt;code&gt;database-data&lt;/code&gt; is a Docker volume and &lt;code&gt;/var/lib/postgresql/data&lt;/code&gt; is the directory where PostgreSQL sees it inside the container.
The data remains available even if the container is removed.
Volumes are therefore particularly useful for persistent application data such as databases.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;bind mount&lt;/strong&gt; directly maps an existing file or directory from the host filesystem into the container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ./src:/app/src&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; my-app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, &lt;code&gt;./src&lt;/code&gt; is a directory on the host and &lt;code&gt;/app/src&lt;/code&gt; is where it appears inside the container.
Changes made on either side are immediately visible on the other side.&lt;/p&gt;
&lt;p&gt;Volumes are generally appropriate for persistent application data.
Bind mounts are useful when the container must directly access files from the host, for example source code, configuration files, or datasets.&lt;/p&gt;
&lt;p&gt;For example, we can persist PostgreSQL data using a named volume:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; POSTGRES_PASSWORD=postgres&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5432:5432&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; postgres-data:/var/lib/postgresql/data&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;    postgres&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Docker creates and manages &lt;code&gt;postgres-data&lt;/code&gt;.
Removing the container does not remove the volume.&lt;/p&gt;
&lt;p&gt;During development, we can instead use a bind mount to expose the Python application’s source code directly inside the container.
This avoids rebuilding the image whenever the source code changes.&lt;/p&gt;
&lt;p&gt;A DockerfileDev can therefore omit the source code:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; python:3.9-slim&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;WORKDIR&lt;/span&gt;&lt;span&gt; /app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; requirements.txt .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We removed the line COPY . .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;CMD&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;bash&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Build and run it with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; python_app&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; DockerfileDev&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; run&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .:/app&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; python_app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; In the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; main.py&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Modify the source code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; main.py&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Changes are reflected in the container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thus, you can reuse the same image even if the source code has changed.&lt;/p&gt;
&lt;h2 id=&quot;extras&quot;&gt;Extras&lt;/h2&gt;
&lt;p&gt;Some additional Docker features and tools that may be useful in your projects.&lt;/p&gt;
&lt;h3 id=&quot;cleanup&quot;&gt;Cleanup&lt;/h3&gt;
&lt;p&gt;When using Docker, it is important to consider the storage used by images, containers, volumes, and other Docker artifacts.
Poor storage management can lead to excessive disk usage and make Docker maintenance and resource management difficult.
Docker provides several &lt;code&gt;prune&lt;/code&gt; commands to remove unused containers and images.
To clean up various Docker artifacts, the command &lt;code&gt;docker system prune -a -f&lt;/code&gt; removes all unused resources.&lt;/p&gt;
&lt;h3 id=&quot;docker-compose&quot;&gt;Docker Compose&lt;/h3&gt;
&lt;p&gt;Docker Compose is a tool that allows you to easily define and manage multi-container applications.
It simplifies deployment and orchestration of Docker containers using a simple, readable configuration file.&lt;/p&gt;
&lt;p&gt;With Docker Compose, you can specify services, networks, volumes, and other configurations needed to run an application composed of multiple containers.
You can also define dependencies among containers, environment variables, exposed ports, etc.&lt;/p&gt;
&lt;p&gt;Docker Compose uses a YAML configuration file to describe the application’s infrastructure.
This file contains sections such as &lt;em&gt;services&lt;/em&gt;, &lt;em&gt;networks&lt;/em&gt;, &lt;em&gt;volumes&lt;/em&gt;, etc., where you can define the different parts of your application and their configurations.&lt;/p&gt;
&lt;p&gt;Here is an example &lt;code&gt;docker-compose.yml&lt;/code&gt; for the Rust application that launches both the server and the PostgreSQL database:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; List of containers to launch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ervices&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Database container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We find many of the same parameters as with `docker run`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Image to launch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mage&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ostgres:18&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Restart the database if the container stops&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;estart&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;lways&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Environment variables passed to PostgreSQL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    e&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nvironment&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      P&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;OSTGRES_USER&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ostgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      P&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;OSTGRES_PASSWORD&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ostgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Store the database outside the container using a named volume&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    v&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;olumes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;b:/var/lib/postgresql/data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Test whether PostgreSQL is ready to accept connections&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Starting a container does not necessarily mean that the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; application inside it is ready yet.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    h&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ealthcheck&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;est&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;CMD-SHELL&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;pg_isready -U postgres&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nterval&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;imeout&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;etries&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;tart_period&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Rust server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  a&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pi&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Build the Dockerfile in the directory containing compose.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    b&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;uild&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Start the API only once the database healthcheck succeeds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;epends_on&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        c&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ondition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ervice_healthy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Map host port 8081 to container port 8081&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    p&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;orts&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;8081:8081&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Containers in the same Compose application share a network.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Services can reach each other using their service name.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Therefore, the database is available at hostname `db`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; rather than `localhost`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    e&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nvironment&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      D&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ATABASE_URL&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ostgres://postgres:postgres@db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Named volumes used by the application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;olumes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;river&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; l&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ocal&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; compose&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; up&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compose creates a default network for the application.
The &lt;code&gt;api&lt;/code&gt; container can therefore resolve &lt;code&gt;db&lt;/code&gt; as a hostname and connect directly to the PostgreSQL container.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;depends_on&lt;/code&gt; normally controls startup order only.
By combining it with the database healthcheck and condition: &lt;code&gt;service_healthy&lt;/code&gt;, Compose waits until PostgreSQL is actually ready to accept connections before starting the API.&lt;/p&gt;
&lt;h3 id=&quot;podman&quot;&gt;Podman&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://podman.io/&quot;&gt;Podman&lt;/a&gt; is an open-source alternative to Docker.
Docker and Podman are two popular containerization tools that share similar features but differ in architecture and security approach.
Docker uses a client-server architecture, where the Docker daemon runs as a separate process and Docker commands are executed via the CLI.
In contrast, Podman uses a daemonless architecture, meaning it runs directly as a regular user and does not require a separate daemon process.
Thus, Podman can run without special privileges, limiting potential risks associated with running as superuser. See &lt;a rel=&quot;external&quot; href=&quot;https://www.redhat.com/en/topics/containers/what-is-podman&quot;&gt;What is podman?&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;Podman also offers tools to manage &lt;em&gt;pods&lt;/em&gt;, a topic outside the scope of this workshop.&lt;/p&gt;
&lt;h3 id=&quot;kubernetes&quot;&gt;Kubernetes&lt;/h3&gt;
&lt;p&gt;Kubernetes is an open-source container orchestration system that facilitates the deployment, management, and scaling of containerized applications.
Using Kubernetes offers many benefits, such as fault tolerance, easier deployments, and management and scaling of containerized applications.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bash Workshop</title>
        <published>2025-09-06T00:00:00+00:00</published>
        <updated>2025-09-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/bash-workshop/"/>
        <id>https://willguimont.com/blog/bash-workshop/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/bash-workshop/">&lt;p&gt;Bash is a powerful command-line interpreter that allows users to interact with their operating system through text commands.
As a programmer, you will often need to use the command line to perform various tasks, such as navigating the file system, managing files and directories, and executing scripts.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;p&gt;The original workshop was designed to use with a virtual machine (&lt;a rel=&quot;external&quot; href=&quot;https://github.com/willGuimont/IFT2001-Scripting&quot;&gt;willGuimont/IFT2001-Scripting&lt;/a&gt;).
While you can follow the instructions below to set up the virtual machine, you can also choose to follow the workshop using Docker.&lt;/p&gt;
&lt;p&gt;Follow these steps to prepare your environment.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;external&quot; href=&quot;https://docs.docker.com/engine/install/ubuntu/&quot;&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run -it --rm ubuntu:latest bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the Docker container, run:
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt install -y git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir .atelier &amp;amp;&amp;amp; cd .atelier &amp;amp;&amp;amp; git clone https://github.com/willGuimont/IFT2001-Scripting ateliers-iftglo-2001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd ateliers-iftglo-2001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./helper/install.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python3 ./helper/prepare_bashrc.py &amp;amp;&amp;amp; source ~/.bashrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy the files in your home directory: &lt;code&gt;cd ~/.atelier/ateliers-iftglo-2001/files &amp;amp;&amp;amp; cp -r . ~/&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;instructions&quot;&gt;Instructions&lt;/h3&gt;
&lt;p&gt;The instruction above sets up your environment for the workshop.
The grading commands are of the form &lt;code&gt;correction_nn&lt;/code&gt;, where &lt;code&gt;nn&lt;/code&gt; is an integer representing the exercise number, for example &lt;code&gt;correction_03&lt;/code&gt; for exercise 3.
Instructions for validating commands will be provided with the first question that has an expected result.&lt;/p&gt;
&lt;p&gt;To complete this workshop, you must perform each exercise directly in the terminal.
You will use the &lt;code&gt;nano&lt;/code&gt; text editor to modify the requested scripts.
To open a file with nano, run the following in the terminal.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nano&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; test.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then edit the file; enter&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello world&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To exit nano, press &lt;kbd&gt;CTRL&lt;/kbd&gt;-&lt;kbd&gt;X&lt;/kbd&gt;, then answer &lt;code&gt;y&lt;/code&gt; to save the changes.
Run the following commands to validate that everything works:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chmod&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; test.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;./test.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These commands should print &lt;code&gt;Hello world&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;&lt;strong&gt;Adventurers only&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are comfortable with the command line, we encourage you to try completing this workshop using &lt;code&gt;vim&lt;/code&gt; as your text editor.
A brief introduction to &lt;code&gt;vim&lt;/code&gt; commands is available on &lt;a rel=&quot;external&quot; href=&quot;https://missing.csail.mit.edu/2020/editors/&quot;&gt;MIT’s The Missing Semester&lt;/a&gt;.
&lt;code&gt;vim&lt;/code&gt; offers many shortcuts to edit text and code very efficiently.
As a programmer, you will spend a lot of time writing code, so investing in learning &lt;code&gt;vim&lt;/code&gt; is worthwhile for the rest of your career.
There are plugins emulating &lt;code&gt;vim&lt;/code&gt; commands for most IDEs: &lt;a rel=&quot;external&quot; href=&quot;https://marketplace.visualstudio.com/items?itemName=vscodevim.vim&quot;&gt;Vim for VS Code&lt;/a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https://plugins.jetbrains.com/plugin/164-ideavim&quot;&gt;IdeaVim for JetBrains products&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please note that no assistance regarding &lt;code&gt;vim&lt;/code&gt; will be provided during this workshop.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;solutions&quot;&gt;Solutions&lt;/h3&gt;
&lt;p&gt;Proposed solutions to the exercises in these workshops are available in the following GitHub repository: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/ulavalIFTGLOateliers/IFT2001-Scripting&quot;&gt;ulavalIFTGLOateliers/IFT2001-Scripting&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;introduction-to-bash&quot;&gt;Introduction to Bash&lt;/h2&gt;
&lt;p&gt;It’s a day like any other at the office. You arrive early in the morning, coffee in hand and your laptop under your arm.
As you enter your department, you notice that your usually calm and relaxed boss is pacing nervously down the hallway. His pale expression and trembling hands immediately catch your attention.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Worrying — what’s going on?” you ask, concerned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“Production has crashed,” he replies in a trembling voice. “We’re getting hundreds of customer calls, nothing works anymore…”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Your heart races as you realize the magnitude of the problem. Your company depends on a server that hosts most of its services, and it seems something is malfunctioning. Your boss looks you straight in the eye.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Solving this problem is your priority,” he says firmly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He hands you a sheet of paper with the login credentials to access the server.
You feel both nervous and excited at the prospect of solving this critical issue.
Your boss then leads you to the server room, where an old CRT screen and a keyboard await you.
He explains that it’s a Linux server edition, so without a graphical interface.
You will therefore have to solve the problems using only the terminal.&lt;/p&gt;
&lt;div class=&quot;wide-crt&quot;&gt;
&lt;div class=&quot;crt scanlines&quot; aria-hidden=&quot;true&quot;&gt;
	&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;┌───────────────────────────── SYSTEM DIAGNOSTIC (BOOT/RESCUE) ──────────────────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ Host: crt-prod-01                User: username               TTY: /dev/pts/0          │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ Kernel: 5.15.x-generic           Uptime: 00:07:13             Load: 1.42 0.97 0.53     │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ -------------------------------------------------------------------------------------- │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ LOG SCAN: messages.txt                                                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   Errors (raw): ................. 37  (use: grep &amp;#39;Error&amp;#39; messages.txt)                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   Unique 4xx errors: ............ pending (pipe into uniq | sed ...)                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ NEXT STEPS (YOU):                                                                      │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [1] Locate build log directory         (Exercise 02)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [2] Back up critical log file          (Exercise 03)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [3] Fix permissions &amp;amp; run diagnostics  (Exercise 04)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [4] Corral *.out + purge temp files    (Exercises 05–07)                             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [5] Triage errors with grep/uniq/sed   (Exercises 09–12)                             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [6] Hunt largest files (du/find/sort)  (Exercise 13)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [7] Awk your way through db.tsv        (Exercise 14)                                 │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   [8] Script + rollback automation       (Exercises 15–16)                             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ -------------------------------------------------------------------------------------- │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ TIP: Build one-liners incrementally. Example pipeline scaffold:                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│        cat file | grep pattern | sort | head -n 5                                      │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ REMEMBER:                                                                              │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│   man &amp;lt;cmd&amp;gt;    --help flags    help &amp;lt;builtin&amp;gt;    set -x (debug scripts)                │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│                                                                                        │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;│ STATUS LAMPS:  [CPU OK] [DISK OK] [NET OK] [SERVICE ERROR] -&amp;gt; Investigate app layer    │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└────────────────────────────────────────────────────────────────────────────────────────┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(enter the command line below…)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&quot;the-command-line-and-the-manual&quot;&gt;The command line and the manual&lt;/h3&gt;
&lt;p&gt;Open a terminal with the shortcut &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;T&lt;/kbd&gt;, or press the &lt;kbd&gt;Super&lt;/kbd&gt; key (the Windows key on the keyboard) and search for the &lt;code&gt;Terminal&lt;/code&gt; application.&lt;/p&gt;
&lt;p&gt;As a first step, you decide to inspect the files present on the server in order to find the log files. However, you are not sure which command to use for this.&lt;/p&gt;
&lt;p&gt;Fortunately, the command line lets you learn how each command works. The &lt;code&gt;man&lt;/code&gt; command allows you to read the manual page corresponding to a specific command.
For example, to get the documentation for the &lt;code&gt;ls&lt;/code&gt; command, you can use the following command:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;man&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ls&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you have opened the manual page, you can navigate using the arrow keys to read the content.
To quit the manual page, simply press the &lt;kbd&gt;q&lt;/kbd&gt; key.&lt;/p&gt;
&lt;p&gt;Also, some commands accept the &lt;code&gt;--help&lt;/code&gt; argument which displays a help message describing the arguments that can be passed to the command.
For example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-help&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By running this command, you will get a help message detailing the different options and arguments you can use with the &lt;code&gt;ls&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Do not hesitate to use the &lt;code&gt;--help&lt;/code&gt; argument with commands you wish to explore to obtain additional information on their usage.
This can help you better understand the available features and correctly use commands in your exploration of the server.&lt;/p&gt;
&lt;p&gt;For some commands such as &lt;code&gt;cd&lt;/code&gt; (which is a command built into the Bash shell), you should instead use&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; cd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;&lt;strong&gt;Terminal shortcuts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auto-completion:&lt;/strong&gt; You can use the &lt;kbd&gt;Tab&lt;/kbd&gt; key to get auto-completion in the terminal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quit a command:&lt;/strong&gt; In a terminal, the &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;C&lt;/kbd&gt; shortcut, rather than copying, terminates the execution of a command.
For example, the &lt;code&gt;yes&lt;/code&gt; command indefinitely repeats the letter &lt;code&gt;y&lt;/code&gt; in the terminal.
To quit, press &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;C&lt;/kbd&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;yes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Ctrl+C to quit the execution of yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;To copy and paste&lt;/strong&gt;, the terminal uses &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;C&lt;/kbd&gt; and &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;V&lt;/kbd&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To close a terminal&lt;/strong&gt;, you can use &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;D&lt;/kbd&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;exercise-01-basic-commands&quot;&gt;Exercise 01 – Basic commands&lt;/h3&gt;
&lt;p&gt;This exercise aims to familiarize you with a few basic commands that will be useful throughout the workshop.
To do this, use the &lt;code&gt;man&lt;/code&gt; command and the &lt;code&gt;--help&lt;/code&gt; argument to obtain detailed information on how each command works.
In the file &lt;code&gt;exercice_01.txt&lt;/code&gt;, briefly describe the purpose of each of the following commands.
This cheat sheet will be useful throughout the workshop.
You can consult it with the command &lt;code&gt;cat exercice_01.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Open &lt;code&gt;exercice_01.txt&lt;/code&gt; with &lt;code&gt;nano&lt;/code&gt; with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;nano&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; exercice_01.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In another terminal (&lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;T&lt;/kbd&gt; to open another terminal or &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;T&lt;/kbd&gt; to open another terminal in a tab), use the terminal to determine the behavior of the following commands:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Commands&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;nano&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rm&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rmdir&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mv&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;chmod&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;touch&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;br /&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Command&lt;/th&gt;&lt;th&gt;Definition&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;nano&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Simple text editor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Change current directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;&lt;td&gt;List files in a directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Display a file’s content&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Create a directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rm&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Delete a file or directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rmdir&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Delete an empty directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mv&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Move/rename a file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Show the path of the current directory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Copy a file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;chmod&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Change file permissions&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;touch&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Update a file’s timestamp, or create it if it does not exist&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/details&gt;
&lt;h3 id=&quot;exercise-02-file-system-navigation&quot;&gt;Exercise 02 – File system navigation&lt;/h3&gt;
&lt;p&gt;Use the commands listed above to explore the directory tree and find the file with the &lt;code&gt;.log&lt;/code&gt; extension.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;Here are some special paths:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; represents the current directory;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;..&lt;/code&gt; represents the parent directory;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~&lt;/code&gt; represents the user’s home directory (&lt;code&gt;/home/username/&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-&lt;/code&gt; represents the path of the last visited directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can use these special paths with several commands, notably &lt;code&gt;cd&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Navigate into the abc/def directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; abc/def&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Navigate to the parent directory (abc)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ..&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Return to the home directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Return to the previous directory (abc)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;List the files in the current directory&lt;/li&gt;
&lt;li&gt;Move through the different directories and try to find the file with the &lt;code&gt;.log&lt;/code&gt; extension&lt;/li&gt;
&lt;li&gt;Copy the &lt;strong&gt;absolute&lt;/strong&gt; path (from the root of the file system &lt;code&gt;/&lt;/code&gt;) of the directory where the log files are located into the file &lt;code&gt;~/out_02.txt&lt;/code&gt;. Do not add a newline at the end.&lt;/li&gt;
&lt;/ol&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;p&gt;Commands to run:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd ApplicationData/output/logs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Expected path: &lt;code&gt;/home/glo2001/ApplicationData/output/logs&lt;/code&gt;&lt;/p&gt;
&lt;/details&gt;
&lt;h3 id=&quot;exercise-03-home-directory-and-copy&quot;&gt;Exercise 03 – &lt;code&gt;home&lt;/code&gt; directory and copy&lt;/h3&gt;
&lt;p&gt;Now that you have found the log file, it’s time to make a copy of it in your &lt;code&gt;home&lt;/code&gt; directory.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;The home directory is where a user’s personal files are stored.
Each user has their own directory in &lt;code&gt;/home/&lt;/code&gt;.
If your username is &lt;code&gt;username&lt;/code&gt;, so your home directory is located at &lt;code&gt;/home/username&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is also a shortcut to refer to the home directory: &lt;code&gt;~&lt;/code&gt;. Thus, each of the following commands returns you to the home directory:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Use an absolute path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /home/admin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Use tilde&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Without arguments, cd returns to the home directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Copy the &lt;code&gt;.log&lt;/code&gt; file into the &lt;code&gt;~/log_backup&lt;/code&gt; directory.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Return to your &lt;code&gt;home&lt;/code&gt; directory;&lt;/li&gt;
&lt;li&gt;Create a new directory named &lt;code&gt;log_backup&lt;/code&gt; in your &lt;code&gt;home&lt;/code&gt; directory;&lt;/li&gt;
&lt;li&gt;Copy the .log file into the backup directory, giving it the name &lt;code&gt;build_backup.log&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;p&gt;Commands:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir log_backup&lt;/code&gt; (typo in LaTeX was &lt;code&gt;mdkdir&lt;/code&gt; but intent is mkdir)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cp ~/ApplicationData/output/logs/build.log ~/log_backup/build_backup.log&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/details&gt;
&lt;h3 id=&quot;exercise-04-permissions&quot;&gt;Exercise 04 – Permissions&lt;/h3&gt;
&lt;p&gt;Now that you have backed up the log file, it’s time to run the diagnostic script provided by your boss to analyze the system.
Go back to the log directory, and try to run the script &lt;code&gt;diagnostic.sh&lt;/code&gt; using &lt;code&gt;./diagnostic.sh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, you encounter a permissions error.
To fix this, inspect the script permissions using the &lt;code&gt;ls -l&lt;/code&gt; command.
Then, modify the permissions to make the script executable.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;&lt;code&gt;chmod&lt;/code&gt;, short for &lt;em&gt;change mode&lt;/em&gt;, is a command used to modify access permissions for files and directories.
Permissions in bash refer to the access rights granted to users and groups to read, write, and execute files and directories.
These permissions control who can perform which operations on a given file or directory.
You can list file and directory permissions with &lt;code&gt;ls -l&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;drwxr-xr--&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; group&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4096&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Sep&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;  7&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 10:00&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;-rwxr-xr--&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; group&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;  123&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Sep&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;  7&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 10:00&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Permissions are generally represented by one character followed by three groups of three characters each, for a total of nine characters, displayed in a specific order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first character indicates whether it is a file (&lt;code&gt;-&lt;/code&gt;) or a directory (&lt;code&gt;d&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The first group of three characters represents the permissions of the file’s owner.&lt;/li&gt;
&lt;li&gt;The second group represents the permissions of the group to which the file belongs.&lt;/li&gt;
&lt;li&gt;The third group represents the permissions for other users.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each group of three characters consists of the following permission types:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt; (&lt;em&gt;read&lt;/em&gt;): Read the content of the file or directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;w&lt;/code&gt; (&lt;em&gt;write&lt;/em&gt;): Modify a file’s contents; for a directory, create, delete, or rename entries inside it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x&lt;/code&gt; (&lt;em&gt;execute&lt;/em&gt;): Execute a file; for a directory, traverse it and access entries within it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To modify these permissions, you can use the &lt;code&gt;chmod&lt;/code&gt; command.
For example, to add (&lt;code&gt;+&lt;/code&gt;) the execute permission to a file:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chmod&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; script.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To remove the write permission from a directory:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chmod&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; folder&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inspect the file permissions;&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;chmod&lt;/code&gt; with the &lt;code&gt;+x&lt;/code&gt; argument to modify permissions;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;diagnostic.sh&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Check permissions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;l&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Change permissions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;chmod&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; diagnostic.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Run the script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;./diagnostic.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-05-wildcards&quot;&gt;Exercise 05 – Wildcards&lt;/h3&gt;
&lt;p&gt;The script generated about ten &lt;code&gt;.out&lt;/code&gt; files containing the results of the system analysis. You need to move these files into a new folder named &lt;code&gt;output&lt;/code&gt;.
Instead of moving each file manually with the command &lt;code&gt;mv out_01.out output/&lt;/code&gt;, which would be tedious, you can use the wildcard character (&lt;code&gt;*&lt;/code&gt;), which allows you to select multiple files at once.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;The &lt;code&gt;*&lt;/code&gt; character is interpreted by the shell before the command is executed. This is called globbing.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the current directory contains:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a.out&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b.out&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;notes.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bash expands the command to something equivalent to:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; a.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; b.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;mv&lt;/code&gt; command itself does not interpret &lt;code&gt;*.out&lt;/code&gt;; Bash first replaces the pattern with the matching filenames, then launches &lt;code&gt;mv&lt;/code&gt;.
By default, &lt;code&gt;*&lt;/code&gt; does not match filenames beginning with &lt;code&gt;.&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Some common glob patterns are:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;*       any sequence of characters&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?       exactly one character&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[abc]   one character among a, b, or c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[0-9]   one digit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ls *.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ls file?.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ls image[0-9].png&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Globbing is different from regular expressions.
A pattern such as &lt;code&gt;*.txt&lt;/code&gt; is a shell glob: &lt;code&gt;*&lt;/code&gt; matches any sequence of filename characters and &lt;code&gt;.&lt;/code&gt; is literal. In a regular expression, &lt;code&gt;.&lt;/code&gt; matches any single character and &lt;code&gt;*&lt;/code&gt; repeats the preceding element. &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;sed&lt;/code&gt; use regular expressions; &lt;code&gt;find -name&lt;/code&gt; uses shell-style filename patterns.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before moving the files, you can try the command &lt;code&gt;cat *&lt;/code&gt;.
This command displays the contents of matching non-hidden files in the current directory.&lt;/p&gt;
&lt;p&gt;However, in your case, you do not want to select all files.
You can specify a specific pattern by adding a prefix or suffix to the filenames.
For example, to select all &lt;code&gt;.sh&lt;/code&gt; files, you can use the command &lt;code&gt;ls *.sh&lt;/code&gt;.
This will display the list of files with the &lt;code&gt;.sh&lt;/code&gt; extension.&lt;/p&gt;
&lt;p&gt;Tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a folder named &lt;code&gt;output_backup&lt;/code&gt; in the &lt;code&gt;~/ApplicationData/output/logs&lt;/code&gt; directory;&lt;/li&gt;
&lt;li&gt;Move all files ending with &lt;code&gt;.out&lt;/code&gt; into the folder in a single command.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Move to the correct directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/ApplicationData/output/logs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Create the output folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output_backup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Move the files into the folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output_backup/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-06-deleting-files-and-folders&quot;&gt;Exercise 06 – Deleting files and folders&lt;/h3&gt;
&lt;p&gt;In addition to generating &lt;code&gt;.out&lt;/code&gt; files, the script also generated temporary &lt;code&gt;.tmp&lt;/code&gt; files and a folder named &lt;code&gt;temp&lt;/code&gt;.
These files and this folder can be deleted.&lt;/p&gt;
&lt;p&gt;Tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Delete the files with the &lt;code&gt;.tmp&lt;/code&gt; extension;&lt;/li&gt;
&lt;li&gt;Delete the &lt;code&gt;temp&lt;/code&gt; folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Delete .tmp files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.tmp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Delete the folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; temp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-07-basic-scripting&quot;&gt;Exercise 07 – Basic scripting&lt;/h3&gt;
&lt;p&gt;To simplify the task of moving and deleting the files generated by the &lt;code&gt;diagnostic.sh&lt;/code&gt; script, you can create a script that will automate these actions for you.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;Here is an example Bash script:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Start of script&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;End of script&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this script, the line &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; is called a &lt;em&gt;shebang&lt;/em&gt; (she = &lt;code&gt;#&lt;/code&gt;, bang = &lt;code&gt;!&lt;/code&gt;).
It tells the interpreter which program should be used to run the script—in this case, Bash.
It would also be possible to specify another program as the interpreter.
For example, to interpret the script as Python 3, we would use the following shebang: &lt;code&gt;#!/usr/bin/env python3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; is generally preferable to &lt;code&gt;#!/bin/bash&lt;/code&gt;, as it looks up the location of the Bash executable in the user’s environment, making it more portable across systems.&lt;/p&gt;
&lt;p&gt;You can create a text file with the &lt;code&gt;.sh&lt;/code&gt; extension (for example, &lt;code&gt;example.sh&lt;/code&gt;), copy the script above into it, then make the file executable using &lt;code&gt;chmod +x example.sh&lt;/code&gt;.
Next, you can run the script using &lt;code&gt;./example.sh&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, create a script that performs the following operations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a script named &lt;code&gt;cleanup.sh&lt;/code&gt; in the directory &lt;code&gt;~/ApplicationData/output/logs/&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Give the script execute permissions;&lt;/li&gt;
&lt;li&gt;Use the commands you typed in the previous exercises to create your script:
&lt;ul&gt;
&lt;li&gt;Create a folder named &lt;code&gt;output_backup&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Move all files ending with &lt;code&gt;.out&lt;/code&gt; into the folder in a single command;&lt;/li&gt;
&lt;li&gt;Delete the files with the &lt;code&gt;.tmp&lt;/code&gt; extension;&lt;/li&gt;
&lt;li&gt;Delete the &lt;code&gt;temp&lt;/code&gt; folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Make sure to delete the &lt;code&gt;output&lt;/code&gt; folder you created earlier;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;diagnostic.sh&lt;/code&gt; once more, and test your script.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;You can use the &lt;code&gt;history&lt;/code&gt; command to view the list of commands you have previously executed in the terminal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Create the output_backup folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output_backup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Move the files into the folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output_backup/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Delete .tmp files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.tmp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Delete the folder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; temp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;advanced-commands&quot;&gt;Advanced commands&lt;/h2&gt;
&lt;p&gt;Now that you’ve performed some cleanup operations and become familiar with the command line, it’s time to analyze the logs and outputs of the diagnostic program.
To do this, you will need to combine several commands using &lt;code&gt;piping&lt;/code&gt; and more advanced commands.
Before addressing this topic, you will explore some more advanced commands that will be useful later.&lt;/p&gt;
&lt;h3 id=&quot;exercise-08-advanced-commands&quot;&gt;Exercise 08 – Advanced commands&lt;/h3&gt;
&lt;p&gt;As in exercise 1, use the &lt;code&gt;man&lt;/code&gt; command and the &lt;code&gt;--help&lt;/code&gt; argument to obtain detailed information on the commands in the following table.
These commands are a bit different from those seen in exercise 1; they can take a file as input, or you can &lt;code&gt;pipe&lt;/code&gt; the output of another command to them, which will be the subject of the next section.
You can create a test file (&lt;code&gt;test_file.txt&lt;/code&gt;) to test the commands.&lt;/p&gt;
&lt;p&gt;In the file &lt;code&gt;exercice_08.txt&lt;/code&gt;, briefly describe the purpose of each of the following commands.
This cheat sheet will be useful throughout the workshop.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Commands&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tac&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;less&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uniq&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;du&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;curl&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;awk&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sleep&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;br /&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Command&lt;/th&gt;&lt;th&gt;Definition&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tac&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Reverse the order of lines in a file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;less&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Text pagination&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;&lt;td&gt;File search&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Filter lines by a pattern&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Sort lines&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;uniq&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Remove adjacent duplicate lines&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Count lines, words, and characters&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Display the beginning of a file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Display the end of a file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;du&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Show file sizes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;curl&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Network request (HTTP, FTP, etc.)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Stream editor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;awk&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Interpreter for the &lt;code&gt;awk&lt;/code&gt; language&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Stop a process&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;sleep&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Wait for a number of seconds&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/details&gt;
&lt;h3 id=&quot;exercise-09-advanced-commands-1&quot;&gt;Exercise 09 – Advanced commands 1&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;messages.txt&lt;/code&gt; file in the log folder contains the error messages that cause the system outage.
Unfortunately, this file also contains a lot of logs that are not useful to you.
Rather than manually reading the entire file, you decide to use the Bash commands you just discovered.&lt;/p&gt;
&lt;p&gt;Use a command to display all lines of &lt;code&gt;messages.txt&lt;/code&gt; that contain the string &lt;code&gt;Error&lt;/code&gt; and copy the result into the file &lt;code&gt;~/errors.txt&lt;/code&gt;.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; messages.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-10-advanced-commands-2&quot;&gt;Exercise 10 – Advanced commands 2&lt;/h3&gt;
&lt;p&gt;After inspecting the errors that you copied into &lt;code&gt;~/errors.txt&lt;/code&gt;, you realize there are many duplicates.
Use a Bash command to remove duplicate lines and copy the result into &lt;code&gt;~/errors_2.txt&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;&lt;code&gt;uniq&lt;/code&gt; removes repeated &lt;strong&gt;adjacent&lt;/strong&gt; lines. If identical lines are separated by other lines, &lt;code&gt;uniq&lt;/code&gt; will not detect them.&lt;/p&gt;
&lt;p&gt;A common pattern is therefore:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; uniq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;sort&lt;/code&gt; groups identical lines together, after which &lt;code&gt;uniq&lt;/code&gt; removes the duplicates.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; uniq&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors_2.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors_2.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-11-advanced-commands-3&quot;&gt;Exercise 11 – Advanced commands 3&lt;/h3&gt;
&lt;p&gt;The log file &lt;code&gt;~/errors_2.txt&lt;/code&gt; contains HTTP errors such as:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error 404: File not found&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error 403: Access denied&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error 500: Internal server error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For this exercise, all client errors (&lt;code&gt;4xx&lt;/code&gt; such as &lt;code&gt;400&lt;/code&gt;, &lt;code&gt;403&lt;/code&gt; and &lt;code&gt;404&lt;/code&gt;) should be reclassified as warnings while preserving the error code.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error 404: File not found&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;should become:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Warning 404: File not found&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;sed -E&lt;/code&gt;, match &lt;code&gt;^Error (4[0-9]{2}):&lt;/code&gt; and replace it with &lt;code&gt;Warning \1:&lt;/code&gt;. The &lt;code&gt;\1&lt;/code&gt; inserts the captured error code.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;The substitution has the form: &lt;code&gt;s/pattern/replacement/g&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; means substitute;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pattern&lt;/code&gt; is the regular expression to match;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;replacement&lt;/code&gt; is the text that replaces the match;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g&lt;/code&gt; means replace every match on a line, rather than only the first. It is optional when a pattern can match only once per line.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;In the regular expression &lt;code&gt;^Error (4[0-9]{2}):&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt; matches the beginning of the line, and &lt;code&gt;:&lt;/code&gt; after the code prevents a match on a longer number such as 4000.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;4[0-9]{2}&lt;/code&gt; matches exactly three digits starting with 4, such as 400, 403, or 404.&lt;/li&gt;
&lt;li&gt;The parentheses capture those three digits as group 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the replacement &lt;code&gt;Warning \1:&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\1&lt;/code&gt; inserts the text captured by group 1; the literal colon follows it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use a Bash command to modify the messages and copy the result into &lt;code&gt;~/errors_3.txt&lt;/code&gt;.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sed&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/^Error (4[0-9]{2}):/Warning \1:/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors_2.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/errors_3.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;program-composition&quot;&gt;Program composition&lt;/h2&gt;
&lt;p&gt;Program composition is at the heart of the Unix philosophy.
Here is an excerpt from &lt;em&gt;The Art of Unix Programming&lt;/em&gt; describing the importance of program composition (full chapter available &lt;a rel=&quot;external&quot; href=&quot;http://www.catb.org/esr/writings/taoup/html/ch01s06.html&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s hard to avoid programming overcomplicated monoliths if none of your programs can talk to each other.&lt;/p&gt;
&lt;p&gt;Unix tradition strongly encourages writing programs that read and write simple, textual, stream-oriented, device-independent formats. Under classic Unix, as many programs as possible are written as simple filters, which take a simple text stream on input and process it into another simple text stream on output.&lt;/p&gt;
&lt;p&gt;Despite popular mythology, this practice is favored not because Unix programmers hate graphical user interfaces. It’s because if you don’t write programs that accept and emit simple text streams, it’s much more difficult to hook the programs together.&lt;/p&gt;
&lt;p&gt;Text streams are to Unix tools as messages are to objects in an object-oriented setting. The simplicity of the text-stream interface enforces the encapsulation of the tools. More elaborate forms of inter-process communication, such as remote procedure calls, show a tendency to involve programs with each others’ internals too much.&lt;/p&gt;
&lt;p&gt;To make programs composable, make them independent. A program on one end of a text stream should care as little as possible about the program on the other end. It should be made easy to replace one end with a completely different implementation without disturbing the other.&lt;/p&gt;
&lt;p&gt;— Chapter 1. Philosophy, Rule of Composition&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This program composition can be achieved using different operators, which will be the subject of the next sections.&lt;/p&gt;
&lt;h3 id=&quot;composition&quot;&gt;Composition&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;;&lt;/code&gt; operator allows you to run one command after another on the same line.&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command1 ; command2&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;For example, for exercise 7, we could rewrite the program as follows:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; mv&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.out&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output/&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.tmp&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; temp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator runs the second command only if the first one succeeded (returns an exit code equal to zero).&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command1 &amp;amp;&amp;amp; command2&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Prints &amp;quot;Hello World&amp;quot; because both commands succeed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;World&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We print Hello because the directory exists, so cd succeeds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; existing_directory&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;# We do not print Hello because the directory does not exist, so cd fails&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cd non_existent_directory &amp;amp;&amp;amp; echo &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;||&lt;/code&gt; operator runs the second command only if the first one failed (returns a non-zero exit code).&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command1 || command2&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Prints only Hello, because echo &amp;#39;Hello&amp;#39; succeeds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;World&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We do not print Hello, because cd succeeds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; existing_file&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We print Hello, because cd fails&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; non_existing_file&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;pipes&quot;&gt;Pipes&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;|&lt;/code&gt; operator passes the output of one command as input to another.
This operator is also called a &lt;em&gt;pipe&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command1 | command2&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; List names ending in .txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\.txt$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Sort the lines of a file, keep only the first 5 lines&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;redirection&quot;&gt;Redirection&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;&amp;gt;&lt;/code&gt; operator redirects a command’s output to a file, overwriting the file.&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command &amp;gt; file&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, it is possible to download a text file with &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; https://www.ulaval.ca/&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ulaval.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To discard a command’s output:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;&lt;/code&gt; operator redirects a command’s input from a file.&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command &amp;lt; file&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;wc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; operator, like &lt;code&gt;&amp;gt;&lt;/code&gt;, redirects a command’s output to a file, but &lt;strong&gt;appends&lt;/strong&gt; to the end of the file rather than overwriting it:&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command &amp;gt;&amp;gt; file&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator is like &lt;code&gt;&amp;lt;&lt;/code&gt;, but allows you to pass multiple lines.&lt;/p&gt;
&lt;p&gt;(&lt;code&gt;command &amp;lt;&amp;lt;delim [multiple lines] delim&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;abc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;def&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;hij&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; We can replace EOF (end of file) with any other string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;ABC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;abc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;def&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;hij&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ABC&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Find the first 5 names ending in .txt in alphabetical order&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\.txt$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. List the names&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Keep only names ending in .txt; \ makes the dot literal, and $ matches the end of the line&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Sort alphabetically&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 4. Keep only the first 5 results&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Using find for regular files; -name uses a filename glob, where the dot is already literal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; .&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;maxdepth&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;*.txt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Keep only lines containing the text &amp;quot;warning&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; replace &amp;quot;warning&amp;quot; with &amp;quot;error&amp;quot;, then write the result to output.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; data.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/warning/error/g&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Display the contents of data.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Filter lines to keep only those containing &amp;quot;warning&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Apply a regex to replace &amp;quot;warning&amp;quot; with &amp;quot;error&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 4. &amp;gt; writes the result to the file output.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Can also just use grep&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; data.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/warning/error/g&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Generate a test file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1\t2\n2\t3\n3\t4\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; foo.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Display a formatted string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Write the result to foo.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Compute the sum of each column&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; foo.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{sum += $1; sum2 += $2} END {print sum; print sum2}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; xargs&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Sum of both columns&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Display the contents of foo.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Awk accumulates column sums and prints them&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Pass the awk result to echo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Or omit cat&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{sum += $1; sum2 += $2} END {print sum; print sum2}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; foo.txt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; xargs&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Sum of both columns&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We recommend trying these commands one at a time to fully understand each step of the pipeline, for example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\.txt$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\.txt$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\.txt$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;standard-input-output-and-errors&quot;&gt;Standard input, output, and errors&lt;/h3&gt;
&lt;p&gt;Unix programs conventionally use three standard streams:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0   stdin    standard input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1   stdout   standard output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2   stderr   standard error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;stdin&lt;/code&gt; is where a program reads its input. &lt;code&gt;stdout&lt;/code&gt; carries normal output, while &lt;code&gt;stderr&lt;/code&gt; carries warnings and errors.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; server.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This reads &lt;code&gt;server.log&lt;/code&gt; and writes matching lines to stdout. The &lt;code&gt;&amp;gt;&lt;/code&gt; operator redirects stdout to a file:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; server.log&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; errors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is equivalent to explicitly writing &lt;code&gt;1&amp;gt;&lt;/code&gt; because &lt;code&gt;1&lt;/code&gt; refers to stdout:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; server.log&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; errors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Errors can be redirected separately with &lt;code&gt;2&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; missing-file.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; errors.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Normal output would still go to the terminal, while error messages go to &lt;code&gt;errors.log&lt;/code&gt;. You can redirect both streams independently:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; output.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; errors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To discard a stream, redirect it to &lt;code&gt;/dev/null&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To discard both stdout and stderr:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; sends file descriptor &lt;code&gt;2&lt;/code&gt; to the destination currently used by file descriptor &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By default, a pipeline passes only stdout from &lt;code&gt;command1&lt;/code&gt; to stdin of &lt;code&gt;command2&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;command1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; command2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Errors from &lt;code&gt;command1&lt;/code&gt; still appear on the terminal.&lt;/p&gt;
&lt;h3 id=&quot;exercise-12-piping-and-redirection&quot;&gt;Exercise 12 – Piping and redirection&lt;/h3&gt;
&lt;p&gt;Use piping and redirection to rewrite exercises 9, 10 and 11 as a single command.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Error&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; messages.txt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; uniq&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sed&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/^Error (4[0-9]{2}):/Warning \1:/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_12.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-13-file-sizes&quot;&gt;Exercise 13 – File sizes&lt;/h3&gt;
&lt;p&gt;Use this command which returns the list of files and their size:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/Documents&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; du&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; {}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each line contains the size in bytes and the file name separated by a &lt;kbd&gt;Tab&lt;/kbd&gt; character.
Use the output of this command to find the five largest files. Your script must return five lines in the same format as &lt;code&gt;du&lt;/code&gt;.&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/Documents&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; du&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; {}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;rh&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_13.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/Documents&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; du&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; {}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; tac&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_13.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/Documents&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; du&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;sb&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; {}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; tail&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; tac&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_13.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-14-data-analysis&quot;&gt;Exercise 14 – Data analysis&lt;/h3&gt;
&lt;p&gt;The file &lt;code&gt;~/ApplicationData/db.tsv&lt;/code&gt; contains data in TSV format (&lt;em&gt;TAB separated value&lt;/em&gt;).
Format:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;id&lt;/th&gt;&lt;th&gt;date&lt;/th&gt;&lt;th&gt;name&lt;/th&gt;&lt;th&gt;type&lt;/th&gt;&lt;th&gt;size&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;123&lt;/td&gt;&lt;td&gt;2023-12-25&lt;/td&gt;&lt;td&gt;foo&lt;/td&gt;&lt;td&gt;error_log&lt;/td&gt;&lt;td&gt;23&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Use this file to find the 10 rows with the smallest size (size column), keeping only the name column. You must keep the header of the retained column, i.e. the first line of &lt;code&gt;~/out_14.txt&lt;/code&gt; should be &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;To accomplish this task, you can use &lt;code&gt;awk&lt;/code&gt;, a programming language specialized for text manipulation.
For example, to extract the 1st and 3rd columns, separated by a &lt;kbd&gt;Tab&lt;/kbd&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{print $1 &amp;quot;\t&amp;quot; $3}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{print $5 &amp;quot; &amp;quot; $3}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; db.tsv&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 11&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{print $2}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_14.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;awk&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{print $5 &amp;quot; &amp;quot; $3}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; db.tsv&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sort&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; head&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 11&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/^[^ ]* //&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/out_14.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;scripting&quot;&gt;Scripting&lt;/h2&gt;
&lt;p&gt;Now that you are more comfortable with Bash, it’s time to create more advanced scripts.&lt;/p&gt;
&lt;p&gt;The following examples will help you understand how to create scripts that can take arguments, use variables, and implement control structures such as conditionals and loops.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The script arguments are available with $n (where n is a natural number)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The script name is: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The first argument is: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The second argument is: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;All arguments: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; {@:2:3} means take a slice starting at 2 (1-based) of length 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Arguments from 2 to 4: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Variables; note there are no spaces around the = sign&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;John&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; $age substitutes the variable’s value inside a string between double quotes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;My name is &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; and I am &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; years old.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Environment variables&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The value of HOME is: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;HOME&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Substitution&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;current_directory&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pwd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Substitutions work only for double quotes &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The current directory is: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;current_directory&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; using double quotes&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Not for single quotes &amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The current directory is: $current_directory using single quotes&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; It is also possible to call a command directly inside a string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Path: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Conditionals&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -ge&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 18&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;You are an adult.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;You are a minor.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Loops&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 3&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 4&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;i&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;done&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;fruits&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;apple&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;banana&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;orange&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; fruit&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;fruits&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;I like &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;done&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;while&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -le&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;counter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ((&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;++&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;done&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;greet&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello, &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Alice&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;quoting-variables&quot;&gt;Quoting variables&lt;/h3&gt;
&lt;p&gt;When a variable is expanded without quotes, Bash may split its value into multiple arguments and expand wildcard characters in it.&lt;/p&gt;
&lt;p&gt;Consider:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;my report.txt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bash expands the command approximately as:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; my&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; report.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;rm&lt;/code&gt; receives two filenames:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;my&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;report.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is usually not what we want. Quote the expansion when the value should remain a single argument:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now &lt;code&gt;rm&lt;/code&gt; receives exactly one filename:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;my report.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same rule applies to most variable expansions:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;kill&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;server_pid&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a general rule, write &lt;code&gt;&quot;$variable&quot;&lt;/code&gt; unless you specifically want Bash to split the value into words or expand wildcard characters in it.&lt;/p&gt;
&lt;p&gt;Double quotes still allow variable and command substitution:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Alice&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single quotes do not:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Hello $name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prints:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Hello $name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;exercise-15-test-script&quot;&gt;Exercise 15 – Test script&lt;/h3&gt;
&lt;p&gt;After all that cleaning and analysis, you decide it is wiser to just roll back to a previous version of the server until the problem is fixed.
As you are not sure which version is functional, you decide to write a script that will test the server and roll back to the previous version if the test fails.&lt;/p&gt;
&lt;p&gt;The first step is to write a script that tests whether the server is functional.
Save this script in the file &lt;code&gt;~/test.sh&lt;/code&gt;, and give it execute permissions.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Start the server in the background&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;python3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; uvicorn&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; main:app&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Save the process ID (pid) of the server with $!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; $! returns the pid of the last background process started&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;server_pid&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The `stop_server` function stops the server process&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;stop_server&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  kill&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;server_pid&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Register the `stop_server` function to be called when this script exits&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;trap&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; stop_server&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; EXIT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Wait for the server to be ready&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; TODO make an HTTP request to localhost:8000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; TODO If the result is an error, exit with code 1 using `exit 1`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; $? contains the return code of the last command&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Start the server in the background&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;python3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; uvicorn&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; main:app&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Save the process ID (pid) of the server with $!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;server_pid&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The `stop_server` function stops the server process&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;stop_server&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  kill&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;server_pid&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Register the `stop_server` function to be called when this script exits&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;trap&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; stop_server&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; EXIT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Wait for the server to be ready&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; TODO make an HTTP request to localhost:8080&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; localhost:8000&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; TODO If the result is an error, exit with code 1 using `exit 1`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; $? contains the return code of the last command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -eq&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Server is up&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Server is down&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  exit&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Or cleaner&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; curl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; localhost:8000&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Server is up&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Server is down&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    exit&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h3 id=&quot;exercise-16-version-rollback-script&quot;&gt;Exercise 16 – Version rollback script&lt;/h3&gt;
&lt;p&gt;Now that you have a test script, you can write a script that will roll back to the previous version of the server if the test fails.
Use the given &lt;code&gt;revert_last_commit&lt;/code&gt; function to roll back to the previous version of the server.&lt;/p&gt;
&lt;p&gt;Complete the following script to roll back to a previous version of the server until the test script passes.
Save this script in the file &lt;code&gt;~/revert.sh&lt;/code&gt;, and give it execute permissions.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
	&lt;p&gt;The repository contains a known working version in its history, so repeatedly moving to the previous commit will eventually succeed.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git reset --hard&lt;/code&gt; discards uncommitted changes.
It is safe here because the workshop repository is disposable.
Be careful if you use it in your own projects!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;revert_last_commit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; reset&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD~1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-hard&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit_status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; TODO write a while loop while $exit_status is not equal to 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; At each iteration, run the test.sh script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; If the script exits with code 0, stop the script with exit 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Otherwise, call the `revert_last_commit` function&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;details&gt;&lt;summary&gt;Solution&lt;/summary&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;revert_last_commit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; reset&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD~1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-hard&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit_status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;while&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit_status&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -ne&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Run the test script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  ~/test.sh&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Save the test script status&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  exit_status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit_status&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -ne&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The script returned a non-zero exit status (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit_status&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;). Reverting commit and retrying...&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    revert_last_commit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;The script returned 0 (success).&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    exit&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Add a delay between retries (optional)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  sleep&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;extras&quot;&gt;Extras&lt;/h2&gt;
&lt;h3 id=&quot;bashrc-file&quot;&gt;&lt;code&gt;.bashrc&lt;/code&gt; file&lt;/h3&gt;
&lt;p&gt;Below are optional enhancements you can add to your &lt;code&gt;~/.bashrc&lt;/code&gt; (or &lt;code&gt;~/.bash_profile&lt;/code&gt; depending on your shell startup rules) to make day‑to‑day terminal work more pleasant.&lt;/p&gt;
&lt;h4 id=&quot;prompt-customization&quot;&gt;Prompt customization&lt;/h4&gt;
&lt;p&gt;Simple minimal prompt (user@host:cwd$):&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;PS1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\u@\h:\w$ &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Prompt with colors, Git branch and exit code indicator (status inlined, no helper function):&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Compute git branch (if any)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;parse_git_branch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rev-parse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-is-inside-work-tree&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; br&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  br&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; symbolic-ref&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-short&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rev-parse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-short&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/dev/null&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; printf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; (%s)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;prompt_command&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; exit&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; exit status of previous command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; status&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -eq&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[32m\]✔\[\e[0m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[31m\]✘ &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[0m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; git_segment&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rev-parse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-is-inside-work-tree&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    git_segment&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;parse_git_branch&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  PS1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[36m\]\u@\h\[\e[0m\]:\[\e[33m\]\w\[\e[0m\]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git_segment&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\n$ &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;PROMPT_COMMAND&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Retro prompt:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;workshop_prompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; code&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; green&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[32m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; red&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[31m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; cyan&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[36m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; yellow&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[33m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\[\e[0m\]&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; status&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -eq&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;OK&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ERR:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; branch&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rev-parse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-is-inside-work-tree&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;amp;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    b&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; symbolic-ref&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-short&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; rev-parse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-short&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; HEAD&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/dev/null&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    branch&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;yellow&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Add user@host and current directory like the earlier prompt example&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Format: user@host:cwd [diag:STATUS]{ branch}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  PS1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cyan&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\u@\h&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;yellow&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\w&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cyan&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;branch&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\n$ &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;PROMPT_COMMAND&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&quot;safety-quality-of-life-options&quot;&gt;Safety &amp;amp; quality of life options&lt;/h4&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Safer rm / mv / cp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;rm -i&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; mv&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;mv -i&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; cp&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cp -i&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Human readable sizes for common tools&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; l&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ls -lh&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; la&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ls -lah&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; lt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ls -lht&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Grep with color&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; grep&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;grep --color=auto&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Shortcuts to common folders&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; docs&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cd ~/Documents&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; dls&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cd ~/Downloads&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; desk&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cd ~/Desktop&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Some fun aliases&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; please&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; emacs&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable some helpful shell options:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Append to history (do not overwrite) and share across sessions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;shopt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; histappend&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Re-edit a failed history substitution rather than error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;shopt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; histreedit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Correct minor directory typos with cd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;shopt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; cdspell&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;/dev/null&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;functions&quot;&gt;Functions&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Extract various archive formats with one command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;extract&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -f&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;File not found: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&amp;amp;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  case&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xjf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xzf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xJf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;     tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;  &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xjf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;     tar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; xzf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;     unzip&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;   &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;     unrar&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;      7z&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;    &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Don&amp;#39;t know how to extract &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&amp;amp;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt; ;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  esac&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Quickly serve current directory over HTTP (Python 3)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;serve&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  local&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; port&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:-&lt;/span&gt;&lt;span&gt;8000&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  echo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Serving on http://localhost:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; (Ctrl+C to stop)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  python3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; http.server&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;path&quot;&gt;&lt;code&gt;PATH&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;PATH&lt;/code&gt; environment variable contains a list of directories where the shell looks for executable files when you type a command.
When you type a command, the shell searches through each directory in the &lt;code&gt;PATH&lt;/code&gt; variable in order until it finds an executable file that matches the command name.
The first matching executable is executed.&lt;/p&gt;
&lt;p&gt;The value of &lt;code&gt;PATH&lt;/code&gt; is a colon-separated list of directories.
Adding directories to your &lt;code&gt;PATH&lt;/code&gt; allows you to run executables located in those directories without specifying their full path.
For example, if you have a script located in &lt;code&gt;~/.bin&lt;/code&gt;, you can add this directory to your &lt;code&gt;PATH&lt;/code&gt; variable to run the script from anywhere.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; PATH&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:~/.bin&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;alias-git&quot;&gt;Alias git&lt;/h3&gt;
&lt;p&gt;As you will likely use &lt;code&gt;git&lt;/code&gt; a lot, here are some useful aliases to add to your &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.gitconfig&lt;/code&gt; file.
Aliases allow you to create shortcuts for long commands.
You can add these aliases in your &lt;code&gt;~/.gitconfig&lt;/code&gt; file under the &lt;code&gt;[alias]&lt;/code&gt; section.
Here’s an example of useful &lt;code&gt;git&lt;/code&gt; aliases from &lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/willGuimont/79a8611a6a157db98945ae631ce847da&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;alias&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	lg1&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; log --graph --abbrev-commit --decorate --&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;format&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;format:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span&gt; --all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	lg2&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; log --graph --abbrev-commit --decorate --&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;format&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;format:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span&gt; --all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	lg&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;git lg1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  adog&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; log --all --decorate --oneline --graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	st&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	co&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	com&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; commit -m&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	coam&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; commit --amend&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	a&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	aa&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; add .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	p&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	pu&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; push -u origin HEAD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	cb&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; checkout -b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	c&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; checkout&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	m&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; merge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	f&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; fetch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	g&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; pull&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	wip&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; commit -a -m &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;wip&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	wap&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; commit -a -m&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	todo&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;git commit -a -m \&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;todo\&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;amp;&amp;amp; git p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	obs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;git commit -a -m \&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;obsidian\&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;amp;&amp;amp; git p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	refs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;git pull &amp;amp;&amp;amp; git commit -a -m \&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;updated references\&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;amp;&amp;amp; git p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	figs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;git pull &amp;amp;&amp;amp; git commit -a -m \&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;updated figures\&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;amp;&amp;amp; git p&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; In word diff, . matches each non-newline character&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	wdiff&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; diff --&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;word-diff-regex&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pull&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    ff&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; only&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Element of Errors Handling</title>
        <published>2025-07-25T00:00:00+00:00</published>
        <updated>2025-07-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/error-handling/"/>
        <id>https://willguimont.com/blog/error-handling/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/error-handling/">&lt;p&gt;Errors are everywhere.
Any computation, IO operation, database access, or API call – any of them can fail.
Despite this, most programming languages either struggle to make error handling correct or make it painful.
It’s almost always easy to write the happy path.
The moment something goes wrong, though, most languages make the not-so-happy path either verbose, implicit, or dangerously ignorable.&lt;/p&gt;
&lt;p&gt;Handling errors well should be a first-class concern of most programming languages.
It feels as if errors are just an afterthought in mainstream languages, added inelegantly out of necessity.&lt;/p&gt;
&lt;p&gt;This blog post stems from some error-handling experimentation I did back in 2021.
Then, at the end of my undergraduate studies in software engineering at Université Laval, we were assigned a final project in collaboration with an industry partner.
They gave us carte blanche to choose the technology.
Looking to try less mainstream languages and explore new paradigms, we decided to explore and compare several less conventional stacks – paying particular attention to how each one approached error handling, since our project required high reliability and robustness.&lt;/p&gt;
&lt;h2 id=&quot;errno-of-our-ways-c&quot;&gt;&lt;code&gt;errno&lt;/code&gt; of Our Ways (C)&lt;/h2&gt;
&lt;p&gt;Before looking at more &lt;em&gt;modern&lt;/em&gt; approaches to error handling, it is worth recalling the baseline most of them react against: C.
C has no dedicated error mechanism at all.
Functions signal failure through their return value – a &lt;code&gt;NULL&lt;/code&gt; pointer, a non-zero integer, or some other sentinel value – and stash the reason in a global variable, &lt;code&gt;errno&lt;/code&gt;.
You are expected to check the return value, then read &lt;code&gt;errno&lt;/code&gt; to find out what actually went wrong.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;errno.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;string.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    FILE &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt;f &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; fopen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;nonexistent.txt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;f &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; errno was set by fopen; translate it to a message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stderr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; strerror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;errno&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; will print the string followed by the string representation of errno&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error opening file&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    fclose&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While simple and practical, this model presents some flaws.
As C does not support multiple return values – i.e., tuples – without much boilerplate (defining a &lt;code&gt;struct&lt;/code&gt; with the return value and the error, a tagged union, or setting output variables via pointers), we end up using a value &lt;em&gt;in-band&lt;/em&gt; of the return type: &lt;code&gt;-1&lt;/code&gt; is both a valid integer and might indicate an error.
And &lt;code&gt;errno&lt;/code&gt; is global mutable state, which means it’s only meaningfully valid immediately after the call, is clobbered by the next failing function, and is a thread-safety hazard (hence &lt;code&gt;errno&lt;/code&gt; being a per-thread macro in modern C, since C11).
Every guarantee is shifted onto the discipline of the programmer; the language does not provide much tooling to handle errors.
With this model, the programmer needs to fix it by convention, for example, returning the value via assignment to a pointer, and keeping the function return value to indicate the error:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;errno.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;string.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Return value signals success/failure; result is written through `out`.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;y &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; EDOM&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; non-zero: error (domain error)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    *&lt;/span&gt;&lt;span&gt;out &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;/&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;         //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; zero: success&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    int&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    int&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;err &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stderr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; strerror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;trying-to-catch-lightning-in-a-bottle-exceptions-java-and-friends&quot;&gt;&lt;code&gt;Try&lt;/code&gt;ing to &lt;code&gt;Catch&lt;/code&gt; &lt;del&gt;Lightning in a Bottle&lt;/del&gt; Exceptions (Java and Friends)&lt;/h2&gt;
&lt;p&gt;The most well-known model is the &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; mechanism available in most mainstream programming languages.
You throw an error and hope someone, somewhere, catches it up the stack.
Otherwise, your program crashes unceremoniously.&lt;/p&gt;
&lt;p&gt;It’s an &lt;em&gt;easy&lt;/em&gt; method for the error-generating code: throw the exception and forget about it, but it is far from simple.
This is similar to the distinction between &lt;em&gt;simple&lt;/em&gt; and &lt;em&gt;easy&lt;/em&gt; made by Rich Hickey in his talk “&lt;a class=&quot;external&quot; href=&quot;https://www.infoq.com/presentations/Simple-Made-Easy/&quot; target=&quot;_blank&quot;&gt;Simple Made Easy&lt;/a&gt;”.
Exceptions are &lt;strong&gt;complecting&lt;/strong&gt; by nature; they intertwine normal control flow with error handling.
The control flow is no longer linear and predictable; you climb back up the stack looking for a handler.&lt;/p&gt;
&lt;p&gt;They let you skip instructions, bubble errors up several layers, and bypass normal control flow.
In a way, they are sugar-coated &lt;code&gt;goto&lt;/code&gt;s that jump through stack frames.&lt;/p&gt;
&lt;p&gt;Yes, &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt;/&lt;code&gt;finally&lt;/code&gt; blocks and RAII (in C++/Java with &lt;code&gt;try-with-resources&lt;/code&gt;) can clean things up nicely (although I prefer using &lt;code&gt;defer&lt;/code&gt; or &lt;code&gt;err_defer&lt;/code&gt;, which we will discuss later), but you’re still left with a system where it’s not obvious what code might throw and who handles the exception.&lt;/p&gt;
&lt;p&gt;Java attempted to solve the uncertainty around which operations might throw exceptions through checked exceptions, but that just shifted the problem.
You now have to annotate everything, tracing all possible failure paths and punting the problem upstream.
Most Java developers end up defaulting to unchecked exceptions anyway, sacrificing safety for their sanity.
Even Robert C. Martin said in Clean Code:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Checked exceptions can sometimes be useful if you are writing a critical library: You must catch them.
But in general application development, the dependency costs outweigh the benefits.&lt;/p&gt;
&lt;p&gt;– Robert C. Martin. Clean Code. 2008.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Despite their limitations, exceptions are still very much useful for their convenience and ease of use in simple cases.
That said, while it can be convenient to let domain exceptions bubble up – for instance, in a REST API handler where you want a 404 Not Found if the entity is not found in the repository deep in the domain – you’re still playing with possibly impossible-to-predict, and more importantly difficult-to-debug, control flow.
This is especially true in large codebases with many layers of abstraction, where an exception thrown deep in the stack can be caught and handled far away from its origin, making it hard to trace the error’s source.
While you can try to limit this with coding standards and best practices, it remains challenging and cumbersome if the language does not provide good alternatives.&lt;/p&gt;
&lt;h3 id=&quot;what-java-s-throws-wanted-to-be-swift&quot;&gt;What Java’s &lt;code&gt;throws&lt;/code&gt; Wanted to Be (Swift)&lt;/h3&gt;
&lt;p&gt;Swift 6.0+ offers a variation on the exception model, addressing some of the limitations and drawbacks of traditional exception handling by requiring explicit &lt;code&gt;try&lt;/code&gt; annotations, ensuring that potential failure points are visible at the call site.
Errors are values conforming to the &lt;code&gt;Error&lt;/code&gt; protocol (not a class hierarchy rooted in &lt;code&gt;Throwable&lt;/code&gt;), functions advertise fallibility with throws in their signature, and every call site must acknowledge it with &lt;code&gt;try&lt;/code&gt;, making throwing operations syntactically visible rather than invisible like Java’s unchecked exceptions.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; DivisionError&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; Error&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divisionByZero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;_&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;Int&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;by&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;Int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; throws&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;DivisionError&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; Int&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    guard&lt;/span&gt;&lt;span&gt; y &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; throw&lt;/span&gt;&lt;span&gt; DivisionError.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;divisionByZero&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;/&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Must acknowledge the throw with `try`, inside do/catch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;do&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    let&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;by&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result: &lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;\(&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; catch&lt;/span&gt;&lt;span&gt; DivisionError.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;divisionByZero&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; exhaustive: the type is known&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Cannot divide by zero&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; maybe  &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;by&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; nil — collapses the throw into an Optional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; forced &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;by&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5  — asserts it won&amp;#39;t throw; crashes if it does&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While similar to Java’s checked exceptions, Swift’s model sidesteps the problems of Java:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It’s opt-in, not mandatory. Plain throws still means “throws anything” — formally &lt;code&gt;throws(any Error)&lt;/code&gt;.
Java forces you to either declare every checked exception in your signatures or wrap them; there’s no escape hatch, so real codebases need to sprinkle &lt;code&gt;throws Exception&lt;/code&gt; or convert everything to unchecked &lt;code&gt;RuntimeException&lt;/code&gt;.
Swift lets you reach for a precise type only where it pays off (a critical domain error) and stay untyped everywhere else.&lt;/li&gt;
&lt;li&gt;Call-site ergonomics for choosing your safety level.
The &lt;code&gt;try&lt;/code&gt; / &lt;code&gt;try?&lt;/code&gt; / &lt;code&gt;try!&lt;/code&gt; family lets each call decide per-use whether to propagate, downgrade the throw into an Optional, or assert-and-crash.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;c-and-raii&quot;&gt;&lt;code&gt;C++&lt;/code&gt; and RAII&lt;/h3&gt;
&lt;p&gt;C++ does have one particularly elegant answer to exceptions: Resource Acquisition Is Initialization (RAII).
Instead of explicitly cleaning up resources in every possible failure path, you bind their lifetime to an object: the constructor acquires the resource, and the destructor releases it.
When an exception unwinds the stack, destructors for fully constructed local objects are called automatically in reverse order, so files are closed, locks released, and memory freed without finally blocks.
Standard types such as std::vector, std::unique_ptr, and std::lock_guard make this the default style of modern C++.
RAII does not make exception control flow any less implicit, but it makes that implicit flow considerably safer by ensuring that abandoning a scope does not also abandon its resources—provided, crucially, that destructors themselves do not throw.&lt;/p&gt;
&lt;h2 id=&quot;going-somewhere-with-errors-go&quot;&gt;&lt;code&gt;Go&lt;/code&gt;ing Somewhere with Errors (Go)&lt;/h2&gt;
&lt;p&gt;Go brought back the C-style return code (i.e., non-zero return for errors), modernized as error values returned by the function, now with &lt;code&gt;nil&lt;/code&gt; as the successful return value (absence of error).
You call a function, and it returns both a result and an error.
By convention, the error is the last return value.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;    &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;    &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; formatNaturalNumber validates the input is non-negative and returns it as a string.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; formatNaturalNumber&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;string&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; input&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; errors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;New&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;input is not a natural number: value is negative&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Natural Number: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; input&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    input&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 42&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    result&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; formatNaturalNumber&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;input&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Handle error and exit early&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%v&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Continue with the success path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes error handling explicit, which is a good thing: you see where errors can occur and have to deal with them directly.
You can follow the code, and you should be able to know exactly what happens when an error is returned.
You can handle the error here and there, or return it to the function’s caller.&lt;/p&gt;
&lt;p&gt;But this explicitness comes at the cost of verbosity and boilerplate.
You will see &lt;code&gt;if err != nil&lt;/code&gt; peppered everywhere.
Also, Go gives you no tools to help with error handling.
You’re mostly on your own to handle errors consistently.
Go does not provide any syntactic sugar for error handling, i.e., no &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt;, no pattern matching, no monadic operators.
Just &lt;code&gt;if err != nil&lt;/code&gt; over and over.&lt;/p&gt;
&lt;p&gt;You end up either duplicating error-propagation boilerplate or hiding the verbosity behind a generic helper that turns a non-nil error into a &lt;code&gt;panic&lt;/code&gt; (unwound by a &lt;code&gt;recover&lt;/code&gt; at the boundary; more on that mechanism below):&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; try&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; any&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        panic&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; v&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At which point you’ve reinvented a monad poorly: you’ve recovered the &lt;code&gt;?&lt;/code&gt;-style short-circuiting from Rust, but with none of the type-level guarantees – the control flow now rides on &lt;code&gt;panic&lt;/code&gt;/&lt;code&gt;recover&lt;/code&gt;, the compiler no longer sees the failure path, and one stray panic outside a recovering frame takes down the program.
The thing Go removed on purpose, smuggled back in through the back door.&lt;/p&gt;
&lt;p&gt;To its credit, Go includes one elegant feature for cleanup after an error might have occurred: &lt;code&gt;defer&lt;/code&gt;.
It allows you to schedule resource cleanup (like closing files or releasing locks) regardless of how the function exits, which pairs well with manual error handling:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;	&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;	&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; process&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Fprintln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Stderr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; process&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;file.txt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;		return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	defer&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Closing file&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Yes, this could also return an error and would need to be handled correctly&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	result&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; doSomething&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;		//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; f will still be closed! (&amp;quot;Closing file&amp;quot; prints even on this early return)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;		return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; doSomething&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;string&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Go also has a second, exception-like channel it would rather you didn’t reach for: &lt;code&gt;panic&lt;/code&gt; and &lt;code&gt;recover&lt;/code&gt;.
A panic unwinds the stack like an exception, and a deferred recover can catch it; it is used almost exclusively for truly unrecoverable bugs or at goroutine boundaries, not ordinary error handling.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; safeDivide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;	//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The panic is caught and recovered, so the program continues running&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Main keeps running&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; safeDivide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	defer&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;		if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; recover&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;			//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; &amp;quot;Catches&amp;quot; the panic and recovers, returning 0 as the result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;			fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Recovered:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;			result&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; compute&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; compute&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; panics here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More idiomatically, Go’s standard library leans on sentinel errors plus wrapping.
Wrapping an error with &lt;code&gt;%w&lt;/code&gt; preserves it in a chain; &lt;code&gt;errors.Is&lt;/code&gt; and &lt;code&gt;errors.As&lt;/code&gt; then walk that chain to match a sentinel or extract a typed error.
This recovers some of the structure that a bare &lt;code&gt;if err != nil&lt;/code&gt; discards.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;go&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;	&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;	&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; ErrDivideByZero&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; errors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;New&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;divide by zero&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Custom type carries the operands AND wraps the sentinel&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; DivideError&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	A&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; B&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;DivideError&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; string&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;cannot divide &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; by &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;A&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; e&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;B&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Unwrap lets errors.Is reach ErrDivideByZero underneath&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;e &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;DivideError&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; ErrDivideByZero&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;		return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;divide failed: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%w&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;DivideError&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;A&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; B&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	_&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;	fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;	//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; errors.Is: match the category (walks through DivideError&amp;#39;s Unwrap)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; errors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Is&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;err&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; ErrDivideByZero&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Category: divide by zero&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;	//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; errors.As: extract the data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	var&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; de&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;DivideError&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;	if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; errors&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;As&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;err&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;de&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;		fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Operands: a=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;, b=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; de&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;A&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; de&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;B&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;zig&quot;&gt;Zig&lt;/h3&gt;
&lt;p&gt;Zig handles errors a bit differently.
Instead of adding an explicit error return value, Zig uses error union types.
By adding &lt;code&gt;!&lt;/code&gt; before a type, you indicate that the function can return either a value of that type or an error, e.g., &lt;code&gt;fn doSomething() !i32&lt;/code&gt;.
Thus, it takes the union of the error set and the normal return type.
You can optionally narrow down the error set to specific errors by prefixing the error type, e.g., &lt;code&gt;fn doSomethingElse() ErrorType!ReturnType&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In addition, Zig has built-in syntax for propagating errors with &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt;.
When you call a function that can return an error, you can use &lt;code&gt;try&lt;/code&gt; to automatically propagate the error if it occurs, or get the value if it succeeds.
With &lt;code&gt;catch&lt;/code&gt;, you can provide a default value or handle the error in place by passing the error to a lambda.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;const&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; @import&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;const&lt;/span&gt;&lt;span&gt; DivisionError&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; error&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DivisionByZero&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; i32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;return&lt;/span&gt;&lt;span&gt; DivisionError&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DivisionByZero&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; @divTrunc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; performCalculation uses &amp;#39;try&amp;#39; to propagate errors to its caller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; performCalculation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; i32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; If divide returns an error, performCalculation exits here and returns the error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    const&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; This line only executes if divide was successful&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    const&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; performCalculation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Flow interrupted by error: {}&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Final Result: {}&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This minimizes boilerplate while keeping error handling explicit.
I quite like this approach, as it makes error propagation concise without losing clarity.&lt;/p&gt;
&lt;p&gt;Zig also has &lt;code&gt;defer&lt;/code&gt; for cleanup, similar to Go, but it adds &lt;code&gt;errdefer&lt;/code&gt;.
&lt;code&gt;errdefer&lt;/code&gt; is used when you want to clean up resources only if an error occurs.
For example, if you allocate a struct and an error happens later, you can use &lt;code&gt;errdefer&lt;/code&gt; to free that struct only in the error case, and return the created struct on success.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;const&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; @import&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;const&lt;/span&gt;&lt;span&gt; ProcessError&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; error&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    StepTwoFailed&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; complexOperation&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Step 1: Resource allocated.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; errdefer will ONLY run if this function returns an error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    errdefer&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Cleanup: Rolling back Step 1 due to failure.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    const&lt;/span&gt;&lt;span&gt; failure_condition&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;failure_condition&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Step 2: Encountered an issue.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; ProcessError&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;StepTwoFailed&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Step 3: Success! errdefer will not run.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    complexOperation&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;debug&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Final result: {}&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;err&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;odin&quot;&gt;Odin&lt;/h3&gt;
&lt;p&gt;I recently started experimenting with Odin, which has some interesting ideas around error handling.
Instead of considering errors as exceptions or special types, Odin treats them as regular return values.
As is the case for Go, Odin conventionally returns an error as the last return value of a function.
Unlike Zig, which uses error unions that require declaring error types using &lt;code&gt;error{}&lt;/code&gt;, Odin, by convention, simply treats non-zero return values as errors.
This is paired with Odin’s commitment to make zero values useful defaults, so a function returning zero for an error indicates success.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;core:fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Division_Error&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; enum&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    None&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; This is the zero value, indicating no error. Variables of this type default to None (0).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Division_By_Zero&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Negative_Input&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Function returns a result and an error enum&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;divide_positive&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;int&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Division_Error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;Division_By_Zero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;Negative_Input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; /&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    res&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide_positive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error encountered: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%v&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; res&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But Odin goes further with built-in operators to streamline error handling.
Assuming the last return value is the error, and that any non-zero value indicates an error, Odin provides &lt;code&gt;or_else&lt;/code&gt;, &lt;code&gt;or_return&lt;/code&gt;, &lt;code&gt;or_continue&lt;/code&gt;, and &lt;code&gt;or_break&lt;/code&gt; operators to handle errors concisely:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;or_else&lt;/code&gt; allows you to provide a default value if an error occurs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;or_return&lt;/code&gt; will return from the current function if an error occurs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;or_continue&lt;/code&gt; and &lt;code&gt;or_break&lt;/code&gt; can be used in loops to skip iterations or exit loops on errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;odin&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;core:fmt&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Division_Error&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; enum&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    None&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Division_By_Zero&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Negative_Input&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;divide_positive&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;int&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Division_Error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;Division_By_Zero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;|&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;Negative_Input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; /&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;wrapper_proc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; int&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; error_out&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Division_Error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Because parameters are named, or_return knows to put &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; the error into &amp;#39;error_out&amp;#39; and return.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Named return values, as everything in Odin, are zero-initialized.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    res&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide_positive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; or_return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; res&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 100&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Example using or_return (via wrapper)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    val&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; wrapper_proc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; !=&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;None&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;wrapper_proc failed: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%v&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;wrapper_proc result: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Example using or_else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; or_else provides a fallback value if the second return is not .None/false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    final_res&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide_positive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;5&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; or_else&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 999&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;divide_positive with or_else fallback: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; final_res&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Odin’s approach is reminiscent of Go’s explicit error handling but adds syntactic sugar to reduce boilerplate.
From these &lt;em&gt;errors-as-values&lt;/em&gt; methods, this is probably my favorite.
It builds on Go’s explicit error handling while providing operators like &lt;code&gt;or_return&lt;/code&gt; to streamline common patterns.
It does not require separate error construction like Zig, making it conceptually simpler.
Overall, I find Odin’s solution to error handling to be particularly elegant, while staying explicit.
It looks like a &lt;strong&gt;simpler&lt;/strong&gt; solution, albeit not necessarily an &lt;strong&gt;easy&lt;/strong&gt; one.&lt;/p&gt;
&lt;h2 id=&quot;playing-tag-with-errors-rust&quot;&gt;Playing Tag with Errors (Rust)&lt;/h2&gt;
&lt;p&gt;Rust’s tagged unions &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; and &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; types offer a different approach.
Errors are in the type system.
The compiler forces you to handle them – or explicitly ignore them (e.g., with &lt;code&gt;unwrap&lt;/code&gt;, &lt;code&gt;expect&lt;/code&gt;, etc.).
You can use Rust’s pattern matching to destructure and handle errors explicitly.&lt;/p&gt;
&lt;p&gt;Rust also provides the &lt;code&gt;?&lt;/code&gt; operator for concise error propagation:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;derive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyError&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; InvalidInput&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyError&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;MyError&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;InvalidInput&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; calculate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyError&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; If divide returns Err, calculate returns Err immediately&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; result&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Pattern match on the Result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    match&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; calculate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;        Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Result: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;        Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;?&lt;/code&gt; operator propagates errors up and makes code shorter, but it can also obscure control flow.
The whole flow of the function can be interrupted by a single &lt;code&gt;?&lt;/code&gt; character.
This single symbol rewires control flow and introduces implicit short-circuiting, which can obscure the data path.
At least, the &lt;code&gt;?&lt;/code&gt; operator is limited to functions returning &lt;code&gt;Result&lt;/code&gt; or &lt;code&gt;Option&lt;/code&gt;, so its use is explicit in the function signature.&lt;/p&gt;
&lt;p&gt;This is a limited form of monadic error handling.
This is arguably one of Rust’s strengths; it makes functional programming ideas more mainstream, e.g., algebraic data types, pattern matching, higher-order functions, and monadic error handling.&lt;/p&gt;
&lt;p&gt;Of course, Rust doesn’t force you to propagate or handle errors safely – you can always opt out:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; foo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; panics if Err&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; foo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;expect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;better crash message&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; same, but with context&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is worth distinguishing between &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; and &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;.
&lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; models a computation that failed and can say why, &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; models mere &lt;em&gt;absence&lt;/em&gt;, a value that may legitimately not be there, with no error to report.
Conflating them is a common design smell. A “Key not found in map” is usually an &lt;code&gt;Option&lt;/code&gt;, as absence is expected and unremarkable, whereas “could not read the config file” is a &lt;code&gt;Result&lt;/code&gt;; you want the reason.
This choice encodes intent directly into the type system, in a way that using nullable does not.
Rust lets you convert between them (&lt;code&gt;Option::ok_or&lt;/code&gt;, &lt;code&gt;Result::ok&lt;/code&gt;) precisely because the boundary is a judgment call that shifts with context; in some cases, &lt;em&gt;absence&lt;/em&gt; is &lt;em&gt;error&lt;/em&gt; or &lt;em&gt;error&lt;/em&gt; is &lt;em&gt;absence&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;riding-the-happy-rails-f-elm&quot;&gt;Riding the Happy Rails (F# / Elm)&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;?&lt;/code&gt; operator from Rust is really sugar for a pattern that some languages make the centerpiece: railway-oriented programming (a term coined by Scott Wlaschin for F#).
Picture two parallel tracks, success and failure.
Each step is a function that takes a success value and returns a &lt;code&gt;Result&lt;/code&gt;; &lt;code&gt;bind&lt;/code&gt;/&lt;code&gt;andThen&lt;/code&gt; chains them so that the first failure switches you onto the error track, where you stay for the rest of the journey.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; parseInt&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; string&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    match&lt;/span&gt;&lt;span&gt; System.Int32.TryParse s &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;with&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; true&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span&gt; n  &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; Ok n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; false&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Error &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;(&lt;/span&gt;&lt;span&gt;sprintf &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39; is not a number&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; divide&lt;/span&gt;&lt;span&gt; divisor x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; divisor &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;span&gt; Error &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;divide by zero&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    else&lt;/span&gt;&lt;span&gt; Ok &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;(&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;/&lt;/span&gt;&lt;span&gt; divisor&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; checkEven&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;span&gt; Ok x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    else&lt;/span&gt;&lt;span&gt; Error &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;(&lt;/span&gt;&lt;span&gt;sprintf &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; is not even&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;// Parse a string, divide by 2, then require the result to be even.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; compute&lt;/span&gt;&lt;span&gt; input &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&amp;gt;&lt;/span&gt;&lt;span&gt; parseInt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&amp;gt;&lt;/span&gt;&lt;span&gt; Result.bind &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;(&lt;/span&gt;&lt;span&gt;divide &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    |&amp;gt;&lt;/span&gt;&lt;span&gt; Result.bind checkEven&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt; _ &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    let&lt;/span&gt;&lt;span&gt; inputs&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        [&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     // 16 / 2 = 8, even   -&amp;gt; Ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;          &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     // 12 / 2 = 6, even   -&amp;gt; Ok&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;          &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     // 10 / 2 = 5, odd    -&amp;gt; fails at checkEven&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;          &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ]&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  // not a number       -&amp;gt; fails at parseInt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    for&lt;/span&gt;&lt;span&gt; input &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;in&lt;/span&gt;&lt;span&gt; inputs &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        match&lt;/span&gt;&lt;span&gt; compute input &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;with&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span&gt; Ok n    &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; printfn &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;ok:    &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span&gt; Error e &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; printfn &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;error: &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;    0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Elm spells the same idea &lt;code&gt;Result.andThen&lt;/code&gt;.
F#’s &lt;code&gt;bind&lt;/code&gt; is inspired by Haskell monads, and the &lt;code&gt;bind&lt;/code&gt; operator &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, which will be the subject of the next section.&lt;/p&gt;
&lt;h3 id=&quot;a-monadic-digression&quot;&gt;A Monadic Digression&lt;/h3&gt;
&lt;p&gt;Before writing this document, I assumed that Rust’s &lt;code&gt;?&lt;/code&gt; operator was limited to built-in types like &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; and &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, effectively restricting its use to these specific monads.
While this holds on stable Rust, the nightly-only &lt;code&gt;try_trait_v2&lt;/code&gt; feature extends the language’s capabilities by allowing custom types to participate in &lt;code&gt;?&lt;/code&gt;-based control flow through the implementation of the &lt;code&gt;Try&lt;/code&gt; and &lt;code&gt;FromResidual&lt;/code&gt; traits.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;feature&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;try_trait_v2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Infallible&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;ops&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;ControlFlow&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; FromResidual&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Try&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;derive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;E&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Try&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Output&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; T&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Residual&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Infallible&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; from_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;        MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;output&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; branch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; ControlFlow&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Residual&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Self&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Output&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        match&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;            MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;                println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Encountered Ok with value.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;                ControlFlow&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Continue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;            MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;                println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Encountered Err with value.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;                ControlFlow&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;Break&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; FromResidual&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Infallible&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; from_residual&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;residual&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Infallible&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; E&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        match&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; residual&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;            MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;                println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Converting residual Err to MyResult.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;                MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;            _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; unreachable!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; do_something&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; str&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; i32&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;oops&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    MyResult&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Output: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; do_something&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Outputs:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Encountered Ok with value.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Encountered Err with value.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Converting residual Err to MyResult.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Output: Err(&amp;quot;oops&amp;quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;from_output&lt;/code&gt; is analogous to Haskell’s &lt;code&gt;return&lt;/code&gt; (or &lt;code&gt;pure&lt;/code&gt; in the applicative context), lifting a value into the &lt;code&gt;Try&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;branch&lt;/code&gt; corresponds to a poor man’s monadic bind (&lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;), determining whether to propagate the value or short-circuit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;from_residual&lt;/code&gt; reconstructs the enclosing &lt;code&gt;Try&lt;/code&gt; type from the residual when &lt;code&gt;?&lt;/code&gt; short-circuits. Additional &lt;code&gt;FromResidual&lt;/code&gt; implementations can also explicitly permit propagation between compatible residual types.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Despite this flexibility, Rust’s &lt;code&gt;?&lt;/code&gt; operator is fundamentally an abstraction over short-circuiting control flow rather than general monadic sequencing.
&lt;code&gt;Result&lt;/code&gt; uses that mechanism for errors, &lt;code&gt;Option&lt;/code&gt; for absence, and &lt;code&gt;ControlFlow&lt;/code&gt; for explicit early termination.
In Haskell, by contrast, &amp;gt;&amp;gt;= describes general sequencing of computations and is not inherently associated with early exit.&lt;/p&gt;
&lt;p&gt;Despite how tempting it might look to generalize &lt;code&gt;?&lt;/code&gt; to arbitrary monads, I would caution against it.
Unlike Haskell, where monads are a first-class abstraction for sequencing computations with various effects, using &lt;code&gt;?&lt;/code&gt; with arbitrary monads could lead to confusion.&lt;/p&gt;
&lt;h2 id=&quot;a-monad-is-just-a-monoid-in-the-category-of-endofunctors-what-s-the-problem-haskell&quot;&gt;A monad is just a monoid in the category of endofunctors, what’s the problem? (Haskell)&lt;/h2&gt;
&lt;p&gt;Where Rust brings functional error handling into a systems programming language – with &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt;, &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, and &lt;code&gt;?&lt;/code&gt; – Haskell has far more powerful abstractions.&lt;/p&gt;
&lt;p&gt;Monads give you composable effects, including errors.
You can throw, catch, pattern match, and compose computations in &lt;code&gt;Either&lt;/code&gt;, &lt;code&gt;Maybe&lt;/code&gt;, or more complex stacks using monad transformers.&lt;/p&gt;
&lt;p&gt;As in Rust, &lt;code&gt;Either Error Value&lt;/code&gt; encodes a computation that can fail.
But in Haskell, you can manipulate it using the full suite of monadic tools.&lt;/p&gt;
&lt;p&gt;The example below shows how &lt;code&gt;ExceptT&lt;/code&gt;, a monad transformer, extends any base monad (typically &lt;code&gt;IO&lt;/code&gt;) with error-handling capabilities.
It generalizes the &lt;code&gt;Either e a&lt;/code&gt; pattern, allowing you to compose error propagation with other effects (like &lt;code&gt;IO&lt;/code&gt;, &lt;code&gt;State&lt;/code&gt;, etc.).&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Control.Monad.Except&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Define error type and a type alias for our error-handling monad&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; AppError&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; DivideByZero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  |&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; UnexpectedError&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  deriving&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Show&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; AppM&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExceptT&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; AppError&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; A function that fails safely&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;safeDivide&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; AppM&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;safeDivide _ &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; throwError &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;DivideByZero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;safeDivide x y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  |&lt;/span&gt;&lt;span&gt; y &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;     =&lt;/span&gt;&lt;span&gt; throwError &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;UnexpectedError&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Negative denominator&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  |&lt;/span&gt;&lt;span&gt; otherwise &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; return &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;`&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Composed computation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;compute&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; AppM&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;compute a b c &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; safeDivide a b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  y &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; safeDivide x c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  return y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Entry point&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  result &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; runExceptT &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;compute &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  case&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Left&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; DivideByZero&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;           -&amp;gt;&lt;/span&gt;&lt;span&gt; putStrLn &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Error: division by zero&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Left&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;UnexpectedError&lt;/span&gt;&lt;span&gt; msg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  -&amp;gt;&lt;/span&gt;&lt;span&gt; putStrLn &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Unexpected error: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt; msg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Right&lt;/span&gt;&lt;span&gt; val                   &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; putStrLn &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Success: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt; show val&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is quite elegant mathematically: you get typed, structured error handling that composes well with &lt;code&gt;IO&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But once you start stacking more than one effect – say, &lt;code&gt;ReaderT&lt;/code&gt;, &lt;code&gt;StateT&lt;/code&gt;, and &lt;code&gt;ExceptT&lt;/code&gt; – it quickly becomes hard to manage.
Libraries like &lt;code&gt;mtl&lt;/code&gt;, &lt;code&gt;freer&lt;/code&gt;, or &lt;code&gt;polysemy&lt;/code&gt; try to reduce this friction, but the conceptual weight remains high.
The learning curve is steep, and yes, monads still confuse people.
Not because they’re inherently difficult, but because most programming education doesn’t equip you to think in algebraic structures.&lt;/p&gt;
&lt;h3 id=&quot;excepting-monads&quot;&gt;Excepting Monads&lt;/h3&gt;
&lt;p&gt;Despite Haskell’s emphasis on pure functions and strong static typing, it still includes support for runtime exceptions.
Why?
Because not all errors fit cleanly into a type-level model—especially when dealing with I/O or legacy code.
However, these exceptions can be safely and idiomatically captured and transformed into more composable types like &lt;code&gt;Either&lt;/code&gt;, making them compatible with the broader functional ecosystem.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Control.Exception&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;SomeException&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; try&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Exception&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; throwIO&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Data.Typeable&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Typeable&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Example function that may fail at runtime&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;failingIO&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;failingIO &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; throwIO &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; userError &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Something went wrong&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  result &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; try failingIO &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; SomeException&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  case&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Left&lt;/span&gt;&lt;span&gt; e  &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; putStrLn &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Caught error: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt; show e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Right&lt;/span&gt;&lt;span&gt; v &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; print v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;parsing-and-non-empty-chains-scala&quot;&gt;Parsing and Non-Empty Chains (Scala)&lt;/h3&gt;
&lt;p&gt;This brings us to 2021, when this blog post really began.
During my final undergraduate project with a company, we decided to step away from the mainstream and explore more functional tooling.
That led us to Scala, and more specifically, to Cats.&lt;/p&gt;
&lt;p&gt;In many real-world domains – especially parsing, validation, and data ingestion – you don’t just want to know &lt;em&gt;if&lt;/em&gt; something failed.
You want to know &lt;em&gt;everything&lt;/em&gt; that failed.&lt;/p&gt;
&lt;p&gt;Scala’s &lt;code&gt;Cats&lt;/code&gt; library handles this elegantly with &lt;code&gt;Validated&lt;/code&gt; and &lt;code&gt;NonEmptyChain&lt;/code&gt;.
Unlike &lt;code&gt;Either&lt;/code&gt;, which short-circuits on the first failure, &lt;code&gt;Validated&lt;/code&gt; accumulates all errors.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; cats&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Validated&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;NonEmptyChain&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; cats&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;syntax&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Types&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Error&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;A&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Validated&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;NonEmptyChain&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Error&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;A&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Domain model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; User&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;age&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Input model (e.g., raw user-submitted data)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; RawInput&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;age&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Validation functions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; validateName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;String&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;name.trim.nonEmpty&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; name.validNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Name cannot be empty&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;.invalidNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; validateEmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;String&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;email.contains&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; email.validNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Email must contain &amp;#39;@&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;.invalidNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; validateAge&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ageStr&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; String&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Int&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ageStr.toIntOption &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;match&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;age&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; if&lt;/span&gt;&lt;span&gt; age &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; age.validNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;               =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Age must be non-negative&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;.invalidNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; None&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;                  =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Age must be a valid number&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;.invalidNec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Aggregate all validations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; validateUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; RawInput&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Result&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;User&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    validateName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input.name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    validateEmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input.email&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    validateAge&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input.age&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;/span&gt;&lt;span&gt;.mapN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;User&lt;/span&gt;&lt;span&gt;.apply&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;@&lt;/span&gt;&lt;span&gt;main &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; runValidation&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Unit&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  val&lt;/span&gt;&lt;span&gt; goodInput&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; RawInput&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Alice&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;alice@example.com&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  val&lt;/span&gt;&lt;span&gt; badInput&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; RawInput&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;no-at-symbol&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;-5&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Valid input result:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;validateUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;goodInput&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Invalid input result:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;validateUser&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;badInput&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Outputs:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Valid input result:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Valid(User(Alice,alice@example.com,30))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Invalid input result:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Invalid(Chain(Name cannot be empty, Email must contain &amp;#39;@&amp;#39;, Age must be non-negative))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If name and email both fail, you get both errors, not just the first.
That’s the kind of robustness you want in real-world parsing, form validation, or config loading.
And all that without much boilerplate code.&lt;/p&gt;
&lt;p&gt;It is important to note, though, that &lt;code&gt;Validated&lt;/code&gt; &lt;a class=&quot;external&quot; href=&quot;https://typelevel.org/cats/datatypes/validated.html#of-flatmaps-and-eithers&quot; target=&quot;_blank&quot;&gt;is not a monad&lt;/a&gt; due to the accumulation of errors.&lt;/p&gt;
&lt;h2 id=&quot;effect-systems-haskell&quot;&gt;Effect Systems (Haskell++)&lt;/h2&gt;
&lt;p&gt;Effect systems bring to error handling – and to side effects more broadly – more powerful tools.
Rather than wrapping all effects in a monad like &lt;code&gt;IO&lt;/code&gt;, these systems explicitly track them in the type signature.
This means you can determine exactly which effects a function might perform (I/O, logging, error handling, state, etc.) directly from its type – not by convention, but enforced by the compiler.&lt;/p&gt;
&lt;p&gt;The &lt;a class=&quot;external&quot; href=&quot;https://hackage.haskell.org/package/polysemy&quot; target=&quot;_blank&quot;&gt;polysemy&lt;/a&gt; library in Haskell is a good example of such a system.
Here’s a simple example extracted from &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/exercises_api&quot; target=&quot;_blank&quot;&gt;willGuimont/exercises_api&lt;/a&gt;.
It combines state, logging, and error handling, all visible in the type signature.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Error type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExerciseError&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; ExerciseNotFound&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExerciseId&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; And other types of errors...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  deriving&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Show&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Eq&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Generic&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Persistence effect to query exercices&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Persistence&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; m&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Exercise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;  GetExerciseById&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExerciseId&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Persistence&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; m&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Maybe&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Exercise&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; And other effects...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;makeSem &amp;#39;&amp;#39;Persistence&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;runPersistenceOnIO&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Member&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Embed&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Sem&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Persistence&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Sem&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;runPersistenceOnIO &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  interpret &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    \&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;      --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Exercise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;      GetExerciseById&lt;/span&gt;&lt;span&gt; eId &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; embed &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; .&lt;/span&gt;&lt;span&gt; runSqlite sqliteDbName &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        let&lt;/span&gt;&lt;span&gt; key &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; toSqlKey eId &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; DbExerciseId&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        eDb &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; getEntity key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        pure &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; toExercise &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt;&lt;span&gt; eDb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; and others...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Example function using persistence&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;getExercise&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Members&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Persistence&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Logging&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Error&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExerciseError&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ExerciseId&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Sem&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Exercise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;getExercise eId &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  logInfo &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;getExercise&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  getExerciseById eId &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; \&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Nothing&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; throw &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; ExerciseNotFound&lt;/span&gt;&lt;span&gt; eId &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Error if the exercise is not found&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    Just&lt;/span&gt;&lt;span&gt; e &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt; pure e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;formatNotFoundError&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Show&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; BLU.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;ByteString&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Either&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; ServerError&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;formatNotFoundError entityType eId  &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Left&lt;/span&gt;&lt;span&gt; err404 &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;errBody&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; LBS.&lt;/span&gt;&lt;span&gt;concat &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;entityType &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; BLU.&lt;/span&gt;&lt;span&gt;fromString &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; show eId&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; does not exist&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;createApp&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;createApp &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  loggerStdout &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; fst &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;$&amp;gt;&lt;/span&gt;&lt;span&gt; newFastLogger &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;LogStdout&lt;/span&gt;&lt;span&gt; defaultBufSize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  _ &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; runM &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; runPersistenceManagingOnIO executeMigration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  _ &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; runM &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; runLoggingOnLogger loggerStdout &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span&gt; logInfo &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Starting server on port &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&amp;gt;&lt;/span&gt;&lt;span&gt; pack &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;show port&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  return &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;serve exerciseApi &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; hoistServer exerciseApi &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;interpretServer&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;`&lt;/span&gt;&lt;span&gt; loggerStdout&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; server&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    interpretServer sem loggerStdout &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      sem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt; runPersistenceOnIO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt; runLoggingOnLogger loggerStdout&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt; runError &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;ExerciseError&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Transforms thrown ExerciceError into Either ExerciseError a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt; runM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        &amp;amp;&lt;/span&gt;&lt;span&gt; exerciseErrorHandler&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Convert Either ExerciseError a into a Servant error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    exerciseErrorHandler &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Handler&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; .&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; ExceptT&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; .&lt;/span&gt;&lt;span&gt; fmap handleExerciseErrors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    handleExerciseErrors &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Left&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;ExerciseNotFound&lt;/span&gt;&lt;span&gt; eId&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; formatNotFoundError &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Exercise&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; eId&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    --&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; and other errors&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    handleExerciseErrors &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;Right&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Right&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Port&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;port &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 8080&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;startServer&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;startServer &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  app &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span&gt; createApp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  withStdoutLogger &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; \&lt;/span&gt;&lt;span&gt;appLogger &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    let&lt;/span&gt;&lt;span&gt; settings &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; setPort port &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; setLogger appLogger defaultSettings&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    runSettings settings &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;$&lt;/span&gt;&lt;span&gt; simpleCors app&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes exception handling more explicit and modular – you can define and run separate interpreters for each type of error, allowing each subsystem to handle its own failures independently.&lt;/p&gt;
&lt;p&gt;This approach tickles my functional programming itch, but it comes with complexity.
It is very elegant to think of your program as a series of composable effects that are then interpreted at the edges of your system.
More complex operations can be decomposed into smaller effects before being interpreted.
In some ways, it feels like a sort of interpreter that compiles your source code into a simpler bytecode (core language primitive operations) that is then executed.
However, the learning curve is steep, and the abstraction overhead can be significant for small to medium projects.&lt;/p&gt;
&lt;h2 id=&quot;resuming-the-conversation-ocaml-koka-effekt&quot;&gt;Resuming the Conversation (OCaml, Koka, Effekt)&lt;/h2&gt;
&lt;p&gt;Polysemy’s interpreters live in Haskell’s type system, but effects can be a language feature.
OCaml 5, Koka, and Effekt provide algebraic effects with handlers, and crucially, a handler can resume the suspended computation, not just abort it.
Where &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; only ever unwinds, an effect handler holds a continuation it can call to pick up exactly where the effect was performed.&lt;/p&gt;
&lt;p&gt;The real power shows up when you keep the computation fixed and swap only the handler.
Here, the pipeline is written once and knows nothing about how a division by zero is dealt with; two handlers impose two completely different policies on it:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;ocaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;Deep&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;(*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The effect carries the numerator, so the handler has something to decide with. &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Div_by_zero&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;t&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; divide&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; then&lt;/span&gt;&lt;span&gt; perform&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt;Div_by_zero&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; else&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; /&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;(*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; The computation. It does NOT know how divide-by-zero is handled. &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; pipeline&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; ()&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; divide&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   (*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5 &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; divide&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 7&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    (*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; performs Div_by_zero 7 &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; c&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; divide&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 20&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   (*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5 — runs only if b resumes &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;(*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Policy 1: resume, substituting the numerator as the result. &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; resume_with_numerator&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  match_with&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; ()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt;    {&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; retc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; v&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;    ;&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; exnc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; raise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;    ;&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; effc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;eff&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        match&lt;/span&gt;&lt;span&gt; eff&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; with&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Div_by_zero&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Some&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; continuation&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; continue&lt;/span&gt;&lt;span&gt; k&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; None&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;(*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Policy 2: abort the whole computation with a sentinel. &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Aborted&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; abort_on_zero&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  match_with&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; ()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt;    {&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; retc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; v&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; v&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;    ;&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; exnc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; raise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;    ;&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; effc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;eff&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Effect&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        match&lt;/span&gt;&lt;span&gt; eff&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; with&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Div_by_zero&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Some&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; continuation&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; raise&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; Aborted&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; None&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt; ()&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  (*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Same pipeline, two policies — only the handler differs. &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;  Printf&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;resume: %d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt; (&lt;/span&gt;&lt;span&gt;resume_with_numerator&lt;/span&gt;&lt;span&gt; pipeline&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-3&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-10 z-d-10&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  (*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5 + 7 + 5 = 17 &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  match&lt;/span&gt;&lt;span&gt; abort_on_zero&lt;/span&gt;&lt;span&gt; pipeline&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; with&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; n&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Printf&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;abort:  %d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  |&lt;/span&gt;&lt;span&gt; exception &lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-6&quot;&gt;Aborted&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; Printf&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;.&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;abort:  aborted&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the separation of concerns that exceptions can’t express.
&lt;code&gt;pipeline&lt;/code&gt; decides where a problem is raised; the handler decides what it means.
Under &lt;code&gt;resume_with_numerator&lt;/code&gt;, the handler calls &lt;code&gt;continue k 7&lt;/code&gt;, it resumes the suspended &lt;code&gt;divide 7 0&lt;/code&gt; in place, hands back &lt;code&gt;7&lt;/code&gt;, and execution flows on to &lt;code&gt;c&lt;/code&gt;, so the block completes and sums to &lt;code&gt;17&lt;/code&gt;.
Under abort_on_zero, the handler simply doesn’t call the continuation; it raises instead, discarding the rest of the computation, and &lt;code&gt;c&lt;/code&gt; never runs.
Same code, opposite outcomes, and the pipeline is none the wiser.&lt;/p&gt;
&lt;p&gt;That’s the leverage: with &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; the decision to abort is baked into the throwing code (once you throw, the frames are gone).
With effects, “abort” and “resume” are just two handlers you can choose between after the fact; abort is the special case where you decline to resume.
That resumption ability, recovering without unwinding, is the bridge to one of the oldest ideas in this whole post: Common Lisp’s conditions and restarts.&lt;/p&gt;
&lt;h2 id=&quot;terms-and-conditions-common-lisp&quot;&gt;Terms and Conditions (Common Lisp)&lt;/h2&gt;
&lt;p&gt;Most mechanisms here fuse three concerns into one act: signaling a problem, deciding how to recover, and performing the recovery all happen at the catch site, after the stack has already been torn down.
Common Lisp’s condition system, predating almost everything above, keeps them separate, and never unwinds until it’s good and ready.&lt;/p&gt;
&lt;p&gt;A condition is signaled deep in the stack.
Restarts are named recovery strategies defined at that same low level.
But the handler that chooses which restart to invoke sits high up – and it runs with the stack still intact, in the dynamic context of the signaling code.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;common-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;define-condition&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; divide-by-zero&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ((&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;numerator&lt;/span&gt;&lt;span&gt; :initarg&lt;/span&gt;&lt;span&gt; :numerator&lt;/span&gt;&lt;span&gt; :reader&lt;/span&gt;&lt;span&gt; numerator-of)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;defun&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt; (x y)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;restart-case&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;zerop&lt;/span&gt;&lt;span&gt; y)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span&gt;divide-by-zero &lt;/span&gt;&lt;span&gt;:numerator&lt;/span&gt;&lt;span&gt; x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;/&lt;/span&gt;&lt;span&gt; x y))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    ;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;; Recovery strategies, defined DOWN at the point of failure:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;use-value&lt;/span&gt;&lt;span&gt; (v) &lt;/span&gt;&lt;span&gt;:report&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Supply a replacement result.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; v)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (use-zero  ()  &lt;/span&gt;&lt;span&gt;:report&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Treat the result as 0.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;       0&lt;/span&gt;&lt;span&gt;)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;defun&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;e&lt;/span&gt;&lt;span&gt; ()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  ;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;; The policy, decided UP here - chosen without unwinding the stack:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;handler-bind&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ((divide-by-zero&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;lambda&lt;/span&gt;&lt;span&gt; (c)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;invoke-restart&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span&gt;use-value (numerator-of c)))))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;let&lt;/span&gt;&lt;span&gt; ((a (divide &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;))   &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (b (divide &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;))    &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; signals -&amp;gt; handler picks the use-value restart -&amp;gt; 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (c (divide &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;)))  &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5 -- still runs, because the restart resumed in place&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;+&lt;/span&gt;&lt;span&gt; a b c))))            &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5 + 7 + 5 = 17&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; t&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;result: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; (run-pipeline))  &lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; =&amp;gt; 17&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;code&gt;(divide 7 0)&lt;/code&gt; runs, divide does two things and stops: it signals a condition and publishes a menu of restarts (&lt;code&gt;use-value&lt;/code&gt;, &lt;code&gt;use-zero&lt;/code&gt;).
Signalling is not throwing: nothing unwinds, so &lt;code&gt;divide&lt;/code&gt;’s frame is still alive.
The matching handler-bind runs while the stack is frozen, reads the numerator off the condition, and calls &lt;code&gt;(invoke-restart &#39;use-value 7)&lt;/code&gt;.
That resumes divide in place with &lt;code&gt;7&lt;/code&gt;, so &lt;code&gt;c&lt;/code&gt; still runs, and the block sums to &lt;code&gt;17&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The whole idea is that one split: signal (where), restart (how), handler (which).
&lt;code&gt;divide&lt;/code&gt; provides the recovery mechanisms without choosing one; &lt;code&gt;run-pipeline&lt;/code&gt; chooses the policy without knowing how recovery works.
Swap the handler to &lt;code&gt;use-zero&lt;/code&gt;, and divisions by zero become &lt;code&gt;0&lt;/code&gt;; decline to restart, and you abort, all without touching divide.&lt;/p&gt;
&lt;p&gt;And because the restarts are just a published menu, if no handler matches, Lisp doesn’t crash; it drops into the debugger and offers those same restarts to a human, who can pick one and resume the live program.
Error handling, interactive recovery, and debugging are one mechanism.&lt;/p&gt;
&lt;p&gt;This is the most general model in the post: exceptions are just the degenerate case where the only restart is “unwind to the handler.”
It pairs naturally with Elixir’s “let it crash” as the opposite pole, where Erlang isolates failure and restarts a process; Lisp keeps the process alive and restarts a computation.&lt;/p&gt;
&lt;h2 id=&quot;trust-but-verify-assert-d&quot;&gt;Trust, but &lt;del&gt;verify&lt;/del&gt; &lt;code&gt;assert&lt;/code&gt; (D)&lt;/h2&gt;
&lt;p&gt;Some languages, like Eiffel and D, support design by contract, a declarative way to specify preconditions, postconditions, and invariants.
If a contract is violated, the program crashes or throws, often with minimal recovery.
They are often even omitted when compiled in release mode.
Thus, they are not, as the other techniques overviewed in this document, ways to validate user input or alternatives to exceptions.&lt;/p&gt;
&lt;p&gt;Design by contract is about catching programmer mistakes, not handling external failures.
If a function says “I expect a non-empty list,” and you give it an empty one, that’s not a runtime error to recover from – it’s a logic bug.
The contract makes that explicit.&lt;/p&gt;
&lt;p&gt;In contrast, exceptions, &lt;code&gt;Either&lt;/code&gt;, &lt;code&gt;Result&lt;/code&gt;, and &lt;code&gt;Validated&lt;/code&gt; are about handling real-world uncertainty: invalid input, missing files, network timeouts, and corrupted data.
These are expected failures that your program should handle gracefully.&lt;/p&gt;
&lt;p&gt;Here’s a simple example of contract programming using D:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;d&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span&gt; std.stdio&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; BankAccount&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    private&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        string&lt;/span&gt;&lt;span&gt; owner&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        double&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    this&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;string&lt;/span&gt;&lt;span&gt; owner&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span&gt; initialDeposit&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    in&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;owner.length&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Owner name cannot be empty&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;initialDeposit&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Initial deposit must be non&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;negative&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    do&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        this&lt;/span&gt;&lt;span&gt;.owner&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; owner&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        this&lt;/span&gt;&lt;span&gt;.balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; initialDeposit&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    invariant()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Invariant failed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; balance must be non&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;negative&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; deposit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;double&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    in&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;amount&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Deposit amount must be positive&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    do&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        double&lt;/span&gt;&lt;span&gt; oldBalance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;=&lt;/span&gt;&lt;span&gt; oldBalance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Postcondition failed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; balance didn&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;t increase&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; withdraw&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;double&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    in&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;amount&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Withdrawal amount must be positive&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;amount&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Insufficient funds&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    do&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        double&lt;/span&gt;&lt;span&gt; oldBalance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        assert(&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span&gt; oldBalance&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Postcondition failed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; balance didn&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;t decrease&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; getBalance&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; const&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    string&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; getOwner&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; const&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; owner&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    auto&lt;/span&gt;&lt;span&gt; acc&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; BankAccount&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Alice&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1000.0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    acc.deposit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;500.0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    acc.withdraw&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;200.0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    writeln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Owner&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; acc.getOwner&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    writeln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Balance&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; acc.getBalance&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    // Uncomment to test contract violations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    // acc.withdraw(2000); // Insufficient funds&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    // acc.deposit(-100);  // Negative deposit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    // auto bad = BankAccount(&amp;quot;&amp;quot;, -10); // Invalid initial values&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Contracts in D  –  namely &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;out&lt;/code&gt;, and &lt;code&gt;invariant&lt;/code&gt; blocks  -  act like free unit tests embedded directly within your code.
They document and verify the intended behaviour of functions and invariants of types, automatically checked at runtime in debug builds.
For instance, a precondition on &lt;code&gt;withdraw&lt;/code&gt; guarantees that the withdrawal amount is valid before the function runs, while a postcondition ensures the balance decreases.
Unlike traditional unit tests, which are often separate and may omit corner cases, contracts enforce correctness systematically and immediately during development, catching logic errors as soon as they are introduced.
They don’t replace unit tests entirely, but they eliminate many boilerplate checks, serving as a robust safety net and specification tool during implementation.&lt;/p&gt;
&lt;h2 id=&quot;let-it-go-crash-elixir&quot;&gt;Let It &lt;del&gt;Go&lt;/del&gt; Crash (Elixir)&lt;/h2&gt;
&lt;p&gt;Elixir (and its Erlang foundations) embraces a fundamentally different philosophy: don’t prevent all errors - expect them, isolate them, and recover from them.&lt;/p&gt;
&lt;p&gt;Instead of striving for defensive, error-free code at every level, Elixir leverages lightweight, isolated processes and robust supervision trees.
Each process operates independently.
When a failure occurs, it doesn’t propagate through shared memory or unwind a global stack.
The process simply crashes – and a supervisor decides what to do next.&lt;/p&gt;
&lt;p&gt;Here, errors are also values, represented as tagged tuples &lt;code&gt;{:ok, value}&lt;/code&gt; and &lt;code&gt;{:error, reason}&lt;/code&gt;.
Functions return these tuples, and you pattern match on them to handle success and failure cases explicitly.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; do_something&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;ok&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    next_step&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;error&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; reason&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    handle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;reason&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  _&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Catch-all for any other return value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;    IO&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;puts&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Unexpected result&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This design makes fault tolerance an architectural feature, not an implementation detail.
Pattern matching ensures that error handling remains explicit and readable.
Elixir’s paradigm forces you to think about the not-so-happy path from the beginning.
Every function that returns &lt;code&gt;:ok&lt;/code&gt; or &lt;code&gt;:error&lt;/code&gt; reminds you that failure is part of the domain.
You can’t ignore it – you have to model it.&lt;/p&gt;
&lt;p&gt;Unlike Go, where the programmer is responsible for inspecting and propagating every error manually, Elixir encourages you to crash early and let the system self-heal.
Resilience is not patched in – it’s built in.&lt;/p&gt;
&lt;h2 id=&quot;conclusion-errors-are-the-norm-not-the-exception&quot;&gt;Conclusion: Errors Are the Norm, Not the Exception&lt;/h2&gt;
&lt;p&gt;There is no perfect model.
But there are better tradeoffs.&lt;/p&gt;
&lt;p&gt;Every meaningful computation—every I/O operation, API call, database query – can fail.
Yet most programming languages treat error handling as a second-class concern: either overly verbose, dangerously ignorable, or both.
The happy path is (almost) always easy to write.
The hard part is everything else.&lt;/p&gt;
&lt;p&gt;There’s &lt;a class=&quot;external&quot; href=&quot;https://worrydream.com/refs/Brooks_1986_-_No_Silver_Bullet.pdf&quot; target=&quot;_blank&quot;&gt;no silver bullet&lt;/a&gt;.
But there are better tradeoffs – depending on your constraints, goals, and team culture.
Personally, my thoughts on error handling have evolved over time.
In the past, I leaned towards leveraging the type system to make errors explicit, like Haskell and Rust.
But lately, I’ve come to appreciate the simplicity of Odin’s approach, which balances explicitness with conciseness and Elixir’s philosophy of embracing failure as a first-class concern rather than defensive coding.&lt;/p&gt;
&lt;p&gt;Errors are the norm, not the exception.
The best systems are those that make handling them not only simple, but obvious.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>3D-Printed AprilTags That Withstand the Real World</title>
        <published>2025-05-27T00:00:00+00:00</published>
        <updated>2025-05-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/cube/"/>
        <id>https://willguimont.com/blog/cube/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/cube/">&lt;p&gt;In many robotics projects, AprilTags are indispensable. But the standard approach — printing on paper, gluing to cardboard — doesn’t hold up outside the lab.
Tags peel, warp, fade, and disintegrate when exposed to handling, humidity, or rough environments.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Tracker3D.jl&lt;/code&gt; solves this.
It generates 3D-printable AprilTags engineered for the real world: flat, durable, weather-resistant, and easy to integrate directly into enclosures or mounts.
Whether you’re field-testing robots or deploying long-term vision systems, these tags won’t fail you.&lt;/p&gt;
&lt;p&gt;Why &lt;code&gt;Tracker3D.jl&lt;/code&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🚫 No more flimsy paper or fragile adhesives&lt;/li&gt;
&lt;li&gt;✅ Always flat, robust, and easy to embed&lt;/li&gt;
&lt;li&gt;☁️ Weatherproof and reusable&lt;/li&gt;
&lt;li&gt;🧩 Ideal for industrial, outdoor, or educational setups&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/Tracker3D.jl&quot; target=&quot;_blank&quot;&gt;willGuimont/Tracker3D.jl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ready-to-print tags:&lt;/strong&gt; &lt;a class=&quot;external&quot; href=&quot;https://www.thingiverse.com/thing:6983741&quot; target=&quot;_blank&quot;&gt;Thingiverse&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Citizen Science Data for UAV Image Analysis</title>
        <published>2025-04-09T00:00:00+00:00</published>
        <updated>2025-04-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/citizen-sciences/"/>
        <id>https://willguimont.com/blog/citizen-sciences/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/citizen-sciences/">&lt;p&gt;Co-authored paper in MDPI: &lt;a class=&quot;external&quot; href=&quot;https://www.mdpi.com/1999-4907/16/4/616&quot; target=&quot;_blank&quot;&gt;Using Citizen Science Data as Pre-Training for Semantic Segmentation of High-Resolution UAV Images for Natural Forests Post-Disturbance Assessment&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ability to monitor forest areas after disturbances is key to ensure their regrowth. Problematic situations that are detected can then be addressed with targeted regeneration efforts. However, achieving this with automated photo interpretation is problematic, as training such systems requires large amounts of labeled data. To this effect, we leverage citizen science data (iNaturalist) to alleviate this issue. More precisely, we seek to generate pre-training data from a classifier trained on selected exemplars. This is accomplished by using a moving-window approach on carefully gathered low-altitude images with an Unmanned Aerial Vehicle (UAV), WilDReF-Q (Wild Drone Regrowth Forest—Quebec) dataset, to generate high-quality pseudo-labels. To generate accurate pseudo-labels, the predictions of our classifier for each window are integrated using a majority voting approach. Our results indicate that pre-training a semantic segmentation network on over 140,000 auto-labeled images yields an $F1$ score of 43.74% over 24 different classes, on a separate ground truth dataset. In comparison, using only labeled images yields a score of 32.45%, while fine-tuning the pre-trained network only yields marginal improvements (46.76%). Importantly, we demonstrate that our approach is able to benefit from more unlabeled images, opening the door for learning at scale. We also optimized the hyperparameters for pseudo-labeling, including the number of predictions assigned to each pixel in the majority voting process. Overall, this demonstrates that an auto-labeling approach can greatly reduce the development cost of plant identification in regeneration regions, based on UAV imagery.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Free 3D Scanning using iOS devices</title>
        <published>2025-03-03T00:00:00+00:00</published>
        <updated>2025-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/3d-scanning/"/>
        <id>https://willguimont.com/blog/3d-scanning/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/3d-scanning/">&lt;p&gt;The current state of 3D scanning apps on the App Store is a bit disappointing.
Most of them are either paid or have a subscription model.
Not doing enough scanning to justify the cost, I decided to look for a free alternative.&lt;/p&gt;
&lt;p&gt;I was pleasantly surprised to find that Apple’s own &lt;a class=&quot;external&quot; href=&quot;https://developer.apple.com/documentation/realitykit&quot; target=&quot;_blank&quot;&gt;RealityKit&lt;/a&gt; framework has a sample app for exactly this purpose.
&lt;a class=&quot;external&quot; href=&quot;https://developer.apple.com/documentation/realitykit/scanning-objects-using-object-capture&quot; target=&quot;_blank&quot;&gt;Scanning objects using Object Capture&lt;/a&gt; is a free app that lets you scan objects using your iOS device.&lt;/p&gt;
&lt;p&gt;To get started, install Xcode and download the sample app from the &lt;a class=&quot;external&quot; href=&quot;https://developer.apple.com/documentation/realitykit/scanning-objects-using-object-capture&quot; target=&quot;_blank&quot;&gt;Object Capture sample code&lt;/a&gt;.
Build and run the app on your iOS device, and follow the instructions to scan an object.&lt;/p&gt;
&lt;p&gt;Once done, you can export the scanned object as a USDZ file or save all the images to your device.
The images can then be used with &lt;a class=&quot;external&quot; href=&quot;https://developer.apple.com/documentation/realitykit/building-an-object-reconstruction-app&quot; target=&quot;_blank&quot;&gt;Building an object reconstruction app&lt;/a&gt; to create a high-quality 3D model.&lt;/p&gt;
&lt;p&gt;Since USDZ is not a widely supported format in the 3D printing world or CAD software, you can convert it to other formats using tools like &lt;a class=&quot;external&quot; href=&quot;https://www.blender.org/&quot; target=&quot;_blank&quot;&gt;Blender&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terrain Classification for Boreal Forests</title>
        <published>2024-09-10T00:00:00+00:00</published>
        <updated>2024-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/borealtc/"/>
        <id>https://willguimont.com/blog/borealtc/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/borealtc/">&lt;p&gt;Co-authored paper at IROS 2024: &lt;a class=&quot;external&quot; href=&quot;https://norlab-ulaval.github.io/BorealTC/&quot; target=&quot;_blank&quot;&gt;Proprioception Is All You Need: Terrain Classification for Boreal Forests&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Recent works in field robotics highlighted the importance of resiliency against different types of terrains. Boreal forests, in particular, are home to many mobility-impeding terrains that should be considered for off-road autonomous navigation. Also, being one of the largest land biomes on Earth, boreal forests are an area where autonomous vehicles are expected to become increasingly common. In this paper, we address the issue of classifying boreal terrains by introducing BorealTC, a publicly available dataset for proprioceptive-based terrain classification (TC). Recorded with a Husky A200, our dataset contains 116 min of Inertial Measurement Unit (IMU), motor current, and wheel odometry data, focusing on typical boreal forest terrains, notably snow, ice, and silty loam. Combining our dataset with another dataset from the literature, we evaluate both a Convolutional Neural Network (CNN) and the novel state space model (SSM)-based Mamba architecture on a TC task. We show that while CNN outperforms Mamba on each separate dataset, Mamba achieves greater accuracy when trained on a combination of both. In addition, we demonstrate that Mamba’s learning capacity is greater than a CNN for increasing amounts of data. We show that the combination of two TC datasets yields a latent space that can be interpreted with the properties of the terrains. We also discuss the implications of merging datasets on classification. Our source code and dataset are &lt;a class=&quot;external&quot; href=&quot;https://github.com/norlab-ulaval/BorealTC&quot; target=&quot;_blank&quot;&gt;publicly available online&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fix Obsidian Broken Graph View</title>
        <published>2024-07-14T00:00:00+00:00</published>
        <updated>2024-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/obsidian-broken-graph/"/>
        <id>https://willguimont.com/blog/obsidian-broken-graph/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/obsidian-broken-graph/">&lt;p&gt;If the Graph View in Obsidian is broken after an update, you can fix it by following these steps:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Close Obsidian&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; ~/.config/obsidian&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;rf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Cache&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; Code&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\ &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Cache&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; DawnCache&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; GPUCache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Reopen Obsidian&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cite website Bookmarklet</title>
        <published>2024-06-08T00:00:00+00:00</published>
        <updated>2024-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/citeshortcut/"/>
        <id>https://willguimont.com/blog/citeshortcut/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/citeshortcut/">&lt;p&gt;To automatically cite a website in &lt;a class=&quot;external&quot; href=&quot;https://www.bibme.org&quot; target=&quot;_blank&quot;&gt;bibme.org&lt;/a&gt;, add the following bookmarklet to your bookmarks bar:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;javascript&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;void&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;location&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;https://www.bibme.org/apa/website-citation/search?q=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;location&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;href&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clicking the bookmarklet will open the current page in &lt;a class=&quot;external&quot; href=&quot;https://www.bibme.org&quot; target=&quot;_blank&quot;&gt;bibme.org&lt;/a&gt;’s citation generator.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Benchmarking of Real-Time Object Detection Models</title>
        <published>2024-06-05T00:00:00+00:00</published>
        <updated>2024-06-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/det-bench/"/>
        <id>https://willguimont.com/blog/det-bench/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/det-bench/">&lt;p&gt;Published a paper to ArXiv: &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/2405.06911&quot; target=&quot;_blank&quot;&gt;Replication Study and Benchmarking of Real-Time Object Detection Models&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This work examines the reproducibility and benchmarking of state-of-the-art real-time object detection models. As object detection models are often used in real-world contexts, such as robotics, where inference time is paramount, simply measuring models’ accuracy is not enough to compare them. We thus compare a large variety of object detection models’ accuracy and inference speed on multiple graphics cards. In addition to this large benchmarking attempt, we also reproduce the following models from scratch using PyTorch on the MS COCO 2017 dataset: DETR, RTMDet, ViTDet and YOLOv7. More importantly, we propose a unified training and evaluation pipeline, based on MMDetection’s features, to better compare models. Our implementation of DETR and ViTDet could not achieve accuracy or speed performances comparable to what is declared in the original papers. On the other hand, reproduced RTMDet and YOLOv7 could match such performances. Studied papers are also found to be generally lacking for reproducibility purposes. As for MMDetection pretrained models, speed performances are severely reduced with limited computing resources (larger, more accurate models even more so). Moreover, results exhibit a strong trade-off between accuracy and speed, prevailed by anchor-free models - notably RTMDet or YOLOx models. The code used is this paper and all the experiments is available in the repository at &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/segdet_mlcr2024&quot; target=&quot;_blank&quot;&gt;this https URL&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>RandAugment</title>
        <published>2024-04-03T00:00:00+00:00</published>
        <updated>2024-04-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/randaugment/"/>
        <id>https://willguimont.com/blog/randaugment/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/randaugment/">&lt;p&gt;Presentation made for the course &lt;a class=&quot;external&quot; href=&quot;https://www.ulaval.ca/etudes/cours/gif-7010-avancees-en-apprentissage-automatique&quot; target=&quot;_blank&quot;&gt;GIF-7010: Avancées en apprentissage automatique&lt;/a&gt; at Université Laval on &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/1909.13719&quot; target=&quot;_blank&quot;&gt;RandAugment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are the slides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;RandAugment.pptx&quot; target=&quot;_blank&quot;&gt;RandAugment.pptx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;RandAugment.pdf&quot; target=&quot;_blank&quot;&gt;RandAugment.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sync Obsidian vaults to Android using Git</title>
        <published>2024-03-25T00:00:00+00:00</published>
        <updated>2024-03-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/obsidian-android-alternative/"/>
        <id>https://willguimont.com/blog/obsidian-android-alternative/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/obsidian-android-alternative/">&lt;p&gt;Updated way to sync your Obsidian vault to an Android phone using Git.
Previous method can be found &lt;a href=&quot;https://willguimont.com/blog/obsidian-android/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s the procedure to sync your &lt;a class=&quot;external&quot; href=&quot;https://obsidian.md/&quot; target=&quot;_blank&quot;&gt;Obsidian&lt;/a&gt; vault to an Android phone.&lt;/p&gt;
&lt;p&gt;First, you’ll have to run these commands on your computer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a SSH key using &lt;code&gt;ssh-keygen -f ~/obsidian-phone-key -t ed25519 -C &quot;your_email@example.com&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the public key (&lt;code&gt;~/obsidian-phone-key.pub&lt;/code&gt;) to your GitHub account&lt;/li&gt;
&lt;li&gt;Connect your phone to your computer and allow the computer to access phone data (e.g., using &lt;a rel=&quot;external&quot; href=&quot;https://localsend.org/&quot;&gt;LocalSend&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Copy the private key (&lt;code&gt;~/obsidian-phone-key&lt;/code&gt;) to your phone&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, on your phone:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a class=&quot;external&quot; href=&quot;https://f-droid.org/&quot; target=&quot;_blank&quot;&gt;F-Droid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open F-Droid and install &lt;a class=&quot;external&quot; href=&quot;https://f-droid.org/packages/com.termux/&quot; target=&quot;_blank&quot;&gt;Termux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In Termux, install &lt;code&gt;git&lt;/code&gt; using &lt;code&gt;pkg install git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In Termux install &lt;code&gt;termu-am&lt;/code&gt; using &lt;code&gt;pkg install termux-am&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Mount the phone storage using &lt;code&gt;termux-setup-storage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy your SSH key into &lt;code&gt;~/.ssh/&lt;/code&gt; using &lt;code&gt;cp ~/storage/shared/path/to/obsidian-phone-key ~/.ssh/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Follow &lt;a rel=&quot;external&quot; href=&quot;https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent&quot;&gt;these instructions to add the ssh key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Now go to the location you want to clone the repository (should be in &lt;code&gt;~/storage/shared/&lt;/code&gt; for Obsidian to have access) and clone it using &lt;code&gt;git clone git@github.com:username/repo.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You can now open Obsidian
&lt;ol&gt;
&lt;li&gt;Open folder as vault&lt;/li&gt;
&lt;li&gt;Browse to the repository you copied from your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Open F-Droid and install &lt;a class=&quot;external&quot; href=&quot;https://f-droid.org/packages/com.manichord.mgit/&quot; target=&quot;_blank&quot;&gt;MGit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;From the settings page of MGit, import the SSH key
&lt;ol&gt;
&lt;li&gt;SSH Keys&lt;/li&gt;
&lt;li&gt;Download button in the upper right corner&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;obsidian-phone-key&lt;/code&gt; you copied from your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Go back to the main menu of MGit, press the three dots in the upper right and press the &lt;code&gt;Import Repository&lt;/code&gt; button&lt;/li&gt;
&lt;li&gt;Browse to the repository you copied from your computer&lt;/li&gt;
&lt;li&gt;You should now be able to &lt;code&gt;pull&lt;/code&gt; from MGit&lt;/li&gt;
&lt;li&gt;Your Obsidian vault is now synced using Git!&lt;/li&gt;
&lt;li&gt;(Optional) If you want to also be able to manage the repository from Termux, run the command &lt;code&gt;git config --global --add safe.directory ~/storage/shared/path/to/repo&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Segment Anything</title>
        <published>2024-02-21T00:00:00+00:00</published>
        <updated>2024-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/segment-anything/"/>
        <id>https://willguimont.com/blog/segment-anything/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/segment-anything/">&lt;p&gt;Presentation made for the course &lt;a class=&quot;external&quot; href=&quot;https://www.ulaval.ca/etudes/cours/gif-7010-avancees-en-apprentissage-automatique&quot; target=&quot;_blank&quot;&gt;GIF-7010: Avancées en apprentissage automatique&lt;/a&gt; at Université Laval on &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/2304.02643&quot; target=&quot;_blank&quot;&gt;Segment Anything&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are the slides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;SegmentAnything.pptx&quot; target=&quot;_blank&quot;&gt;Segment Anything.pptx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;SegmentAnything.pdf&quot; target=&quot;_blank&quot;&gt;Segment Anything.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wayback Machine Bookmarklet</title>
        <published>2023-12-29T00:00:00+00:00</published>
        <updated>2023-12-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/wayback/"/>
        <id>https://willguimont.com/blog/wayback/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/wayback/">&lt;p&gt;To automatically open a website in the Wayback Machine, add the following bookmarklet to your bookmarks bar:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;javascript&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;void&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;location&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;https://web.archive.org/web/*/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;location&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;href&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clicking the bookmarklet will open the current page in the Wayback Machine.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ph.D. Proposal Passed</title>
        <published>2023-09-25T00:00:00+00:00</published>
        <updated>2023-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/phd-proposal-passed/"/>
        <id>https://willguimont.com/blog/phd-proposal-passed/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/phd-proposal-passed/">&lt;p&gt;Passed the Ph.D. proposal exam!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;phdProposal_williamGuimontMartin.pdf&quot; target=&quot;_blank&quot;&gt;Ph.D. Proposal Final Version&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ph.D. Proposal - A First Draft</title>
        <published>2023-09-25T00:00:00+00:00</published>
        <updated>2023-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/phd-proposal/"/>
        <id>https://willguimont.com/blog/phd-proposal/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/phd-proposal/">&lt;p&gt;This is my Ph.D. proposal. It is a work in progress: &lt;a href=&quot;phdProposal_williamGuimontMartin_v0.pdf&quot; target=&quot;_blank&quot;&gt;Ph.D. Proposal&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Random quotes about research</title>
        <published>2023-09-15T00:00:00+00:00</published>
        <updated>2023-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/research/"/>
        <id>https://willguimont.com/blog/research/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/research/">&lt;p&gt;A small collection of random quotes about research.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Research is what I’m doing when I don’t know what I’m doing.&lt;/p&gt;
&lt;p&gt;– Wernher von Braun&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;If it works in theory, it also works in practice. In theory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And some quotes from discussions with friends.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Research is like wandering through a maze in search of an knowledge. But you can’t see the walls, and you don’t know if you’re lost. So you just keep bumping into walls until you find the something.&lt;/p&gt;
&lt;p&gt;– A friend of mine&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where’s the box?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Let’s think outside of the box to solve this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A friend:&lt;/strong&gt; But there is no box to think outside of.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And a &lt;del&gt;poem&lt;/del&gt; joke about this video &lt;a class=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=rgiC8YfytDw&quot; target=&quot;_blank&quot;&gt;Socialism Is When The Government Does Stuff&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Science is when you know stuff.&lt;/p&gt;
&lt;p&gt;And it’s more sciencey the more stuff you know.&lt;/p&gt;
&lt;p&gt;And if you know a real lot of stuff, it’s a paper.&lt;/p&gt;
&lt;p&gt;– A friend of mine&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Atelier Bash et Docker</title>
        <published>2023-09-05T00:00:00+00:00</published>
        <updated>2023-09-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/bash-docker/"/>
        <id>https://willguimont.com/blog/bash-docker/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/bash-docker/">&lt;p&gt;Ces ateliers ont été conçus pour le département d’informatique et de génie logiciel de l’Université Laval.
Ils ont été donnés dans le cadre du cours IFT-2001 et GLO-2001 Systèmes d’exploitation.&lt;/p&gt;
&lt;h2 id=&quot;atelier-d-introduction-a-bash&quot;&gt;Atelier d’introduction à Bash&lt;/h2&gt;
&lt;p&gt;Ce premier atelier a pour but de vous familiariser avec le terminal et le langage de script Bash.
Vous apprendrez à utiliser les commandes de base de Bash et à écrire des scripts simples.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;AtelierBash.pdf&quot; target=&quot;_blank&quot;&gt;Énoncé Bash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;AtelierBashSolutionnaire.pdf&quot; target=&quot;_blank&quot;&gt;Solutionnaire Bash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://github.com/ulavalIFTGLOateliers/IFT2001-Scripting&quot; target=&quot;_blank&quot;&gt;Code source&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;atelier-d-introduction-a-docker&quot;&gt;Atelier d’introduction à Docker&lt;/h2&gt;
&lt;p&gt;Ce deuxième atelier a pour but de vous familiariser avec Docker.
Vous apprendrez à utiliser les commandes de base de Docker et à écrire des Dockerfile.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;AtelierDocker.pdf&quot; target=&quot;_blank&quot;&gt;Énoncé Docker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;AtelierDockerSolutionnaire.pdf&quot; target=&quot;_blank&quot;&gt;Solutionnaire Docker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://github.com/ulavalIFTGLOateliers/IFT2001-Docker&quot; target=&quot;_blank&quot;&gt;Code source&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MaskBEV</title>
        <published>2023-07-11T00:00:00+00:00</published>
        <updated>2023-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/maskbev/"/>
        <id>https://willguimont.com/blog/maskbev/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/maskbev/">&lt;p&gt;Accepted paper at IROS 2023: &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/2307.01864&quot; target=&quot;_blank&quot;&gt;MaskBEV: Joint Object Detection and Footprint Completion for Bird’s-eye View 3D Point Clouds&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Recent works in object detection in LiDAR point clouds mostly focus on predicting bounding boxes around objects. This prediction is commonly achieved using anchor-based or anchor-free detectors that predict bounding boxes, requiring significant explicit prior knowledge about the objects to work properly. To remedy these limitations, we propose MaskBEV, a bird’s-eye view (BEV) mask-based object detector neural architecture. MaskBEV predicts a set of BEV instance masks that represent the footprints of detected objects. Moreover, our approach allows object detection and footprint completion in a single pass. MaskBEV also reformulates the detection problem purely in terms of classification, doing away with regression usually done to predict bounding boxes. We evaluate the performance of MaskBEV on both SemanticKITTI and KITTI datasets while analyzing the architecture advantages and limitations.&lt;/p&gt;
&lt;/blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Synchronise Obsidian vaults to Android using Git</title>
        <published>2023-07-07T00:00:00+00:00</published>
        <updated>2023-07-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/obsidian-android/"/>
        <id>https://willguimont.com/blog/obsidian-android/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/obsidian-android/">&lt;p&gt;Here’s the procedure to sync your &lt;a class=&quot;external&quot; href=&quot;https://obsidian.md/&quot; target=&quot;_blank&quot;&gt;Obsidian&lt;/a&gt; vault to an Android phone.&lt;/p&gt;
&lt;p&gt;First, you’ll have to run these commands on your computer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a SSH key using &lt;code&gt;ssh-keygen -f ~/obsidian-phone-key -t ed25519 -C &quot;your_email@example.com&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the public key (&lt;code&gt;~/obsidian-phone-key.pub&lt;/code&gt;) to your GitHub account&lt;/li&gt;
&lt;li&gt;Connect your phone to your computer and allow the computer to access phone data&lt;/li&gt;
&lt;li&gt;Copy the private key (&lt;code&gt;~/obsidian-phone-key&lt;/code&gt;) to your phone&lt;/li&gt;
&lt;li&gt;Also copy your Obsidian vault, including the &lt;code&gt;.git&lt;/code&gt; folder&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, on your phone:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a class=&quot;external&quot; href=&quot;https://f-droid.org/&quot; target=&quot;_blank&quot;&gt;F-Droid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open F-Droid and install &lt;a class=&quot;external&quot; href=&quot;https://f-droid.org/packages/com.manichord.mgit/&quot; target=&quot;_blank&quot;&gt;MGit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;From the settings page of MGit, import the SSH key
&lt;ol&gt;
&lt;li&gt;SSH Keys&lt;/li&gt;
&lt;li&gt;Download button in the upper right corner&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;obsidian-phone-key&lt;/code&gt; you copied from your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Go back to the main menu of MGit, press the three dots in the upper right and press the &lt;code&gt;Import Repository&lt;/code&gt; button&lt;/li&gt;
&lt;li&gt;Browse to the repository you copied from your computer&lt;/li&gt;
&lt;li&gt;You should now be able to &lt;code&gt;pull&lt;/code&gt; from MGit&lt;/li&gt;
&lt;li&gt;You can now open Obsidian
&lt;ol&gt;
&lt;li&gt;Open folder as vault&lt;/li&gt;
&lt;li&gt;Browse to the repository you copied from your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Your Obsidian vault is now synced using Git!&lt;/li&gt;
&lt;/ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Learn Transformers</title>
        <published>2023-03-23T00:00:00+00:00</published>
        <updated>2023-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/transformers/"/>
        <id>https://willguimont.com/blog/transformers/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/transformers/">&lt;p&gt;Here’s a small library I made to explain the Transformer architecture in PyTorch: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/transformers&quot; target=&quot;_blank&quot;&gt;willGuimont/transformers&lt;/a&gt;.
The code is heavily commented and should be easy to follow.&lt;/p&gt;
&lt;p&gt;This repository also contains some popular transformer-based models, such as Vision Transformer.&lt;/p&gt;
&lt;p&gt;This was made while developping new practical exercises for &lt;a class=&quot;external&quot; href=&quot;https://github.com/ulaval-damas/glo4030-labs&quot; target=&quot;_blank&quot;&gt;GLO-7030 at Université Laval&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>torch_waymo</title>
        <published>2023-02-02T00:00:00+00:00</published>
        <updated>2023-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/torch-waymo/"/>
        <id>https://willguimont.com/blog/torch-waymo/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/torch-waymo/">&lt;p&gt;Here’s a small library I made to use the &lt;a class=&quot;external&quot; href=&quot;https://waymo.com/open/&quot; target=&quot;_blank&quot;&gt;Waymo Open Dataset&lt;/a&gt; in PyTorch, without any dependency to Tensorflow: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/torch_waymo&quot; target=&quot;_blank&quot;&gt;willGuimont/torch_waymo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s the corresponding PyPI package: &lt;a class=&quot;external&quot; href=&quot;https://pypi.org/project/torch-waymo/&quot; target=&quot;_blank&quot;&gt;torch-waymo&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Apprentissage profonds sur les nuages de points 3D</title>
        <published>2022-09-12T00:00:00+00:00</published>
        <updated>2022-09-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/nn-on-pc-ift-6001/"/>
        <id>https://willguimont.com/blog/nn-on-pc-ift-6001/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/nn-on-pc-ift-6001/">&lt;p&gt;Papier réalisé pour le cours IFT-6001 @ Université Laval sur l’apprentissage par réseaux de neurones profonds sur les nuages de points 3D: &lt;a href=&quot;ApprentissageParReseauxDeNeuronesProfondsSurLesNuagesDePoints3D.pdf&quot; target=&quot;_blank&quot;&gt;Apprentissage par réseaux de neurones profonds sur les nuages de points 3D&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>APIs using Haskell and polysemy</title>
        <published>2022-06-08T00:00:00+00:00</published>
        <updated>2022-06-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/api-haskell/"/>
        <id>https://willguimont.com/blog/api-haskell/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/api-haskell/">&lt;p&gt;Here’s a simple API in Haskell using Servant and Polysemy: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/status-checker&quot; target=&quot;_blank&quot;&gt;willGuimont/status-checker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And another one: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/exercises_api&quot; target=&quot;_blank&quot;&gt;willGuimont/exercises_api&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Point-BERT IFT-6001</title>
        <published>2022-04-28T00:00:00+00:00</published>
        <updated>2022-04-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/point-bert-ift-6001/"/>
        <id>https://willguimont.com/blog/point-bert-ift-6001/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/point-bert-ift-6001/">&lt;p&gt;Voici une présentation que j’ai donnée le 28 avril 2022 pour le cours &lt;a class=&quot;external&quot; href=&quot;https://www.ulaval.ca/etudes/cours/ift-6001-introduction-a-la-recherche-en-informatique-communication-et-methodologie&quot; target=&quot;_blank&quot;&gt;IFT-6001 Introduction à la recherche en informatique : communication et méthodologie&lt;/a&gt; à l’Université Laval sur &lt;a class=&quot;external&quot; href=&quot;https://arxiv.org/abs/2111.14819&quot; target=&quot;_blank&quot;&gt;Point-BERT&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Voici les diapositives: &lt;a href=&quot;Point-BERT-IFT-6001.pdf&quot; target=&quot;_blank&quot;&gt;Point-BERT&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Voici l’enregistrement de la présentation:&lt;/p&gt;
&lt;iframe
	class=&quot;youtube-embed&quot;
	src=&quot;https://www.youtube-nocookie.com/embed/fywySHYLzW4&quot;
	allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
	referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;
&lt;/iframe&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Les tests en pratique</title>
        <published>2022-03-14T00:00:00+00:00</published>
        <updated>2022-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/tests-en-pratique/"/>
        <id>https://willguimont.com/blog/tests-en-pratique/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/tests-en-pratique/">&lt;p&gt;Tester, ce n’est pas seulement s’assurer que le code « marche ». C’est une démarche structurée pour réduire l’incertitude, détecter les erreurs tôt et donner confiance dans le système. Trop souvent, les tests sont vus comme une contrainte ou un ajout après coup. En pratique, bien utilisés, ils deviennent un outil de conception, de documentation et de robustesse.&lt;/p&gt;
&lt;p&gt;Ces slides présentent une approche concrète : les différents niveaux de tests (unitaires, intégration, système, acceptation), leurs rôles respectifs et les pièges fréquents. On y retrouve aussi des principes simples : un test doit être automatisé, indépendant et binaire. Il doit rester lisible, rapide et maintenable.&lt;/p&gt;
&lt;p&gt;À travers l’exemple d’UTournament, nous verrons comment structurer un test (Arrange-Act-Assert), comment limiter la fragilité et comment élargir la portée avec des approches comme le property-based testing. L’objectif est de montrer qu’avec un minimum de rigueur, les tests deviennent un allié au développement plutôt qu’un fardeau.&lt;/p&gt;
&lt;p&gt;Slides: &lt;a href=&quot;LesTestsEnPratique.pdf&quot; target=&quot;_blank&quot;&gt;Les tests en pratique&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding monads: Some resources</title>
        <published>2021-10-14T00:00:00+00:00</published>
        <updated>2021-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/monads/"/>
        <id>https://willguimont.com/blog/monads/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/monads/">&lt;p&gt;Instead of doing like everyone else and write a long-winded blog post about my &lt;code&gt;aha moment&lt;/code&gt; about monads, I’ll only link some useful resources about monads.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; href=&quot;https://cuddly-octo-palm-tree.com/posts/2021-04-11-monads-0/&quot; target=&quot;_blank&quot;&gt;Cuddly, Octo-Palm Tree’s series on monads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; href=&quot;http://www.jerf.org/iri/post/2958&quot; target=&quot;_blank&quot;&gt;Functors and Monads For People Who Have Read Too Many “Tutorials”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Transformers in Computer Vision</title>
        <published>2021-09-02T00:00:00+00:00</published>
        <updated>2021-09-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/transformers-in-cv/"/>
        <id>https://willguimont.com/blog/transformers-in-cv/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/transformers-in-cv/">&lt;p&gt;On September 2nd 2021, I gave a talk on transformer-based neural network architectures for computer vision. I gave the in University Laval’s &lt;a class=&quot;external&quot; href=&quot;https://norlab.ulaval.ca/&quot; target=&quot;_blank&quot;&gt;Norlab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here are the slides: &lt;a href=&quot;TransformersInComputerVision.pdf&quot; target=&quot;_blank&quot;&gt;Transformers in Computer Vision&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And here is the recording of the event:&lt;/p&gt;
&lt;iframe
	class=&quot;youtube-embed&quot;
	src=&quot;https://www.youtube-nocookie.com/embed/eaWXeXs8dh0&quot;
	allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
	referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;
&lt;/iframe&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inward and Outward Polymorphism</title>
        <published>2020-07-09T00:00:00+00:00</published>
        <updated>2020-07-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/polymorphism/"/>
        <id>https://willguimont.com/blog/polymorphism/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/polymorphism/">&lt;p&gt;I’ve recently become fond of Algebraic Data Types (ADT).&lt;/p&gt;
&lt;p&gt;Languages like Haskell and Rust allows you to model your domain in a concise way using ADT. What would take several classes (and files) in Java (Interface-Oriented Programming (IOP)) can be expressed in a couple of lines. This got me thinking about software architecture using those two.&lt;/p&gt;
&lt;p&gt;Both IOP and ADT have advantages and disadvantages.&lt;/p&gt;
&lt;p&gt;ADT is a lot more concise but requires to use pattern-matching. Adding a new ADT type would then mean that you’ll have to add a case to every function matching on the type. Whereas adding a new function acting on an ADT is easy, you simply need to write the function.&lt;/p&gt;
&lt;p&gt;For IOP on the other hand, adding a new implementation of the interface is easy. You simply implement the needed methods. Whereas adding a new function in the interface can quickly become expensive, you’ll have to add the method to every class implementing the interface. I’ll include Haskell’s type-classes and Rust’s traits as IOP.&lt;/p&gt;
&lt;p&gt;I discussed that compromise a bit more in &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/&quot;&gt;a previous post on abstract data types&lt;/a&gt;. Albeit about a different type of ADT (algebraic vs abstract), the post is still relevant to understand the difference between ADT and IOP.&lt;/p&gt;
&lt;p&gt;Here, I would like to discuss the software engineering aspect of using IOP and ADT when designing modules. I’ll introduce the concept of inward and outward polymorphism.&lt;/p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;To motivate the introduction of those concepts, let’s start with two small examples.&lt;/p&gt;
&lt;h3 id=&quot;algebraic-data-type&quot;&gt;Algebraic Data Type&lt;/h3&gt;
&lt;p&gt;You are charged to build a networking library in Rust. You want to support both IPv4 and IPv6. Each one represents addresses in different ways, IPv4 stores address using four 8 bits numbers, while IPv6 stores it as a string. Using Rust, and having recently read the &lt;a class=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html&quot; target=&quot;_blank&quot;&gt;Rust Book’s chapter on enums&lt;/a&gt;, you decide to declare them the following way:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; IpAddr&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    V4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; u8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    V6&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;String&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The user will call your functions, like &lt;code&gt;connect_to(ip: IpAddr)&lt;/code&gt;, using the polymorphic nature of &lt;code&gt;IpAddr&lt;/code&gt; to use either IPv4 or IPv6.&lt;/p&gt;
&lt;h3 id=&quot;interface-oriented-programming&quot;&gt;Interface-Oriented Programming&lt;/h3&gt;
&lt;p&gt;The next day, you are writing Java (poor you). You have to implement an application that provides support for plugins. So, you make an interface and write your code calling that interface. The user can then implement your interface with their code, and you can call their class since it implements your interface.&lt;/p&gt;
&lt;p&gt;So, your library calls the user’s code polymorphically.&lt;/p&gt;
&lt;h3 id=&quot;inward-or-outward&quot;&gt;Inward or Outward&lt;/h3&gt;
&lt;p&gt;In the last two examples, we can see two different uses of polymorphism. In the first example, the user called your library passing polymorphic data type, while the second one, the user implemented an interface so that your library would call their code.&lt;/p&gt;
&lt;p&gt;We can see that the flow of control is different in both cases. In the first example, the flow moves &lt;strong&gt;into&lt;/strong&gt; your code whereas, in the other example, the flow moves &lt;strong&gt;out of&lt;/strong&gt; your code.&lt;/p&gt;
&lt;p&gt;Based on the control flow, we can define &lt;strong&gt;inward polymorphism&lt;/strong&gt; as polymorphism used when the user calls your code. &lt;strong&gt;Outward polymorphism&lt;/strong&gt; would then be the use of polymorphism when your code is expected to call the user’s code.&lt;/p&gt;
&lt;p&gt;The examples were about libraries, but the same concept of inward or outward can be applied to modules.&lt;/p&gt;
&lt;h2 id=&quot;adt-or-iop&quot;&gt;ADT or IOP&lt;/h2&gt;
&lt;p&gt;Inward and outward polymorphism impose different types of constraints.&lt;/p&gt;
&lt;p&gt;When I need to write inward polymorphic code, I like to use the expressiveness of ADT. This can make the code elegant and concise.&lt;/p&gt;
&lt;p&gt;For outward polymorphism, you have to use IOP, so that both your module and the user’s code can communicate using a common interface.&lt;/p&gt;
&lt;p&gt;The choice between ADT and IOP can be really difficult and, as always, there is no &lt;em&gt;apply to all solutions&lt;/em&gt; in software architecture. The only real answer you’ll receive is “it depends”.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TossingBot</title>
        <published>2020-04-29T00:00:00+00:00</published>
        <updated>2020-04-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/tossingbot/"/>
        <id>https://willguimont.com/blog/tossingbot/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/tossingbot/">&lt;p&gt;This video presents TossingBot, a robotic arm that learns to throw arbitrary objects with residual physics.&lt;/p&gt;
&lt;p&gt;This video was made for the class &lt;em&gt;GLO-7030: Deep Learning&lt;/em&gt; at Université Laval.&lt;/p&gt;
&lt;iframe
	class=&quot;youtube-embed&quot;
	src=&quot;https://www.youtube-nocookie.com/embed/Icx6j3s_Pmc&quot;
	allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
	referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;
&lt;/iframe&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>On Learning</title>
        <published>2020-01-23T00:00:00+00:00</published>
        <updated>2020-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/on-learning/"/>
        <id>https://willguimont.com/blog/on-learning/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/on-learning/">&lt;p&gt;This is just some rambles on learning…&lt;/p&gt;
&lt;p&gt;I’m currently taking a class on deep neural networks. In the first class, we discussed multiple ways to have artificial intelligence systems.&lt;/p&gt;
&lt;p&gt;One way would be to code hand-designed programs to accomplish the task. &lt;code&gt;If&lt;/code&gt; something happens, &lt;code&gt;then&lt;/code&gt; the system does that, &lt;code&gt;else if&lt;/code&gt; this other thing happens, &lt;code&gt;then&lt;/code&gt; do this, &lt;code&gt;else if&lt;/code&gt;… We can achieve great things using rule-based programs, but on more complex tasks we would need a lot of cases to handle a lot of different cases.&lt;/p&gt;
&lt;p&gt;Another way would be to make the computer learn from the data. So we analyze the data, find features for the system to learn from, then use classical machine learning algorithms such as SVM. Again, for complex tasks, we may miss some useful feature to correctly learn from the data.&lt;/p&gt;
&lt;p&gt;The next step is to make the algorithm find features by itself. This is what neural networks do. Each layer of a deep neural network extract features for the higher layers to “reason” about. The classical example is a neural network that detects faces. The first layers might detect very simple patterns like edges. Higher up, a layer might detect corners and contours. Layers at the end of the network might detect complex object parts used by the final layer to classify the object. This is what is called representation learning, the artificial intelligence system finds a way of representing the data so that it is easy to solve the task.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Goodfellow-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/on-learning/#fn-Goodfellow&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;A good way of visualizing the different takes on artificial intelligence is from the book Deep Learning&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Goodfellow-2&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/on-learning/#fn-Goodfellow&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.
&lt;img src=&quot;https://willguimont.com/blog/on-learning/types.webp&quot; alt=&quot;Types of learning&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;dreyfus&quot;&gt;Dreyfus&lt;/h2&gt;
&lt;p&gt;When I learned about representation learning, it got me thinking about how we learn and the Dreyfus model&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Dreyfus-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/on-learning/#fn-Dreyfus&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;I think we can draw links between the Novice stage and rule-based systems. In this first stage of the Dreyfus model, the learner relies on rules to determine the action.&lt;/p&gt;
&lt;p&gt;Perhaps, there are other links between machine learning and the Dreyfus model.&lt;/p&gt;
&lt;h2 id=&quot;mental-representations&quot;&gt;Mental representations&lt;/h2&gt;
&lt;p&gt;In The Sciences of the artificial&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Simon-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/on-learning/#fn-Simon&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; from Herbert A. Simon, the author discusses the experience of A. de Groot and al. on chess perception. They showed chessboard with pieces in positions of real games for 5 seconds, then removed the pieces. Then they asked the subjects to put the pieces back in their position.&lt;/p&gt;
&lt;p&gt;As you might guess, somebody not accustomed to chess would have a pretty hard time to reconstruct the positions. For grandmasters and masters though, they were able to reconstruct the positions with almost no error!&lt;/p&gt;
&lt;p&gt;They then retried the experiment with &lt;em&gt;random&lt;/em&gt; piece positions. In that case, even grandmasters could not reconstruct the board.&lt;/p&gt;
&lt;p&gt;This shows that a grandmaster or a master built a good mental &lt;em&gt;representation&lt;/em&gt; of the game. Instead of memorizing all pieces, they memorized relations between pieces, which allow them to memorize them more easily.&lt;/p&gt;
&lt;p&gt;So, when I learned about representation learning, this reminded me of that particular example. Under the hood, a neural network &lt;em&gt;tries&lt;/em&gt; to do exactly what the grandmaster did, build a good representation of the problem to solve. Once the representation is built, a simple linear layer can solve the problem!&lt;/p&gt;
&lt;p&gt;I think this is what is really going on when humans learn. All the studying isn’t about memorizing facts or formulas, it’s about building a good mental representation that can be used to solve many problems. Once you understand basic algebra, you can use that framework to solve many problems you weren’t trained on.&lt;/p&gt;
&lt;p&gt;In a neural network, we are usually not concerned about memorizing all the input data, instead, we want to generalize to unseen examples.&lt;/p&gt;
&lt;p&gt;Perhaps we should tell students that they aren’t in school to memorize facts, but instead to build a toolbox of mental representations to help them in life. Our brain is a neural network that needs to be trained with great care!&lt;/p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-Goodfellow&quot;&gt;
&lt;p&gt;Goodfellow, Ian &amp;amp; Bengio, Yoshua &amp;amp; Courville, Aaron. Deep Learning. 2016. &lt;a href=&quot;https://willguimont.com/blog/on-learning/#fr-Goodfellow-1&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/on-learning/#fr-Goodfellow-2&quot;&gt;↩2&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Dreyfus&quot;&gt;
&lt;p&gt;Dreyfus, Stuart E. The Five-Stage Model of Adult Skill Acquisition. 2004. &lt;a href=&quot;https://willguimont.com/blog/on-learning/#fr-Dreyfus-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Simon&quot;&gt;
&lt;p&gt;Simon, Herbert A. The Sciences of the Artificial, 1969. &lt;a href=&quot;https://willguimont.com/blog/on-learning/#fr-Simon-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PROSAC</title>
        <published>2019-12-26T00:00:00+00:00</published>
        <updated>2019-12-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/prosac-algorithm/"/>
        <id>https://willguimont.com/blog/prosac-algorithm/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/prosac-algorithm/">&lt;p&gt;Recently, for a graduated mobile robotics class, I had to present a scientific paper. Loving algorithms, I decided to read &lt;a href=&quot;2005-Matching-with-PROSAC-progressive-sample-consensus.pdf&quot; target=&quot;_blank&quot;&gt;Matching with PROSAC - Progressive Sample Concensus&lt;/a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-ChumMatas-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/prosac-algorithm/#fn-ChumMatas&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, a paper presenting a variant of the popular RANSAC algorithm.&lt;/p&gt;
&lt;p&gt;This article will be a more detailed version of the presentation I gave for that class, the slides are &lt;a href=&quot;PROSAC.pdf&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. I won’t go into much of the mathematics, the details are in the paper. What I want to do with this article is to give you the intuition behind the algorithm more than writing a lot of equations.&lt;/p&gt;
&lt;p&gt;To supplement the presentation, I wrote an implementation of PROSAC in Python: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/PROSAC&quot; target=&quot;_blank&quot;&gt;willGuimont/PROSAC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before jumping in PROSAC, let’s just review RANSAC a bit.&lt;/p&gt;
&lt;h2 id=&quot;ransac-random-sample-consensus&quot;&gt;RANSAC - Random sample consensus&lt;/h2&gt;
&lt;p&gt;The main goal of RANSAC is to estimate a model from noised data with outliers.&lt;/p&gt;
&lt;p&gt;The basic idea is to randomly sample points from all points; fit a model on those randomly chosen points; then check if the model fits with the rest of the data.&lt;/p&gt;
&lt;p&gt;As you can see, the algorithm is relatively simple: sample, fit, check, rinse and repeat.&lt;/p&gt;
&lt;h3 id=&quot;pseudocode&quot;&gt;Pseudocode&lt;/h3&gt;
&lt;p&gt;Let $m$ be the minimum required number of points to fit a model. For a linear model in 2D, $m$ would be equal to $2$.&lt;/p&gt;
&lt;p&gt;Let $M$ a model to fit on the data.&lt;/p&gt;
&lt;p&gt;Let $\epsilon_{tol}$ be the maximum error between a point and the model to be considered an inlier.&lt;/p&gt;
&lt;p&gt;Let $\tau$ the fraction of inlier over the total number of points above which we are satisfied by the model. If we achieve that ratio, we stop early.&lt;/p&gt;
&lt;p&gt;Let $w$ be the probability of a given point to be an inlier. This is used to estimate the number of times we have to run RANSAC before finding a satisfying solution.&lt;/p&gt;
&lt;p&gt;Let $I$ be the set of inliers of maximal cardinality.&lt;/p&gt;
&lt;h4 id=&quot;ransac&quot;&gt;RANSAC&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Sample $m$ points&lt;/li&gt;
&lt;li&gt;Estimate a model $M$ from the $m$ sampled points&lt;/li&gt;
&lt;li&gt;Find the number of inliers with model $M$ with tolerance $\epsilon_{tol}$. If the number of inliers is greater than the number of previously found inliers, replace $I$ with the new set of inliers.&lt;/li&gt;
&lt;li&gt;If the fraction of inliers over the total number of points is greater than $\tau$, estimate the model with all inliers and stop.&lt;/li&gt;
&lt;li&gt;Repeat steps 1 to 4, a maximum of $\frac{1}{w^m}$ times&lt;/li&gt;
&lt;li&gt;After $\frac{1}{w^m}$ iterations, estimate the model with $I$.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;limitations-of-ransac&quot;&gt;Limitations of RANSAC&lt;/h3&gt;
&lt;p&gt;In the paper, they looked at estimating epipolar geometry from a pair of pictures.&lt;/p&gt;
&lt;div class=&quot;img-row&quot;&gt;
  &lt;img src=&quot;plant01.webp&quot; alt=&quot;Plant 1&quot; class=&quot;img-bg&quot; /&gt;
  &lt;img src=&quot;plant02.webp&quot; alt=&quot;Plant 2&quot; class=&quot;img-bg&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;With this pair of pictures, there is a lot of repetitive patterns on the floor and leaves, so there will be a lot of false matches. We have $m=7$ (epipolar geometry) and $w=9.2%$. The number of iteration of RANSAC is given by $\frac{1}{w^m}$. The estimated number of samples is over $8.43 \times 10^7$ !!! RANSAC would take a pretty long time before finding a good solution… That’s not realistic!&lt;/p&gt;
&lt;p&gt;When the model is complex and the number of correct points is low, RANSAC often takes very long before finding a satisfying solution. Let’s see if PROSAC can help.&lt;/p&gt;
&lt;h2 id=&quot;prosac-progressive-sample-consensus&quot;&gt;PROSAC - Progressive sample consensus&lt;/h2&gt;
&lt;p&gt;PROSAC adds the notion of quality to points with the basic assumption that points of greater quality have more chances to be correct.&lt;/p&gt;
&lt;p&gt;So, to make the algorithm quicker, the algorithm starts by trying to fit with points of greater quality first. Then we &lt;em&gt;progressively&lt;/em&gt; add points of lesser quality.&lt;/p&gt;
&lt;h3 id=&quot;intuition&quot;&gt;Intuition&lt;/h3&gt;
&lt;p&gt;Let’s say that the points in red are outliers. We would like to fit a model of complexity $m=2$ on those points.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;RANSAC&lt;/th&gt;
      &lt;th&gt;PROSAC&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_1$&lt;/i&gt;&lt;/td&gt;
      &lt;td&gt;&lt;i&gt;$p_2$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;i&gt;$p_2$&lt;/i&gt;&lt;/td&gt;
      &lt;td&gt;&lt;i&gt;$p_4$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_3$&lt;/i&gt;&lt;/td&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_6$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;i&gt;$p_4$&lt;/i&gt;&lt;/td&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_3$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_5$&lt;/i&gt;&lt;/td&gt;
      &lt;td&gt;&lt;i&gt;$p_5$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;i&gt;$p_6$&lt;/i&gt;&lt;/td&gt;
      &lt;td style=&quot;background-color:red;&quot;&gt;&lt;i&gt;$p_1$&lt;/i&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In RANSAC, we would be sampling $2$ points among all points, so we would have a probability of $\frac{3}{6}\cdot\frac{2}{5}=20%$. So, we would need, on average, $5$ samples before finding an uncontaminated sample.&lt;/p&gt;
&lt;p&gt;Whereas in PROSAC, we sort points by quality. The first points would be of higher quality. We would start sampling from the top 2 points, so we would sample $p_2$ and $p_4$, both of which are correct. In this case, we would have found an uncontaminated sample on the first draw.&lt;/p&gt;
&lt;p&gt;Even with this simple example, we can see the possible speedup.&lt;/p&gt;
&lt;h3 id=&quot;simplified-pseudo-code&quot;&gt;Simplified pseudo code&lt;/h3&gt;
&lt;h4 id=&quot;prosac&quot;&gt;PROSAC&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Sort points by quality (highest quality first)&lt;/li&gt;
&lt;li&gt;Consider the first $m$ points ($n\leftarrow m$)&lt;/li&gt;
&lt;li&gt;Sample $m$ points from the top $n$&lt;/li&gt;
&lt;li&gt;Fit the model&lt;/li&gt;
&lt;li&gt;Verify model with all points&lt;/li&gt;
&lt;li&gt;If the stopping criteria are not met, repeat steps 3 to 6, adding progressively points ($n\leftarrow n + 1$). Otherwise, fit the model on all inliers and terminate.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;quality&quot;&gt;Quality&lt;/h3&gt;
&lt;p&gt;There are multiple ways of defining quality. For feature matching on images, we could use the correlation of intensity around features on each image.&lt;/p&gt;
&lt;p&gt;In the paper, they mention Lowe’s distance. Lowe’s distance is the ratio between the most and second most similar matches.&lt;/p&gt;
&lt;p&gt;$s_1$: distance of the most similar match&lt;/p&gt;
&lt;p&gt;$s_2$: distance of the second most similar match&lt;/p&gt;
&lt;p&gt;$\text{distance} = \frac{s_1}{s_2}$&lt;/p&gt;
&lt;p&gt;This distance allows us to select the first points that are significantly better than any other. A match with a low Lowe’s distance has more chances of being correct.&lt;/p&gt;
&lt;p&gt;To define quality, we could inverse the ratio.&lt;/p&gt;
&lt;p&gt;$\text{quality} = \frac{s_2}{s_1}$&lt;/p&gt;
&lt;p&gt;You can use any metric you want, as long as the higher the quality is, the higher the probability of the point being correct is.&lt;/p&gt;
&lt;h3 id=&quot;fast-sampling&quot;&gt;Fast sampling&lt;/h3&gt;
&lt;p&gt;We could simply sample $m$ points from the top $n$ points, but that would be inefficient. We could sample multiple times the same set of points. So, to better explore the new possibles sets of $m$ points, we use the fact that when adding a new point $p_{n+1}$, we add a number $a$ of new samples. Each new sample contains the new point $p_{n+1}$ and $m-1$ from the $n$ first points.&lt;/p&gt;
&lt;p&gt;So, we can simply sample $a$ times, picking $p_{n+1}$ and $m-1$ points in the best $n$ points. That way, we ensure the quickly explore the possibles sets of $m$ points.&lt;/p&gt;
&lt;h3 id=&quot;end-criterion&quot;&gt;End criterion&lt;/h3&gt;
&lt;p&gt;The algorithm has two stopping criteria.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Non-random solution&lt;/li&gt;
&lt;li&gt;Maximality&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;non-random-solution&quot;&gt;Non-random solution&lt;/h3&gt;
&lt;p&gt;This criterion states that for a solution to be considered correct, it must have more inliers than what would randomly happen for an incorrect model.&lt;/p&gt;
&lt;p&gt;This is computed by estimating the probability that an incorrect model (fitted on a sample) is supported by a given point, not in the sample.&lt;/p&gt;
&lt;p&gt;The solution is considered non-random if the probability of having its number of inliers by chance is smaller than a certain threshold (usually 5%).&lt;/p&gt;
&lt;h3 id=&quot;maximality&quot;&gt;Maximality&lt;/h3&gt;
&lt;p&gt;We want to stop sampling when the chance of getting a model that fit more points is lower than a certain threshold. This is computed by looking at the odds of missing a set of inliers bigger than previously found after a number of draws. If this probability falls under a certain threshold (usually 5%), it is not worth continuing drawing and we terminate.&lt;/p&gt;
&lt;h2 id=&quot;code&quot;&gt;Code&lt;/h2&gt;
&lt;p&gt;Not having found any implementation of PROSAC online, I decided to post mine: &lt;a class=&quot;external&quot; href=&quot;https://github.com/willGuimont/PROSAC&quot; target=&quot;_blank&quot;&gt;willGuimont/PROSAC&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-ChumMatas&quot;&gt;
&lt;p&gt;Chum, Ondrej &amp;amp; Matas, Jiri. Matching with PROSAC - Progressive Sample Consensus. 2005. &lt;a href=&quot;https://willguimont.com/blog/prosac-algorithm/#fr-ChumMatas-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rubik&#39;s Cube Timer in Vue.js</title>
        <published>2019-06-23T00:00:00+00:00</published>
        <updated>2019-06-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/cube-timer/"/>
        <id>https://willguimont.com/blog/cube-timer/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/cube-timer/">&lt;p&gt;Here a simple Rubik’s Cube Timer I made in Vue.js&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://willguimont.github.io/cube_timer/&quot; target=&quot;_blank&quot;&gt;Link to the timer&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pomodoro Timer in Vue.js</title>
        <published>2019-03-20T00:00:00+00:00</published>
        <updated>2019-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/pomodoro-timer/"/>
        <id>https://willguimont.com/blog/pomodoro-timer/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/pomodoro-timer/">&lt;p&gt;Here a simple Pomodoro Timer I made in Vue.js.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://willguimont.github.io/Pomodoro/&quot; target=&quot;_blank&quot;&gt;Link to the timer&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercice conditions avec des photorésistances</title>
        <published>2019-03-03T00:00:00+00:00</published>
        <updated>2019-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/intro-photoresistance/"/>
        <id>https://willguimont.com/blog/intro-photoresistance/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/intro-photoresistance/">&lt;p&gt;Le but de cet exercice est de vous faire pratiquer les conditions et la boucle principale. De plus, vous aurez la chance de vous pratiquer à lire de la documentation.&lt;/p&gt;
&lt;h2 id=&quot;photoresistance&quot;&gt;Photorésistance&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-photoresistance/photores.webp&quot; alt=&quot;Photoresistance&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Une photorésistance est une composante électronique dont la résistance change selon la lumière qui l’éclaire. En bref, on peut regarder la tension aux bornes de la photorésistance.&lt;/p&gt;
&lt;h2 id=&quot;but-de-l-exercice&quot;&gt;But de l’exercice&lt;/h2&gt;
&lt;p&gt;Écrivez le code pour qu’une DEL s’allume lorsque la photorésistance est à l’ombre et éteindre la DEL lorsqu’elle est éclairée.&lt;/p&gt;
&lt;h2 id=&quot;liens-utiles&quot;&gt;Liens utiles&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/&quot; target=&quot;_blank&quot;&gt;analogRead&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; href=&quot;https://www.arduino.cc/en/Serial/Println&quot; target=&quot;_blank&quot;&gt;Serial pour afficher des informations à l’écran&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction aux conditions et à la boucle principale</title>
        <published>2019-03-02T00:00:00+00:00</published>
        <updated>2019-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/intro-conditions-arduino/"/>
        <id>https://willguimont.com/blog/intro-conditions-arduino/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/intro-conditions-arduino/">&lt;p&gt;Dans l’article précédant, nous avons vu comment faire clignoter une DEL 2 fois avant de s’éteindre. Maintenant, essayons de n’allumer la DEL que lorsqu’un bouton est enfoncé.&lt;/p&gt;
&lt;p&gt;En mots, on voudrait demander à l’Arduino:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Si le bouton est enfoncé
&lt;ol&gt;
&lt;li&gt;Allumer la DEL&lt;/li&gt;
&lt;li&gt;Attendre 3 secondes&lt;/li&gt;
&lt;li&gt;Éteindre la DEL&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Sinon
&lt;ol&gt;
&lt;li&gt;Laisser la DEL éteinte&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour ce faire, on branche un bouton de la façon suivante.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-conditions-arduino/bouton.webp&quot; alt=&quot;Bouton&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Les zig-zags représentent la résistance. Le symbole avec les deux points vides et le bout de fil représente un bouton ou un interrupteur.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-conditions-arduino/schema.webp&quot; alt=&quot;Schema&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;fonctions-de-bases&quot;&gt;Fonctions de bases&lt;/h2&gt;
&lt;h3 id=&quot;pin-en-lecture&quot;&gt;Pin en lecture&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; INPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette fonction permet de mettre la pin 2 en mode lecture.&lt;/p&gt;
&lt;h3 id=&quot;lecture-d-une-pin&quot;&gt;Lecture d’une pin&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;digitalRead&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette fonction retourne &lt;code&gt;HIGH&lt;/code&gt; si la tension est près de 5V sur la pin, ou &lt;code&gt;LOW&lt;/code&gt; si la tension est près de 0V.&lt;/p&gt;
&lt;h2 id=&quot;variables&quot;&gt;Variables&lt;/h2&gt;
&lt;p&gt;On aimerait pouvoir garder l’état du bouton pour pouvoir comparer sa valeur. Pour ce faire, on utilise des variables. Les variables sont comme des boîtes. On peut donner un nom à la boîte et mettre une valeur dedans.&lt;/p&gt;
&lt;p&gt;On peut demander à l’Arduino de nous créer une boîte avec un certain nom. On peut ensuite mettre une valeur à l’intérieur. Si on veut, on peut mettre une autre valeur dans la boîte par la suite.&lt;/p&gt;
&lt;h3 id=&quot;exemple&quot;&gt;Exemple&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; maVariable&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;maVariable&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;maVariable&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;maVariable&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; maVariable&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;int&lt;/code&gt; correspond au type de la variable. maVariable est donc de type int. int veut dire integer, c’est-à-dire entier en français. Un nombre entier sont des nombres comme 0, 1, 2, 3, 4, -3, 42 et -245. On a donc que maVariable peut contenir des nombres entiers.
On commence par donner la valeur 4 à maVariable.
Ensuite, on change cette valeur pour 2.
Ensuite, on met dans maVariable la valeur de maVariable + 1. Comme maVariable valait 2, on a que maVariable est maintenant 2 + 1, donc 3.&lt;/p&gt;
&lt;p&gt;On remarque que le signe = n’a pas le même sens qu’en mathématique. En mathématique, il serait faux de dire 2 = 3. Dans notre cas, on &lt;strong&gt;assigne&lt;/strong&gt; la valeur de droite à la variable de gauche.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remarque&lt;/strong&gt;: On aurait pu utiliser n’importe quel autre nom pour la variable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remarque&lt;/strong&gt;: D’autres opérateurs que l’addition (&lt;code&gt;+&lt;/code&gt;) sont définis, on peut faire des soustractions (&lt;code&gt;-&lt;/code&gt;), des multiplications (&lt;code&gt;*&lt;/code&gt;), des division (&lt;code&gt;/&lt;/code&gt;) et le modulo (&lt;code&gt;%&lt;/code&gt;). La division est toutefois tronqué avec des &lt;code&gt;int&lt;/code&gt; puisqu’un &lt;code&gt;int&lt;/code&gt; ne peut contenir que des nombres entiers. Le modulo calcule le reste de la division. Pour le moment, ne vous inquiétez pas avec cela.&lt;/p&gt;
&lt;h2 id=&quot;storer-l-etat-du-bouton-dans-une-variable&quot;&gt;Storer l’état du bouton dans une variable&lt;/h2&gt;
&lt;p&gt;Maintenant que nous savons ce qu’est une variable et comment récupérer l’état du bouton, sauvegardons l’état du bouton dans une variable.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; INPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;                 //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; pin 2 en lecture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; etatBouton&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; digitalRead&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; mettre l&amp;#39;etat du bouton dans etatBouton&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Voilà, nous avons l’état du bouton dans etatBouton.&lt;/p&gt;
&lt;h2 id=&quot;conditions&quot;&gt;Conditions&lt;/h2&gt;
&lt;p&gt;Maintenant que nous avons l’état du bouton dans une variable, on aimerait pouvoir réaliser certaines actions &lt;code&gt;SI&lt;/code&gt; une condition est vraie et d’autres &lt;code&gt;SINON&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Il existe en C++ une façon de réaliser des branchements conditionnelles, c’est-à-dire de faire certaines chose si la condition est vraie. En voici un exemple simple:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if veut dire si en français. Si on lit le code en français, on a:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Créer une variable nommée x et mettre 5 dedans&lt;/li&gt;
&lt;li&gt;Si x &lt;strong&gt;est plus petit que&lt;/strong&gt; 10 alors
&lt;ol&gt;
&lt;li&gt;On mets 10 dans x&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Comme 5 est plus petit que 10, on a que la valeur de x est maintenant 10.&lt;/p&gt;
&lt;p&gt;Voici un second exemple:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 42&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 42&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if veut dire si en français. Si on lit le code en français, on a:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Créer une variable nommée x et mettre 42 dedans&lt;/li&gt;
&lt;li&gt;Si x &lt;strong&gt;est égal à&lt;/strong&gt; 42 alors
&lt;ol&gt;
&lt;li&gt;On mets x - 10 dans x&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Comme x est bien égal à 42, on soustrait 10 à x. x a donc la valeur de 32 après l’exécution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remarque&lt;/strong&gt;: &lt;code&gt;==&lt;/code&gt; veut dire &lt;strong&gt;est égal à&lt;/strong&gt;, à ne pas confondre avec = qui veut dire assigner&lt;/p&gt;
&lt;p&gt;Disons que nous voulons réaliser ceci:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Soit un entier x qui vaut 39&lt;/li&gt;
&lt;li&gt;Si x == 42
&lt;ol&gt;
&lt;li&gt;x = x - 10&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Sinon
&lt;ol&gt;
&lt;li&gt;x = 0&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Comment pouvons nous traduire cela en code?
Il existe le mot-clef &lt;code&gt;else&lt;/code&gt; qui fait exactement cela.&lt;/p&gt;
&lt;p&gt;On aurait alors&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 39&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 42&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comme &lt;code&gt;x = 39&lt;/code&gt;, on a que la condition &lt;code&gt;x == 42&lt;/code&gt; est fausse, donc on n’exécute pas &lt;code&gt;x = x - 10&lt;/code&gt;, on entre ensuite dans le else où on assigne 0 à &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Maintenant que nous savons comment faire des conditions, on peut allumer la DEL si l’état du bouton est à HIGH.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; INPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;                 //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; pin 2 en lecture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; etatBouton&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; digitalRead&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; mettre l&amp;#39;etat du bouton dans etatBouton&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;etatBouton&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Si le bouton est a HIGH, on allume&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Sinon on laisse éteint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Il y a toutefois un petit problème, la lumière ne s’allume ou ne s’éteint qu’au démarrage de l’Arduino. Pour changer l’état de la lumière, il faut appuyer sur le bouton, puis redémarrer l’Arduino avec le bouton reset. Ce n’est pas très pratique. On aimerait que cela se fasse en tout temps.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-conditions-arduino/reset.webp&quot; alt=&quot;Reset&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pour palier à ce problème, on peut utiliser &lt;code&gt;loop&lt;/code&gt;. Comme son nom l’indique, &lt;code&gt;loop&lt;/code&gt; est une boucle, c’est-à-dire que le code dans cette fonction s’exécute continuellement après l’exécution de &lt;code&gt;setup&lt;/code&gt;. Déplaçons donc ce qui doit être exécuté plusieurs fois dans &lt;code&gt;loop&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; pin 13 en sortie&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; INPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; pin 2 en lecture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;  int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; etatBouton&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; digitalRead&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; mettre l&amp;#39;etat du bouton dans etatBouton&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;etatBouton&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Si le bouton est a HIGH, on allume&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Sinon on laisse éteint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On remarque que les &lt;code&gt;pinMode&lt;/code&gt; sont restés dans &lt;code&gt;setup&lt;/code&gt;. En effet, on ne veut réserver ces pin qu’une seule fois.&lt;/p&gt;
&lt;p&gt;Alors que le &lt;code&gt;if&lt;/code&gt; et &lt;code&gt;else&lt;/code&gt; a été déplacé dans loop, puisque l’on veut continuellement vérifier si le bouton est enfoncé.&lt;/p&gt;
&lt;p&gt;Maintenant, on a que la lumière s’allume et s’éteint dès que l’on appuie ou relâche le bouton.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction à Arduino</title>
        <published>2019-03-01T00:00:00+00:00</published>
        <updated>2019-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/intro-arduino/"/>
        <id>https://willguimont.com/blog/intro-arduino/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/intro-arduino/">&lt;h2 id=&quot;qu-est-ce-qu-arduino&quot;&gt;Qu’est-ce qu’Arduino&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-arduino/arduino.webp&quot; alt=&quot;Arduino&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The UNO is the best board to get started with electronics and coding. If this is your first experience tinkering with the platform, the UNO is the most robust board you can start playing with. The UNO is the most used and documented board of the whole Arduino family.&lt;/p&gt;
&lt;p&gt;– Site officiel Arduino.cc&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Il s’agit d’une carte comprenant un micro-contrôleur. La puce sur la carte est un petit ordinateur que l’on peut programmer. Il y a un port USB pour envoyer le code sur la puce et communiquer avec un ordinateur. Les pins sur le côté permettent d’avoir des entrées-sorties vers le vrai monde. On peut activer des lumières et des moteurs. On peut aussi lire les données envoyées par un capteur de distance à l’ultrason ou une photorésistante pour savoir s’il fait noir.&lt;/p&gt;
&lt;h2 id=&quot;introduction-a-la-programmation&quot;&gt;Introduction à la programmation&lt;/h2&gt;
&lt;p&gt;Un programme est une suite d’instructions exécutées les unes après les autres. On peut voir un programme comme une recette très précise pour réaliser des choses.&lt;/p&gt;
&lt;p&gt;On pourrait vouloir donner la suite d’étape pour faire un sandwich au beurre d’arachides. On pourrait essayer de demander à l’ordinateur de faire:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Faire un sandwich au beurre d’arachide&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Toutefois, l’ordinateur ne comprend pas comment faire cela. On devrait alors décrire les étapes de façon plus précises de façon à ce que l’ordinateur comprenne. On aurait alors:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ouvrir le sac contenant le pain&lt;/li&gt;
&lt;li&gt;Sortir une tranche de pain&lt;/li&gt;
&lt;li&gt;Sortir le pot de beurre d’arachide de l’armoire&lt;/li&gt;
&lt;li&gt;Sortir un couteau&lt;/li&gt;
&lt;li&gt;Ouvrir le pot&lt;/li&gt;
&lt;li&gt;Tartiner le pain avec le couteau&lt;/li&gt;
&lt;li&gt;Sortir une seconde tranche de pain&lt;/li&gt;
&lt;li&gt;Placer la tranche sur l’autre qui est déjà beurrée&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ouf ! C’est beaucoup d’étapes pour un simple sandwich.
Pour programmer un robot, c’est très semblable. On ne peut pas dire au robot de:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Avancer pendant 10 secondes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Il faut plutôt lui dire:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Actionne les moteurs&lt;/li&gt;
&lt;li&gt;Attendre 10 secondes&lt;/li&gt;
&lt;li&gt;Arrête les moteurs&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;del-et-arduino&quot;&gt;DEL et Arduino&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;DEL&lt;/code&gt;: &lt;code&gt;D&lt;/code&gt;iode &lt;code&gt;É&lt;/code&gt;lectro &lt;code&gt;L&lt;/code&gt;uminescente&lt;/p&gt;
&lt;img src=&quot;del.webp&quot; alt=&quot;DEL&quot; class=&quot;img-bg&quot; /&gt;
&lt;p&gt;En bref, une DEL est une lumière qui ne demande que très peu d’énergie. On peut donc l’alimenter directement depuis l’Arduino.&lt;/p&gt;
&lt;p&gt;Si l’on applique une tension aux deux bornes de la DEL, elle s’allumera.&lt;/p&gt;
&lt;p&gt;Une DEL a deux “pattes”. L’une d’elles est légèrement plus longue, il s’agit de la patte positive. L’autre est la négative. Lors du branchement, il faut faire attention de bien brancher la DEL.&lt;/p&gt;
&lt;h2 id=&quot;faire-clignoter-une-del&quot;&gt;Faire clignoter une DEL&lt;/h2&gt;
&lt;p&gt;On voudrait demander à l’Arduino de faire clignoter une la DEL deux fois en la laissant 2 secondes éteintes et 3 secondes allumées. En mots, on aurait:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Allumer la DEL&lt;/li&gt;
&lt;li&gt;Attendre 3 secondes&lt;/li&gt;
&lt;li&gt;Éteindre la DEL&lt;/li&gt;
&lt;li&gt;Attendre 2 secondes&lt;/li&gt;
&lt;li&gt;Allumer la DEL&lt;/li&gt;
&lt;li&gt;Attendre 3 secondes&lt;/li&gt;
&lt;li&gt;Éteindre la DEL&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;telecharger-arduino&quot;&gt;Télécharger Arduino&lt;/h3&gt;
&lt;p&gt;Il est maintenant temps d’essayer de demander à l’Arduino de faire ces étapes. Téléchargeons le logiciel depuis &lt;a class=&quot;external&quot; href=&quot;https://www.arduino.cc/en/main/software&quot; target=&quot;_blank&quot;&gt;le site officiel d’Arduino&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On peut télécharger le ZIP ne demandant pas d’installation à cette &lt;a class=&quot;external&quot; href=&quot;https://www.arduino.cc/download_handler.php&quot; target=&quot;_blank&quot;&gt;adresse&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On peut maintenant lancer l’application.&lt;/p&gt;
&lt;h3 id=&quot;premiers-pas-en-arduino&quot;&gt;Premiers pas en Arduino&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-arduino/ide.webp&quot; alt=&quot;IDE&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On voit maintenant un code de base fournit par Arduino.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; put your setup code here, to run once:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; put your main code here, to run repeatedly:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;setup&lt;/code&gt; est exécuté qu’une fois au démarrage de l’Arduino.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;loop&lt;/code&gt; est ensuite exécuté continuellement.&lt;/p&gt;
&lt;p&gt;Toutefois, avant de commencer à coder, branchons la DEL dans l’Arduino.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-arduino/branchement.webp&quot; alt=&quot;Branchement&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dans le cadre de ce document, nous allons utiliser la &lt;strong&gt;pin&lt;/strong&gt; numéro 13. Vous pouvez en choisir une autre si vous voulez. La longue patte doit être connectée dans la pin 13 et la courte au ground. Le &lt;strong&gt;ground&lt;/strong&gt; est le 0 volt de référence de l’Arduino.&lt;/p&gt;
&lt;p&gt;Pour empêcher de brûler la DEL, on place une résistance en &lt;strong&gt;série&lt;/strong&gt; avec la DEL. La résistance doit être entre 220 et 280 Ohms. Elle peut être placée avant ou après la DEL.&lt;/p&gt;
&lt;h4 id=&quot;fonctions-de-base&quot;&gt;Fonctions de base&lt;/h4&gt;
&lt;p&gt;Pour faire clignoter une DEL, on doit pouvoir être capable de l’allumer, de l’éteindre et d’attendre. Nous allons voir comment réaliser ces actions dans Arduino.&lt;/p&gt;
&lt;h5 id=&quot;configuration-de-la-del&quot;&gt;Configuration de la DEL&lt;/h5&gt;
&lt;p&gt;On doit indiquer à l’Arduino quelles pins on désire utiliser, dans notre cas il s’agit de la pin 13. On appelle alors la fonction suivante:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;OUTPUT&lt;/code&gt; signifie que l’on veut se servir de la pin comme d’une sortie, donc mettre une certaine tension à la pin plutôt que de lire la tension. On aurait pu utiliser &lt;code&gt;INPUT&lt;/code&gt; pour initialiser la pin comme une entrée. Nous allons en voir une exemple par la suite.&lt;/p&gt;
&lt;h5 id=&quot;allumer-la-del&quot;&gt;Allumer la DEL&lt;/h5&gt;
&lt;p&gt;Pour allumer la DEL, on doit mettre une certaine tension aux bornes de la DEL. Comme la patte négative est branchée au ground, on doit appliquer un voltage positif à la patte branchée dans la pin 13. Pour ce faire, on utilise la fonction suivante:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;HIGH&lt;/code&gt; signifie une tension positive. Dans le cas d’une Arduino UNO, on met 5 volts sur la pin 13.&lt;/p&gt;
&lt;h5 id=&quot;eteindre-la-del&quot;&gt;Éteindre la DEL&lt;/h5&gt;
&lt;p&gt;Pour l’éteindre, on procède de façon semblable.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&quot;attendre&quot;&gt;Attendre&lt;/h5&gt;
&lt;p&gt;Pour attendre un certain temps, on utilise la fonction:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ici, 1000 représente le temps à attendre en millisecondes. On a qu’une seconde est 1000 ms. Par exemple, pour attendre 5 secondes, on devrait indiquer 5000 ms.&lt;/p&gt;
&lt;h4 id=&quot;mettre-le-tout-ensemble&quot;&gt;Mettre le tout ensemble&lt;/h4&gt;
&lt;p&gt;Reprenons la liste d’étapes à suivre pour faire clignoter notre DEL:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Allumer la DEL&lt;/li&gt;
&lt;li&gt;Attendre 3 secondes&lt;/li&gt;
&lt;li&gt;Éteindre le DEL&lt;/li&gt;
&lt;li&gt;Attendre 2 secondes&lt;/li&gt;
&lt;li&gt;Allumer la DEL&lt;/li&gt;
&lt;li&gt;Attendre 3 secondes&lt;/li&gt;
&lt;li&gt;Éteindre la DEL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On peut maintenant “traduire” chaque étape en code. Il manque toutefois l’initialisation de la pin au début. Avec les informations un peu plus haut, on peut maintenant coder notre Arduino.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 0. On dit a l&amp;#39;Arduino que l&amp;#39;on réserve la pin 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Allumer la DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Attendre 3 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Éteindre le DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 4. Attendre 2 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5. Allumer la DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 6. Attendre 3 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 7. Éteindre le DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On peut maintenant connecter l’Arduino par USB à l’ordinateur.&lt;/p&gt;
&lt;p&gt;On doit premièrement vérifier que l’Aduino est connectée dans Outils -&amp;gt; Port. Il faut s’assurer que le port selectionné est bien celui de l’Arduino.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://willguimont.com/blog/intro-arduino/port.webp&quot; alt=&quot;Port&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On peut envoyer le code sur l’Arduino avec le bouton “Téléverser” (la flèche vers la droite). Après un certain temps, l’Arduino devrait faire clignoter la DEL deux fois selon les délais définit.&lt;/p&gt;
&lt;h3 id=&quot;a-l-infini&quot;&gt;À l’infini&lt;/h3&gt;
&lt;p&gt;Et si on désirait faire clignoter le DEL à l’infini? Il faudrait demander à l’Arduino de la faire clignoter pleins de fois. On pourrait avoir:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 0. On dit a l&amp;#39;Arduino que l&amp;#39;on réserve la pin 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Allumer la DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Attendre 3 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Éteindre le DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 4. Attendre 2 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 5. Allumer la DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 6. Attendre 3 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 7. Éteindre le DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;             &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;           &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;....&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et on devrait continuer ainsi pendant longtemps… Heureusement, il y a une meilleure façon !&lt;/p&gt;
&lt;p&gt;La fonction loop est exécutée continuellement après setup, il suffit donc d’avoir le code suivant:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; setup&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  pinMode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; OUTPUT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;     //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 0. On dit a l&amp;#39;Arduino que l&amp;#39;on réserve la pin 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; HIGH&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 1. Allumer la DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 2. Attendre 3 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  digitalWrite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;13&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; LOW&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;   //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 3. Éteindre le DEL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;  delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;2000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; 4. Attendre 2 secondes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On a donc que la lumière s’allume pour 3 secondes, et s’éteint pendant 3 secondes à l’infini. On remarque qu’il y a moins de code &lt;strong&gt;copier-collé&lt;/strong&gt; !&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Stacks</title>
        <published>2019-02-15T00:00:00+00:00</published>
        <updated>2019-02-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/stack/"/>
        <id>https://willguimont.com/blog/stack/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/stack/">&lt;p&gt;Stacks are very much like a stack of plates. When you don’t want to do the dishes, you simply &lt;em&gt;push&lt;/em&gt; the dirty plate on top of the others. Whereas when you are washing them, you take to plate on the top of the stack and proceed to &lt;em&gt;pop&lt;/em&gt; them all.&lt;/p&gt;
&lt;p&gt;In the same way, the stack &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/&quot;&gt;abstract data type&lt;/a&gt; allows you to &lt;em&gt;push&lt;/em&gt; and &lt;em&gt;pop&lt;/em&gt; elements on the top of the stack.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Cormen-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/stack/#fn-Cormen&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;img src=&quot;stack.svg&quot; alt=&quot;Push and Pop on a stack&quot; class=&quot;img-bg&quot; /&gt;
&lt;p&gt;We can see a stack as a bottle, you can only access the content from the top.&lt;/p&gt;
&lt;p&gt;Since the last element pushed on the stack is the first one to be popped, we say that the stack is a &lt;em&gt;last in, first out&lt;/em&gt; (LIFO) data structure.&lt;/p&gt;
&lt;p&gt;We can define our stack in an imperative manner. Each operation modifies a stack instance.&lt;/p&gt;
&lt;p&gt;We could also define the stack in a functional manner. The operations applied to the stack is viewed as a mathematical function that maps the old state to the new state. Refer to the example below for more information.&lt;/p&gt;
&lt;h2 id=&quot;imperative-definitions&quot;&gt;Imperative Definitions&lt;/h2&gt;
&lt;p&gt;An imperative stack has two essential operations:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Operation&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;$\text{Push}(S, x)$&lt;/td&gt;&lt;td&gt;Add the element $x$ on the stack $S$&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;$\text{Pop}(S)$&lt;/td&gt;&lt;td&gt;Remove the most recently added element to $S$ and return it&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;We can add non-essential operations to ease programming. We note the non-essential operations:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Operation&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;$\text{Peek}(S)$&lt;/td&gt;&lt;td&gt;Return the most recently added element in $S$ without removing it&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;$\text{Create}()$&lt;/td&gt;&lt;td&gt;Create a new Stack&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;$\text{IsEmpty}(S)$&lt;/td&gt;&lt;td&gt;Return a Boolean value specifying if the stack $S$ is empty&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;As $\text{Peek}(S)$ can be defined in terms of $\text{Push}$ and $\text{Pop}$, we say that this operation is non-essential.&lt;/p&gt;
&lt;p&gt;In pseudo code (Python), we could define $\text{Peek}$ as:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    top_value&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;S&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; top_value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; top_value&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;imperative-implementations&quot;&gt;Imperative Implementations&lt;/h3&gt;
&lt;h4 id=&quot;stack-adt-in-c&quot;&gt;Stack ADT in C&lt;/h4&gt;
&lt;p&gt;For simplicity, the stack is implemented with an array, but it could be implemented using a linked list.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; stack.h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;ifndef&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; STACK_H&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; STACK_H&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stdlib.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;typedef&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; struct&lt;/span&gt;&lt;span&gt; stack_rep stack_rep&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;typedef&lt;/span&gt;&lt;span&gt; stack_rep &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;typedef&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;unsigned&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; stack_item_t&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;STACK_H&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; stack.c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stack.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;struct&lt;/span&gt;&lt;span&gt; stack_rep &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    unsigned&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; top&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    unsigned&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    stack_item_t&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span&gt;elements&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;unsigned&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    stack_t&lt;/span&gt;&lt;span&gt; s &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;struct&lt;/span&gt;&lt;span&gt; stack_rep&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;elements&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; stack_item_t&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;elements&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;--&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_item_t&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;elements&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;stack_t&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; main.c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;stack.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    stack_t&lt;/span&gt;&lt;span&gt; stack &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    const&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span&gt; numValue &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    int&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; numValue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Pushing: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        stack_push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; values &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;+&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; numValue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        int&lt;/span&gt;&lt;span&gt; popped &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;stack_peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Popping: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; popped&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        stack_pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack_empty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;    stack_free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that from the user point of view, &lt;code&gt;stack_t&lt;/code&gt; is completely opaque to the user. Only stack.c knows the inner representation of &lt;code&gt;stack_t&lt;/code&gt;, since we only declared &lt;code&gt;stack_t&lt;/code&gt; in stack.h.&lt;/p&gt;
&lt;p&gt;We could completely change the implementation detail and nothing would change from the user point of view.&lt;/p&gt;
&lt;p&gt;Notice that we pass the stack to the function so that they know on which instance work. This is akin to Python self.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; ValuePrinter&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; __init__&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    def&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; print_value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;self&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The self argument is passed automatically to the object when calling the function on the instance. Both lines are equivalents.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vp&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; ValuePrinter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;42&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;vp&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;print_value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; prints 42&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ValuePrinter&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;print_value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;  #&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; prints 42 too&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the two statements are equivalent because we know that print_value is not overridden. That way we are sure that &lt;code&gt;vp.print_value()&lt;/code&gt; is equivalent to &lt;code&gt;ValuePrinter.print_value(vp)&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;object-oriented-stack-in-java&quot;&gt;Object Oriented Stack in Java&lt;/h4&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Stack.java&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; io&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;willguimont&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; interface&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Stack&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; FullStackException&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; RuntimeException&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; EmptyStackException&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; RuntimeException&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt; element&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    T&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    boolean&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; StackArray.java&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; io&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;willguimont&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; StackArray&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; implements&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; Stack&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Object&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; elements&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; top&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; StackArray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        elements &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Object&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        top &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt; element&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;top &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            elements&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;top&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; element&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; FullStackException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; EmptyStackException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;--&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; EmptyStackException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; elements&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;top &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; boolean&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; top &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; StackList.java&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; io&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;willguimont&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; java&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;LinkedList&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; java&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;List&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; StackList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; implements&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; Stack&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; List&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; elements&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; size&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; StackList&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        elements &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; LinkedList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;T&lt;/span&gt;&lt;span&gt; element&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        elements&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;element&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        size&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; EmptyStackException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        elements&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;remove&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        size&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;--&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; EmptyStackException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; elements&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;elements&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;size&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; boolean&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; elements&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Main.java&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; io&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;willguimont&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-l-b z-d-1 z-d-b&quot;&gt;*&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Main&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; static&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; void&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;String&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; Both work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;Stack&amp;lt;Integer&amp;gt; stack = new StackArray&amp;lt;Integer&amp;gt;(10);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        Stack&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Integer&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; StackList&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        int&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; values&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; values&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;            System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Pushing value: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;            stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;values&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; values&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;length&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ++&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;            int&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; value&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;peek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;            System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Popping value: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;            stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        System&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;Is stack empty: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; stack&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note how easy it is to add new represents of the stack. This is one of the strong points of object-oriented programming compared to ADT.&lt;/p&gt;
&lt;p&gt;Here the stack is defined with an interface that differs from the way we defined &lt;code&gt;stack_t&lt;/code&gt; in C. &lt;code&gt;stack_t&lt;/code&gt; is an opaque type that only the operations know the inner details, whereas the interface declares the methods a stack has to implement.&lt;/p&gt;
&lt;p&gt;For more information on the comparison of ADT and object, see &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/&quot;&gt;Introduction to Abstract Data Types&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;functional-definitions&quot;&gt;Functional Definitions&lt;/h2&gt;
&lt;p&gt;On the contrary to the imperative stack, a functional implementation doesn’t mutate the state of the stack. Instead, the operations are seen as mathematical functions that map from the old state to the new frame.&lt;/p&gt;
&lt;p&gt;Much like a function $ f(x) = x^{2} $ that maps a value $x$ to its square. The initial value of $x$ stays unchanged.&lt;/p&gt;
&lt;p&gt;In a functional paradigm, we need three operations to fully define a stack.&lt;/p&gt;
&lt;p&gt;$\text{Push}(S, x)$: Returns a new stack with an element $x$ pushed on top of $S$&lt;/p&gt;
&lt;p&gt;$\text{Pop}(S)$: Return the stack $S$ without its first element&lt;/p&gt;
&lt;p&gt;$\text{Top}(S)$: Returns the value on top of $S$&lt;/p&gt;
&lt;p&gt;Note that we don’t need a $\text{Create}$ operation because there is no instance. Instead, we define a special state $\Lambda$ (or &lt;strong&gt;empty&lt;/strong&gt;) that represents the empty state.&lt;/p&gt;
&lt;p&gt;Also note that we don’t need an $\text{isEmpty}$ operation either, because we can simply test the equality to $\Lambda$.&lt;/p&gt;
&lt;h3 id=&quot;functional-implementations-in-haskell&quot;&gt;Functional Implementations in Haskell&lt;/h3&gt;
&lt;p&gt;This bit of code is adapted from &lt;a class=&quot;external&quot; href=&quot;https://haskell.org&quot; target=&quot;_blank&quot;&gt;haskell.org&lt;/a&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Haskell-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/stack/#fn-Haskell&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; stack.hs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Stack&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Stack&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; empty&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; isEmpty&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; push&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; top&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; pop&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;isEmpty&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Bool&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;newtype&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; StackImpl&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;a&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;empty &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; StackImpl&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-7 z-d-7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;isEmpty &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;StackImpl&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; null s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;push x &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;StackImpl&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; StackImpl&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;top &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;StackImpl&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; head s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pop &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;StackImpl&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;:&lt;/span&gt;&lt;span&gt;ss&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;StackImpl&lt;/span&gt;&lt;span&gt; ss&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;haskell&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;z-l-6 z-l-i z-d-3 z-d-i&quot;&gt; main.hs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Stack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Control.Monad&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;unless&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;printStack&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Show&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;printStack x &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; unless &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;isEmpty x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; $&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    let&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; pop x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    print a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    printStack s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; ::&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; IO&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;    let&lt;/span&gt;&lt;span&gt; stack &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;=&lt;/span&gt;&lt;span&gt; foldl &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;flip push&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; empty &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 4&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    printStack stack&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note here that this code is much shorter and that the stacks aren’t mutated, instead, the functions return a new stack each time.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Stacks are an elementary data structure. They are fundamentals in computer science. We note their uses in multiples places such as &lt;a class=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Sudoku_solving_algorithms#Backtracking&quot; target=&quot;_blank&quot;&gt;solving sudokus using backtracking algorithms&lt;/a&gt;, recursion, converting equations to &lt;a class=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Reverse_Polish_notation&quot; target=&quot;_blank&quot;&gt;reverse Polish notation&lt;/a&gt; and much more. We even see stacks used in how CPUs handle subroutines. They truly are fundamental to the computer science field, from the theoretical to the practical.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-Cormen&quot;&gt;
&lt;p&gt;Thomas H. Cormen et al. Introduction to Algorithms. 2009. &lt;a href=&quot;https://willguimont.com/blog/stack/#fr-Cormen-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Haskell&quot;&gt;
&lt;p&gt;Haskell org. &lt;a class=&quot;external&quot; href=&quot;https://wiki.haskell.org/Abstract_data_type&quot; target=&quot;_blank&quot;&gt;Abstract Data Types&lt;/a&gt;. 2014. &lt;a href=&quot;https://willguimont.com/blog/stack/#fr-Haskell-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction to Abstract Data Types</title>
        <published>2019-01-27T00:00:00+00:00</published>
        <updated>2019-01-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            William Guimont-Martin
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://willguimont.com/blog/abstract-data-type/"/>
        <id>https://willguimont.com/blog/abstract-data-type/</id>
        
        <content type="html" xml:base="https://willguimont.com/blog/abstract-data-type/">&lt;p&gt;The proposition of abstract data types by Liskov and Zilles is an important step in the way we build computer software. Abstract data types allow programmers to leverage the power of abstraction. By hiding implementation details, they allow programmers to use a structure by only being concerned about their behaviors and not how the structure works inside.&lt;/p&gt;
&lt;p&gt;This gives programmers tools to think at a higher level, focused on the problem to solve.&lt;/p&gt;
&lt;h2 id=&quot;history&quot;&gt;History&lt;/h2&gt;
&lt;p&gt;Abstract data types (ADT) were proposed in 1974 by, 2008 Turing Award winner, Barbara Liskov and her coauthor Stephen Zilles in the paper &lt;em&gt;Programming with abstract data types&lt;/em&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Liskov-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Liskov&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. This paper wasn’t only a theoretical paper, they implemented the concept in a programming language. Liskov and her students created the programming language CLU that included abstract data types. ADTs are often seen as a step in the development of object-oriented programming.&lt;/p&gt;
&lt;p&gt;ADTs were proposed in the 70s, around the time when the term &lt;em&gt;software crisis&lt;/em&gt; was coined. People wanted to build sophisticated software programs but didn’t know how to build them effectively. Projects often ran over-budget, over-time, and the resulting software was often unmanageable, hard to maintain, and of low quality.&lt;/p&gt;
&lt;p&gt;It was around that time that the use of the Go To statement was still controversial. Dijkstra wrote &lt;em&gt;Go To Statement Considered Harmful&lt;/em&gt;&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Dijkstra-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Dijkstra&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; in 1968. At that time, the use of Go To statements was widespread, which led to hard to debug and maintain codes.&lt;/p&gt;
&lt;p&gt;The only kind of abstraction commonly used was procedures that weren’t necessarily used for abstraction per see but save space. If a bit of code was called often, they’d factor it out in a procedure, but not necessarily in a logical module. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Keynote-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Keynote&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Moreover, languages like Algol60 used global variables for the communication between modules, which led to spaghetti code when scaling up. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Keynote-2&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Keynote&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The landscape of software programming was a bit messy, people were building software programs in a non-structured manner.&lt;/p&gt;
&lt;p&gt;The ideas discussed in Liskov &amp;amp; Zilles’s paper may seem obvious now but remember the time when they were proposed. In the last 50 years of building software programs, we learned a lot. This concept paved the way for object-oriented programming and better software design.&lt;/p&gt;
&lt;h2 id=&quot;definitions&quot;&gt;Definitions&lt;/h2&gt;
&lt;h3 id=&quot;adt&quot;&gt;ADT&lt;/h3&gt;
&lt;p&gt;Liskov &amp;amp; Zilles describe ADT as following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An abstract data type defines a class of abstract objects which is completely characterized by the operations available on those objects. This means that an abstract data type can be defined by defining the characterizing operations for that type. […] Implementation information, such as how the object is represented in storage, is only needed when defining how the characterizing operations are to be implemented. The user of the object is not required to know or supply this information.&lt;/p&gt;
&lt;p&gt;– Liskov &amp;amp; Zilles&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Liskov-2&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Liskov&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We learn from the definition that an ADT defines a type and a set of operations. From the perspective of the user, the type is completely opaque, meaning we can’t see the inner representation of the data it contains.&lt;/p&gt;
&lt;p&gt;The type is completely opaque from outside of its operations. This contributes to build abstraction. For the user, the type is nothing particular, he has to use the operations.&lt;/p&gt;
&lt;p&gt;If we want to have multiple representations for an ADT, the operations need to be aware of them. Adding a new representation in an ADT is therefore costly, we need to modify the existing operations. We will discuss later the implications of that fact.&lt;/p&gt;
&lt;p&gt;We can observe two categories of operations: essentials and non-essential. Basically, non-essential can be defined from essential operations. We will see an example later in this article.&lt;/p&gt;
&lt;h3 id=&quot;abstraction&quot;&gt;Abstraction&lt;/h3&gt;
&lt;p&gt;Liskov &amp;amp; Zilles describe abstraction:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What we desire from an abstraction is a mechanism which permits the expression of relevant details and the suppression of irrelevant details.&lt;/p&gt;
&lt;p&gt;– Liskov &amp;amp; Zilles&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Liskov-3&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Liskov&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This allows programmers to use complex objects by being only concerned by their behaviors and not how they are implemented. This helps to have a higher level of reasoning, we can solve the problem using abstraction, then solve the subproblems that are those abstractions. This allows splitting the source code in logical modules, thus improving code reusability. We also separate the level of abstraction, the high-level code isn’t polluted by low-level details, therefore improving code readability.&lt;/p&gt;
&lt;p&gt;As Robert C. Martin said in &lt;em&gt;Clean Code&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mixing levels of abstraction within a function is always confusing. Readers may not be able to tell whether a particular expression is an essential concept or a detail.&lt;/p&gt;
&lt;p&gt;– Robert C. Martin&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Martin-1&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Martin&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;a-small-example&quot;&gt;A small example&lt;/h3&gt;
&lt;p&gt;To make it concrete, here a simple example.&lt;/p&gt;
&lt;p&gt;Abstract data types are like the built-in types of a programming language. When a programmer uses the type &lt;em&gt;Integer&lt;/em&gt; of a programming language, he’s usually not concerned about the binary representation of the integer, i.e. a string of bits. He thinks about the &lt;em&gt;Integer&lt;/em&gt; and the operations related to it as indivisible and atomic, when in fact they can be translated to multiple machine instructions. We define the operations on &lt;em&gt;Integer&lt;/em&gt; by their behaviors. We expect (+) to add two &lt;em&gt;Integer&lt;/em&gt; and (*) to multiply them, but we’re usually not concerned about how those operations are made under the hood. Abstract data types bring that idea of abstraction to user-defined structures. The client code can use those structures “as-is”, much like &lt;em&gt;Integers&lt;/em&gt;, without knowing the implementation details.&lt;/p&gt;
&lt;p&gt;However, the abstraction is not perfect for most types. In the case of &lt;em&gt;Integer&lt;/em&gt;, we may be interested in knowing if an overflow happened. The overflow depends on the implementation. A 32 bits &lt;em&gt;Integer&lt;/em&gt; will overflow at a lower value than 64 bits one. More generally, most built-in types are not perfect abstraction because, in practice, we need to know when the implementation fails to represent the data.&lt;/p&gt;
&lt;h3 id=&quot;computational-complexity-and-adt&quot;&gt;Computational complexity and ADT&lt;/h3&gt;
&lt;p&gt;In a more practical context, we consider that the behavior of the object isn’t enough to characterize completely the type. Let’s imagine we have two implementations of the Stack ADT (see example below). In the first implementation, the push operation is done in $$O(1)$$. The second one was written poorly and the push operation is done in $$O(n!)$$. From a behavioral perspective, both are equivalent. They both correctly implement the expected behavior of a Stack, but in a real software program, it would be better to use the first implementation. That’s the reason why some authors include the complexity of the operations as well in the definition of abstract data types.&lt;/p&gt;
&lt;h2 id=&quot;simple-examples&quot;&gt;Simple examples&lt;/h2&gt;
&lt;p&gt;The Stack is an example of an abstract data type. We can define the behavior of a stack by giving it two operations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Push&lt;/strong&gt;: Add an element on the stack&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pop&lt;/strong&gt;: Remove the most recently added element and return it&lt;/p&gt;
&lt;p&gt;With those two operations, we can completely define the Stack. We note that those two operations are essential to a stack to effectively be a stack. We can derive other operations from those two. We can, for example, define the &lt;strong&gt;Peek&lt;/strong&gt; operator from a pop followed by a push and then returning the value that was popped. &lt;strong&gt;Peek&lt;/strong&gt; isn’t essential because it can be derived from other operations.&lt;/p&gt;
&lt;h2 id=&quot;differences-with-object-oriented-programming&quot;&gt;Differences with object-oriented programming&lt;/h2&gt;
&lt;p&gt;To help demonstrate the differences and trade-offs between object-oriented programming and abstract data type. Here is an adapted version of the Shape example from chapter 6 of &lt;em&gt;Clean Code&lt;/em&gt; of Robert C. Martin&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Martin-2&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Martin&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;procedural-shape-modified&quot;&gt;Procedural Shape (modified)&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Geometry&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; final&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; PI&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 3.141592653589793&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Square&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; side&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Rectangle&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; height&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Circle&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; center&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; radius&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Square&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; createSquare&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Point&lt;/span&gt;&lt;span&gt; topLeft&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span&gt; side&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        Square&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Square&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        s&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;topLeft&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        s&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;side&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; side&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Rectangle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; createRectangle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Point&lt;/span&gt;&lt;span&gt; topLeft&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        Rectangle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Rectangle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        r&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;topLeft&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        r&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        r&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; r&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Circle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; createCircle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Point&lt;/span&gt;&lt;span&gt; center&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span&gt; radius&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;        Circle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; c&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; Circle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; center&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;        c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; radius&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; area&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;Object&lt;/span&gt;&lt;span&gt; shape&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; throws&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; NoSuchShapeException&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;shape &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;instanceof&lt;/span&gt;&lt;span&gt; Square&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;            Square&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Square&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;shape&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;side&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; s&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;side&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;shape &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;instanceof&lt;/span&gt;&lt;span&gt; Rectangle&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;            Rectangle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Rectangle&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;shape&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; r&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;shape &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;instanceof&lt;/span&gt;&lt;span&gt; Circle&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;            Circle&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; c&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Circle&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;shape&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;            return&lt;/span&gt;&lt;span&gt; PI &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;radius&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        throw&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; NoSuchShapeException&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Firstly, we notice that outside of the class Geometry; Square, Rectangle and Circle are completely opaque. This hides the implementation details of the shapes.&lt;/p&gt;
&lt;p&gt;We also notice that if we want to add a new shape, we have to modify all the operations of the Geometry class. Here, we would need to add another clause to handle the new kind of shape.&lt;/p&gt;
&lt;p&gt;On the contrary, if we wanted to add an operation, we would only need to add a method. The types of shape don’t need to change. The process of adding operations is additive, meaning we do not have to modify existing code.&lt;/p&gt;
&lt;h3 id=&quot;polymorphic-shapes&quot;&gt;Polymorphic shapes&lt;/h3&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; interface&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Shape&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; area&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Square&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; implements&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; Shape&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; side&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; area&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; side&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt;side&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Rectangle&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; implements&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; Shape&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; topLeft&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; height&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; area&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; height &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; Circle&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; implements&lt;/span&gt;&lt;span class=&quot;z-l-4 z-d-4&quot;&gt; Shape&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; Point&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; center&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    private&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; radius&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; final&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; PI&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-9&quot;&gt; 3.141592653589793&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt;    public&lt;/span&gt;&lt;span class=&quot;z-l-3 z-l-b z-d-6 z-d-b&quot;&gt; double&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; area&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;        return&lt;/span&gt;&lt;span&gt; PI &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt; radius &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt;*&lt;/span&gt;&lt;span&gt; radius&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we notice that if we want to add a new type of shape, we don’t have to modify anything, the process is purely additive. We create a new class that implements Shape and that’s it.&lt;/p&gt;
&lt;p&gt;On the other side, if we want to add an operation to Shape, we would need to modify all existing classes that implement Shape.&lt;/p&gt;
&lt;h3 id=&quot;adt-and-oop&quot;&gt;ADT and OOP&lt;/h3&gt;
&lt;p&gt;Briefly, we can say that it is easy to add operations on ADT without modifying the existing structure. On the other hand, object-oriented code makes it easy to add new representation without modifying existing operations. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Martin-3&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Martin&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Another way to say it: ADTs make it difficult to add new structures because we would need to modify all existing operations. OO code makes it difficult to add new operations because we would need to modify all existing classes. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-Martin-4&quot;&gt;&lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fn-Martin&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;OO and ADT are complementary concepts. Sometimes we want to be able to easily add new representation while other times we want to be able to add operation at our heart’s content. Not everything is an object.&lt;/p&gt;
&lt;h2 id=&quot;advantages-of-adt&quot;&gt;Advantages of ADT&lt;/h2&gt;
&lt;p&gt;ADT allows abstraction. As stated above, abstraction allows the programmer to think at a higher level, using tools to solve his problems without being embarrassed by the implementation details. This is achieved by hiding implementation details behind an opaque type. This allows separating the level of abstractions. High-level operations are not punctuated of low-level operations that hinder the understanding of the code.&lt;/p&gt;
&lt;p&gt;Moreover, ADTs allow the implementation to change without changing the calling code because the interface is kept secret. This allows the user code to be protected against changes in the implementation because they are hidden behind a fixed interface.&lt;/p&gt;
&lt;p&gt;Another implementation of the ADT can be used interchangeably because of their characterizing behaviors. This allows for performance increase when some implementations are faster in some situations without having to rewrite the client code.&lt;/p&gt;
&lt;p&gt;As stated above, ADTs make it easy to add new operations on a type. In a context where the number of representations won’t change, but you will often add operations, ADTs are preferable to object.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this article, we discussed the concept of an abstract data type. They are an important historical step in the way we build software programs. They are complementary to object in the way they make it easy to add operation while objects make it easy to add new representation.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-Liskov&quot;&gt;
&lt;p&gt;Liskov, Barbara &amp;amp; Zilles, Stephen. Programming with Abstract Data Types. 1974. &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Liskov-1&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Liskov-2&quot;&gt;↩2&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Liskov-3&quot;&gt;↩3&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Dijkstra&quot;&gt;
&lt;p&gt;Edsger W. Dijkstra. Go To Statement Considered Harmful. 1968. &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Dijkstra-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Keynote&quot;&gt;
&lt;p&gt;Barbara Liskov. &lt;a class=&quot;external&quot; href=&quot;https://www.infoq.com/presentations/programming-abstraction-liskov&quot; target=&quot;_blank&quot;&gt;Keynote: The Power of Abstraction&lt;/a&gt;. 2013. &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Keynote-1&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Keynote-2&quot;&gt;↩2&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-Martin&quot;&gt;
&lt;p&gt;Robert C. Martin. Clean Code. 2008. &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Martin-1&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Martin-2&quot;&gt;↩2&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Martin-3&quot;&gt;↩3&lt;/a&gt; &lt;a href=&quot;https://willguimont.com/blog/abstract-data-type/#fr-Martin-4&quot;&gt;↩4&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
</feed>
