Microsoft Research is investigating language designs for writing code that is simple, obvious, and easy to reason about for both humans and machines. The new programming language, Bosque consists of features that provide ways to avoid accidental complexity in the development and coding process. The outcome is improved developer productivity, increased software quality, and enable a range of new compilers and developer tooling experiences.

What is Bosque?

Bosque (bohs-keh), Microsoft’s new open source programming language. It has a completely new model of programming termed as “Regularized Programming” that aims to reduce the accidental code complexity and focuses on algebraic operations.

Let’s have a quick overview of Bosque:

  • The author of Bosque, Mark Marron, introduces a new programming model called Regularized Programming.
  • The GitHub repo was created on 3rd of Mar, 2019, and published on Microsoft.com on 15th of April, 2019.
  • An open source project licensed under MIT.
  • Bosque is typed and functional.
  • The language derives from a combination of TypeScript inspired syntax and types, plus ML inspired semantics and Node/JavaScript.

The name Bosque is derived from Spanish meaning “Forest”. However there is no story behind the name, other than the fact that Microsoft maintains a handful of language names that are mostly single letter but this is a bit overdone.

The basic problem statement that Mark and his team are trying to solve is that, suppose if you are trying to start from a clean slate, what are the complexities that one can encounter and how to get rid of all those complexities. How many things you have to think about and can you minimize those number of things.

Why functional programming ?

The charm of functional programming is that you know what operation the function is supposed to perform without having to look at its implementation at all. You don’t have to worry about the complexities of mutation and side effects and what things might change during or after the execution of the function. It is a very popular programming paradigm at the moment.

From an ergonomic point of view if you look at Lisp, Haskell or Clojure, they are very fascinating and powerful but they have some features that make people a little uncomfortable in certain scenarios to code with a functional mindset. But that is just a creative thing.

Now, Javascript is also developing. It’s adopting a lot of principles and paradigms of functional programming but also putting them in such a way that is more ergonomically adaptable for the developers. So, it’s easy to write pieces of code and putting them together in a way that doesn’t surprise you during or after execution.

What are the features of Bosque?

Let’s have a look into some notable features of the new programming language:

1. Variable Assignment

Variable declarations in Bosque can be declared as constant in the scope using the var declaration form:

Examples of these declarations are:

var Identifier = Exp;
var Identifier:Type = Exp;

If the type is omitted in the declaration it is inferred from the type of the expression used to initialize the variable.

var x: Int = 3; //Int variable introduced and initialized
var y = 3;      //variable introduced and inferred to be of type Int

Alternatively variables can be declared as updatable in the scope using the var! declaration form. In the var! form an initializer expression can be used to set the initial value for the variable or it can be omitted to leave the variable uninitialized.

var! x: Int;
var! y = 7;

var a = x; //error undefined use

x = 3;
y = x;     //ok x is defined now

var z = 5;
z = y;     //error z is not updatable

2. Entity Constructors

To reduce the amount of boilerplate code introduced by constructors, and in particular constructors that have long argument lists that are mainly passed through to super constructors, the Bosque language uses construction via direct field initialization to construct entity (object) values.

concept Bar {
    field f: Int;
}

entity Baz provides Bar {
    field g: Int;
    field h: Bool = true;
}

var y = Baz{f=1, g=2, h=false}; //Create a Baz entity with the given field values
var x = Baz{f=1, g=2};          //Create a Baz entity with default value for h

3. Bulk Update

In most languages updating (or creating an updated copy) is done on a field-by-field basis. However, with the bulk updates in Bosque it is possible to perform the update as an atomic operation and without manually extracting and copying fields.

entity Baz {
    field f: Int;
    field g: Int;
    field k: Bool
}

var t = [ 1, 2, 3 ];
t->update(1=5)      //[1, 5, 2]
t->update(0=3, 1=5) //[3, 5, 3]
t->update(1=5, 4=0) //[1, 5, 3, none, 0]

var r = { f=1, g=2, k=true };
r->update(g=5)          //{f=1, g=5, k=true}
r->update(g=3, k=false) //{f=1, g=3, k=false}
r->update(g=5, h=0)     //{f=1, g=5, k=true, h=0}

var e = Baz{ f=1, g=2, k=true };
e->update(g=5)          //Baz{f=1, g=5, k=true}
e->update(g=3, k=false) //Baz{f=1, g=3, k=false}
e->update(g=5, h=0)     //error invalid field name

4. Merge

The update operations allow bulk algebraic copy-modification of values but require the literal properties/indices/fields to be specified. To allow more programmatic operation the Bosque language also provides chainable merge operations which take pairs of tuple/tuple, record/record, or nominal/record and merge the data values.

entity Baz {
    field f: Int;
    field g: Int;
    field k: Bool
}

var t = [ 1, 2, 3 ];
t->merge([5])       //[1, 2, 3, 5]
t->merge([3, 5])    //[1, 2, 3, 3, 5]

var r = { f=1, g=2, k=true };
r->merge({g=5})          //{f=1, g=5, k=true}
r->merge({g=3, k=false}) //{f=1, g=3, k=false}
r->merge({g=5, h=0})     //{f=1, g=5, k=true, h=0}

var e = Baz{ f=1, g=2, k=true };
e->merge({g=5})          //{f=1, g=5, k=true}
e->merge({g=3, k=false}) //{f=1, g=3, k=false}
e->merge({g=5, h=0})     //error field not defined

5. Iterative Processing

Instead of doing the usual iterative loop, Bosque avoids the whole idea about looping and accessing array directly from the memory.

To multiply all elements of array using loop method:

int a[5] = {1, 2, 3, 4, 5};
int b[5];
for(int i=0; i<5; i++)
    b[i] = a[i]*2;

The same code in Bosque would look like:

var a = List[Int]@{1, 2, 3, 4, 5};
var b = a.map[Int](fn(x) => x*2);

So these were some notable features of Bosque but you can also have a look at the detailed view in their GitHub repository.

How to use Bosque?

In order to build the language the following are needed:

  • 64 bit Operating System
  • The LTS version of node.js ( According to your OS )
  • Typescript (install with: npm i typescript -g)

You can get the Bosque repository here.

The ref_impl directory contains the reference implementation parser, type checker, interpreter, and command line runner. In this directory, you can build and test the Bosque reference implementation with:

npm install && npm run-script build && npm test

The ref_impl directory also contains a simple command line runner for standalone Bosque (.bsq) files. These files should have a single entry point function called main() as shown in the repository examples. The code in the file can be parsed, type checked, and executed with the following:

node bin/test/app_runner.js FILE.bsq

Mark believes that, just as structured programming, this regularized programming model will revolutionize to improved developer productivity, increased software quality, and enable a new level of developments in compilers and developer tooling.

He hopes his creation will soon find its place outside academia, probably in the cloud or server applications, since it “can fit very well in that niche and can be verified for correctness through symbolic analysis.”