Section 1: Introduction
In this part, we introduce the Bosque project. After reading this section, you will understand its key concepts and how to start experimenting with it.
This section comprises the following chapters:
- Chapter 1, Exploring Bosque
- Chapter 2, Configuring the Bosque Environment
- Chapter 3, Bosque Key Features
Chapter 1: Exploring Bosque
The Bosque project was born from Mark Marron's work, where he questioned the accidental complexity that exists in programming languages nowadays. He proposed a new programming language design that eliminated the factors of this complexity in terms of loops, recursion, mutable state, and reference equality, among others, thus resulting in a new paradigm called Regularized Programming.
Bosque has a syntax inspired by TypeScript and adopts semantics from ML and JavaScript, giving rise to a programming language that is easy to write and read.
The simplicity of Bosque allows programmers who decide to adopt Bosque to focus on the core of the problem without worrying about the errors that are caused by the language's accidental complexity. Consequently, they will build more reliable, robust, and predictable programs that have been prepared, by design, to support new trends.
In this chapter, we will cover the basics of what the Bosque project is, as well as some of the theory and motivation behind this project. We will also learn the basics of code intermediate representations (IR). We will learn what they are, why we need them, and what the Bosque approach is. We will also review the problem of accidental complexity and present the concept of regularized programming. Eventually, we will mention where Bosque can be applied.
We will cover the following topics:
- Identifying the need for another language
- Learning what intermediate representation is
- Discovering regularized programming
- Understanding accidental complexity
- How the experiment is going so far
- Bosque applications
By the end of this chapter, you will have knowledge about what Bosque really is and how it works.
Identifying the need for another language
Some of the most frequent questions programmers ask during their early learning years are "Why are there so many programming languages?," "Why don't we just use the same language for everything?," and "Why do we keep creating more programming languages?". A useful analogy to explain the diversity of the programming languages that exist today is to imagine programming languages as musical instruments. We have string, wind, and percussion instruments based on different physical principles; in the same way, programming languages are designed based on different architectures and paradigms. However, instruments or programming languages are often used to generate structured and ordered compositions.
We cannot objectively say that a guitar is not appropriate to play the fifth symphony by Beethoven, since we could only give an appreciation for this based on our personal tastes. In the same way, choosing a programming language might not represent preferring syntax or specific expertise.
But it is also true that interpreting some compositions without the appropriate instrument could be an arduous task, and it could mean sacrificing a big part of the piece due to the physical limitations of the instrument's design. A similar scenario unfolds when we're trying to use programming languages to do things that they were not designed to. Often, this could mean putting in a tremendous technical effort, or having to sacrifice performance, productivity, or stability.
In summary, The Four Seasons by Vivaldi can be beautifully played with a violin and maybe not with a drum; similarly, R rather than Lua could be much more suitable and efficient for statistically analyzing information, while Lua is better for extending Nginx servers instead of Ruby. Although we can use the same tools for everything, they will not always be the most appropriate.
Now that we have a better idea about the diversity of programming languages and their suitability for solving some specific types of problems, the following question arises: "Why was Bosque created?"
When it comes to developing high-level programming languages, one of the main objectives has always been to try to simplify the process of writing code so that it's as close to human language as possible. This allows us to simplify the process of giving instructions to machines using the potential of human reasoning.
But generally, each continuously evolving process implies an increase in complexity, and this complexity may cause mistakes, in the same way that programming languages have been acquiring characteristics that make them complex and prone to causing hard-to-identify errors. By learning from the past and questioning the actual complexity of programming languages, Bosque was born. To solve this and to learn from the past, as inspired by the impact generated by Structural Programming in its day, Bosque was born as a new programming language that eliminates accidental complexity.
As a result, we have a coding process that's more straightforward, predictable, and readable. This allows programmers to focus on the most important stuff or the main program logic, thus improving productivity and making software more reliable.
In the words of Bosque's creator (Mark Marron):
"The Bosque language demonstrates the feasibility of eliminating sources of accidental complexity while retaining the expressivity and performance needs for a practical language, as well as hinting at the opportunity for improved developer productivity and software quality."
Now that we understand why Bosque exists, lets learn how it builds an executable program from high-level source code.
Learning what Intermediate Representation is
Nowadays, it's not unusual to find high-level programming languages that use one or more intermediate representations when they're translating source code into binary code or machine code. By doing this, the compilation process can be simplified without us losing the advantages of a high-level language. It opens the path to developing new programming languages and being friendlier with developers and closer to the process of human reasoning. Bosque is no exception.
Let's learn how intermediate representation works by looking at an example.
First, an abstract representation is usually modeled through a graph that describes the program we are compiling through a data structure. This can occur in different ways:
- An abstract syntax tree (AST)
- Lineal IR's three-way code or Postfix notation
Let's take a look at the following expression:
5 * a - b
This expression can be expressed using the following AST:
Figure 1.1 – AST graph representation
If we quickly inspect the graph, we can identify the code's intent through its structure. We could use this abstract repr...