The Ironism

The Ironism


The lair of Lars J. Nilsson. Contains random musings on beer, writing and this thing we call life.

March 2012
MTWTFSS
« Feb Apr »
 1234
567891011
12131415161718
19202122232425
262728293031 

Categories


If I Would Design a Language

fungrimfungrim
Warning: This post contains fictional grammar, ideas off the cuff and high levels of programmer nerdery. Proceed at your own risk.

I’ve had a look at the influx of new languages for the JVM the last couple of months. In particular I’ve read up a bit on Kotlin, Fantom and Clojure. And naturally I started thinking about what I would do myself if I designed a new language.

Well… the world don’t need a new computer language. But nevertheless, here’s what I’m thinking right now.

Main Ideas

Here’s what I’d aim for primarily:

Hello World

Let’s get right down to it, shall we? We’ll do the standard “hello world” a bit more complicated immediately to highlight a bit more syntax:

So what do we have here? Let’s break it down.

Constructor

The constructor signature is declared immediately after the class name. It can contain default values for arguments. The actual implementation is done either implicitly, or in a “constructor” statement:

Note that this constructor is equivalent with the previous example. Does this mean that a class can only have one constructor? Yes it does, but with default values for arguments, and named argument passing it should be enough.

And by the way, the constructor arguments are accessible through the entire class. So the greeter can be simplified:

Pretty cool huh? This means there’s an implicit field for each constructor argument in each class, which is readable but not writable.

Class Immutability and Field Access

I’ll leave the collection classes for now, but ordinary classes are immutable by default, and all fields have a generated “getter”, and optionally a “setter” as well.  So, to start with, this would be illegal:

If we truly want an object that can be mutated, we’d have to declare it as such:

And now, we can change it post-construction:

Access to object fields are done via accessors that are generated automatically. If you want to change their behavior you can, but only the “setter”, the access is always reading the field as it is:

But all objects have another implicit function attached to fields, namely the clone operator. With this you can get a clone of the current object with one or more fields changed. If our Greeter was imutable, we could do this:

Under the hood this created a new Greeter object which is equivalent with the first, except for the new name. It would be nice if you could chain clone operations as well, but I’ll get back to you on that.

Functions and High Order Functions

We’ve seen a function already and there’s not much to add. The declaration is in the form:

To this we’ll add a few short-hands. OK, I know I said we’d only have one way of articulating statements. But hey, I think these may be worth it. Consider the following example:

Mr Eagle-eye will spot two possible ways of putting this simpler: Why use parenthesis when there’s no arguments, it’s pretty obviously a method declaration anyway. And why declare a “return” when it’s void any way. So…

In addition function should be possible to pass around as any other object. These high order functions comes in two flavors “strict” and “relaxed”.

By default all functions are relaxed as this is a great deal easier to work with. But by declaring strict functions we’ll enable functional programming out of the box a such functions will be guaranteed not to have side effects.

Here’s a bit of syntax for you. First, let’s imagine a “foreach” declaration on an interface:

And in a list of Greeter objects you’d call it like so:

“Primitive” Types and Literals

Everything is objects, and no excuse. Integers and Doubles are 64 bit. Strings are UTF-16. Characters are not integers. We have Bytes. So without further ado, here’s the list of literals:

The duration comes in the following flavors:

In addition to the ones above, here’s some shorthand, taken straight from Fantom:

Modularity

A “module” represent a unit of code which belongs to a particular namespace, and which is versioned and is packaged must like a Java “jar” file, ie. in a ZIP archive together with some meta-data. I haven’t thought through the declaration syntax yet, but here’s what we want in a declaration:

We’ll steal the reference syntax from Maven. So this…

… would be the namespace “net.larsan.test.lang”, the module “Core” and the version “1.1.0”.  The format of the version is probably fixed, but mayinclude a “-SNAPSHOT” postfix option.

Here’s something though: the declaration will not include build information such as “source folder” or similar. That’s mixing apples and oranges, and unfortunately both Fantom and Kotlin are doing it.

Let’s do some imaginary code:

Now, the module syntax is probably just a shorthand for this:

The name of the module class would be anonymous and generated at runtime.

Dependency Injection

With modularity in place, DI is just a small step away. Let’s start with a type to use:

Not very useful admitedly. But hang on:

It get’s neater if the transformer was actually an interface:

No we can play with polymorphism. I’ll skip ahead a bit here, suffice to say that I’m going to steal straight from Guice, including assisted inject, but this time with closures, so if you want to to imagine how it would look, go ahead. Some thing to note:

The great thing here is that we have the perfect place to configure our type binding. Consider the following example:

Add to this high order provider functions, and make the module extendible for binding overrides (which would be neat for unit testing) and you have something awesome in the works.

Concurrency

We’ll do an actor model with a twist inspired by Clojure. We’ll need two concepts:

An actor is an immutable object with an immutable state. However, this state can be updated by visiting functions. So, let’s imagine our Greeter from before is immutable, we could have an actor with a Greeter state:

That’s All?

No obviously not, only my eyes are starting to blur. But this should have given you some ideas, if nothing else about my personal taste. The concurrency model probably needs a bit of re-thinking. Should we allow Actors on mutable objects (provided they are cloned initially)? This would make the code one hell lot easier to write and should speed up execution for complex applications. Also actors needs to be able to talk to other actors.

There’s a lot of other stuff left that I can’t be bothered to cover tonight:

And now my brain is hurting.

The proprietor of this blog. Lunchtime poet, former opera singer, computer programmer. But not always in that order. Ask me again tomorrow.

    Comments 1