An Introduction to Sanha

What is Sanha? It’s the name for a design of a programming language which I’ve been working on for a number of years. I call it a design because there’s no compiler, interpreter, or IDE. Quite literally, I haven’t written a single line of code for this language. It is nothing more than a blueprint. With that said, it began nearly a decade ago after I started writing code in C++. Eventually, I grew such a distaste for C++ that I set off to design a “better” language. It was about a year later that I discovered the D programming language which made my little “project” unimportant (as I delicately put it, “I love D because I hate C++”). However, I had obtained an interest in programming languages, so I continued to write down my thoughts and ideas. I didn’t originally call it Sanha; it’s a name that came later. After a while, I settled on the name Piranha, but I didn’t like the name much. Eventually, I discovered the word sanha from the etymology of piranha; the word, sanha, literally means “tooth”. So what is Sanha like? Initially, it began as a re-engineering of C++, copying it’s syntax and semantics, as that was the only language I really knew at the time. The language has undergone a drastic evolution since then, being highly influenced by D and Python, with C++ being a distant echo. The language still has a C-style feel but there is a lot of hidden semantics in the syntax. Get to it already! The conventional “Hello, World!” program:

module main
import std.console

def main(#args [string])
    printLine("Hello, World!")

Unfortunately, I couldn’t get any syntax highlighting to work here. Everything should seem fairly conventional here. The language uses modules, ‘def’ is used to define functions, braces are used for nesting, and statements are terminated by a line-break. However, this may seem a bit unusual: #args [string] You may have deduced that this defines a parameter, args, which is an array of strings. There are a lot of hidden semantics in this single bit of code. But let’s start with the basics:

  • This defines an explicit type, which means Sanha is statically typed … kind of …
  • The type may be omitted so that the type is inferred from the initializer.
  • The design is such as not to give preference to either type inference or explicit typing; both are encouraged and appropriate in different contexts.

The syntax is actually more clever than that. The full truth is, Sanha employs a hybrid of static and dynamic typing. Variables are statically typed, but their type is not set in stone; given you don’t explicitly define a type, variables may be initialized with an object of any type, which is unknown at compile-time and deduced at runtime. The type of a variable cannot change once it is declared and/or initialized. Another way to think of it, dynamic typing happens at initialization and static typing takes over thereafter. Then there’s the matter of the type syntax. First, it’s important to understand that types are first-class citizens, so you may pass them by reference, store them in containers, et cetera. With that understanding, the term, [string], is literally an array with a type in it. What this means is, types are expressions which may be evaluated at runtime. As long as the expressions results in a object of a special form, it will be translated into a type. The following code is equally valid:

def foo()
    return [string]

def main(#args foo()){ }

The form is only translated into a type in certain contexts. Otherwise, WYSIWYG, [string] is an array with a type in it. There are a variety of forms that can be translated into types. Many types are defined using their own literals. These are some examples:

#array [int32] = [10, 20, 30]
#tuple (string, int32) = ("One Hundred", 100)
#set {int32} = {10, 20, 30}
#range int32..int32 = 10..20

So far, I’ve covered a bit of the concrete aspects of the language. There are many other aspects which are currently poorly defined. For example, I’d like to implement some sort of pattern matching in the language and foresee a variety of applications for it, but I haven’t the slightest clue as for how to design it. I’m also working on a paradigm of “unique mutable / shared immutable” data, which technically works but is poorly executed. That’s it for now. Should I write another post about Sanha, I’ll likely cover more of the syntax and semantics as well as give an introduction to composition.