Overview

This page gives a brief overview of the Tetra programming language including the motivation for creating it, as well as the overall design of the language and features.


Motivation

We are now firmly in the multi core world. It is virtually impossible to buy a new computer with only a single processor core in it. New phones and tablets have either two or four processor cores, and even small computers such as the Raspberry Pi now come with four cores. Nearly every computer that we interact with is a parallel machine.

Despite this huge shift in the hardware world towards parallelism, there has not been a similar shift in the software world. Most programs are still written in a single-threaded manner with parallel programming relegated to niches such as scientific computing, systems development and high performance games.

There are several reasons for this. One of them is that our programming languages and tools are, for the most part, still geared towards sequential programming. Most languages do not include syntax support for parallel programming which makes it more difficult than it should be. Tools like debuggers are also geared primarily for single-threaded programming. Some aspects of parallel programming are inherently difficult, but some of the difficulty comes from our tools not being suited to the task.


Parallelism Built In

The main feature that distinguishes Tetra from most programming languages is that parallelism is a first-class language feature. It has syntax support for specifying that statements run in parallel, or in the background. Most languages instead use libraries to support parallelism. To see why this makes a difference, consider the following Python program which computes the sum of a range of numbers:

total = 0

def sum_range(numbers, a, b):
    i = a
    while i <= b:
        global total
        total = total + numbers[i]
        i = i + 1

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum_range(numbers, 0, 9)
print(total)

Now suppose we wish to parallelize this so that two threads each added half of the numbers. In Python, we'd have to use the threading library like so:

from threading import Thread, Lock

total = 0
lock = Lock( )

def sum_range(numbers, a, b):
    i = a
    while i <= b:
        global total
        lock.acquire( )
        total = total + numbers[i]
        lock.release( )
        i = i + 1

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
t1 = Thread(target = sum_range, args = (numbers, 0, 4))
t1.start( )

t2 = Thread(target = sum_range, args = (numbers, 5, 9))
t2.start( )

t1.join( )
t2.join( )
print(total)

The code related to specifying what should be done in parallel, and what cannot be is in bold. Notice that it takes over twice as many lines as the original sequential program. Not only is this rather tedious, but it is also error-prone. If we forget to join one of the threads, we will have a race condition which is quite difficult to debug.

Now, consider the same sequential sum program, but in Tetra:


global total = 0

def sum_range(numbers [int], a int, b int):
    i = a
    while i <= b:
        total = total + numbers[i]
        i = i + 1

def main( ):
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    sum_range(numbers, 0, 9)
    print(total)

The syntax of Tetra is quite close to that of Python. The major differences are that Tetra requires a main function, and Tetra is statically typed.

The bigger difference, however, is that parallelizing this Tetra program is much easier. It can be done as follows:

global total = 0

def sum_range(numbers [int], a int, b int):
    i = a
    while i <= b:
        lock:
            total = total + numbers[i]
            i = i + 1

def main( ):
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    parallel:
        sum_range(numbers, 0, 4)
        sum_range(numbers, 5, 9)
    print(total)

Again, the added lines appear in bold. Because Tetra has built-in syntax for parallelism, there are only two lines to add. The parallel keyword creates a new block of code. Each statement in that block is launched in a new thread. Each thread is automatically joined at the end of the parallel block. The lock statement also creates a new block which gives a critical section. There is no need to explicitly release the lock - it is automatically released at the end of the block.

Having syntactical support for parallelism makes it easier and less error-prone to use.


Designed for Education

Another reason that parallelism hasn't been widely embraced by the software world is that it is still not a large part of most computer science curriculums, despite several calls for it to be emphasized more.

One barrier to doing this is that most programming languages used for teaching programming, such as Python and Java, do not include parallelism as a built-in feature. The most widely used language, Python, is especially bad for parallelism because, in addition to lacking syntax for it, Python uses a "global interpreter lock" which actually prevents multiple threads from running at the same time.

On the other side of things, the languages which do have good support for parallelism, such as C and Fortran, are not widely used for introductory classes and can be difficult even for experienced programmers.

Tetra is designed to fill the niche of a language that is designed with parallel programming in mind, but which prioritizes ease of use over performance. It does this by including built-in data structures, garbage collection, and a simple syntax.

Copyright © 2018 Tetra | Licensed under the MIT License