Académique Documents
Professionnel Documents
Culture Documents
Alexander Gutev
Another Programming Language?. CodeProjectI recently released version 0.4, the first version that is remotely usable, of Tridash, a
programming language I've been working on...
You're probably wondering, with all the existing programming languages available supporting a variety of programming paradigms
ranging from low-level imperative programming to logic programming, why on earth would I create a new programming language.
What problem do I aim to solve with this new language that has not been solved already by the hundreds of programming
languages that came before it. To tell you the truth I mainly created it because I like writing software and trying out new ideas.
Creating a programming language was an interesting and fun exercise in itself. However this a legitimate reason for creating a new
language, besides the programming exercise.
I've tried many languages ranging from low-level C, object oriented languages such as C++, C#, and Java, scripting languages such
as Python, PHP and JavaScript and languages which implement entirely different programming paradigms such as Common Lisp,
Prolog and Haskell. Whilst all languages excel at different points, they are all rather lacking when it comes to creating robust and
interactive applications. Specifically they are lacking when it comes to managing the state of the application and the changes in its
state triggered by the user interaction or external events such as a data arriving on the network.
As a simple example, consider an application consisting of a text field, in which the user enters his/her name, after which a greeting
(with the user's name) is displayed.
Functional programming languages eschew state completely. In a pure functional programming language, memory does not exist.
Instead the entire application is structured as a pure function, i.e. without side effects, of its input, which produces the application's
output. In order to build interactive applications using a pure functional programming language, all application events (both user
and external) are grouped into an infinite list, referred to as a stream, and the application is structured as a pure function taking the
stream as input. The output is a new "application" object containing the updated GUI and any IO actions which are to be performed.
Whilst this approach offers a lot of benefits, such as being amenable to parallelisation due to the application being structured as a
pure function without side effects and thus without concurrent writes to the same memory location, it requires restructuring the
application logic as a function that takes an old application object as input and produces a new application object as output.
Effectively you have to think of an interactive application as though it is a non-interactive application, which simply takes an input,
produces an output and exits. Furthermore you still have to manually compute a new component from the old component for each
component comprising your application. It is also up to you to keep track of which components are affected by the event. The
addition of new application components, which are affected by some events, requires a change to the application "main" function.
Neither pure functional programming nor imperative programming allow you to declaratively specify the application state as a set
of components which are dependent on the state of other components. Imperative programming grants you too much access to
the underlying memory, allowing you to mutate the memory as you see fit. If not done carefully this can result in hard to find bugs,
moreover manually updating the state in response to events is tedious and distracts from the application logic. Functional
programming, on the end of the spectrum, completely hides the concept of memory forcing you to write your application as a pure
function taking the events and old application state as input and producing the new application state. This forces you to think of
your application in non-interactive terms, and you still have to manually make sure to compute the new state of each computed
affected by the event.
Most GUI toolkits provide some support for simple bindings however they either lack the functionality for specifying bindings
involving an arbitrary function of two or more components, or implementing such a binding requires implementing value
"converter" or "transformer" interfaces in a lower-level language. This is usually so cumbersome that most programmers prefer to
simply drop down to imperative programming.
Functional reactive programming languages are based on the idea of bindings involving arbitrary functions. Admittedly I haven't
tried that many FRP languages, however those which I have tried seem to stick more closely to the traditional functional
programming paradigm of implementing your application as a pure function. Few allow you to implement an application as a set of
distinct nodes with bindings between the nodes.
Enter Tridash
The Tridash language aims to provide a simple and intuitive solution to the State Management Problem, which allows you to think
of your application as an interactive application composed of live stateful, meaning they hold a particular value at a given moment
in time, components called nodes.
Nodes can correspond to purely computational components or other stateful components such as UI elements, the network or the
file system. Bindings between nodes, involving arbitrary functions of other nodes can be declared, using the '->' operator. Examples:
a -> b
a + b -> c
The first example demonstrates a simple binding in which: when the value of a changes, the value of b is updated to it.
The second example demonstrates a binding involve a function of two nodes. When the value of either a or b changes, c is set to
the sum of a and b.
What sets Tridash apart is the free-form manner in which nodes can be declared. There is no main function just a set of declarations.
Bindings can be declared between any pair of nodes.
More than just bindings between nodes, Tridash allows you to treat the bindings as nodes in themselves. Binding to a binding
allows you to control which bindings are active.
Example:
In this example if cond evaluates to true the binding a -> b is active, whereas if it evaluates to false it is as if the binding does not
exist, meaning changes in the value of a will not be propagated to b. This functionality is used to build a unique error handling
scheme, in which bindings are deactivate in the case of an error.
In the next major release you'll also be able to establish bindings between a node and its past states.
The hello example presented earlier can be implemented simply using a single binding declaration.
where name-field.value is a node corresponding to the value of the text field UI node and greeting.textContent
corresponds to the content of the UI node in which the greeting is displayed.
Programs as a whole are composed as a collection of a set nodes and bindings between the nodes. Changes in the value of a node,
are automatically propagated to the nodes which are dependent on the node's value. This allows you to focus on the core
application logic rather than the mechanics of propagating changes in state. The benefit of this is that the values of nodes which are
not dependent on each other can automatically be updated concurrently by the underlying framework, without any additional work.
In conclusion the Tridash language presents a new view of your program, as a collection of live inter-connected components, which
provides numerous benefits over the traditional view of your program as a linear sequence of instructions or a linear composition of
functions.
Status
Tridash is currently at version 0.4 however it is still an alpha product and lacks the necessary features for building real-world
applications, such as data-structures and a standard library. Currently only a JavaScript backend is implemented which uses HTML to
provide a user interface. Other backends are planned for a future release.
Tutorials demonstrating the basic functionality of the language. Advanced tutorials and a reference manual are in the works.
For installation instructions and tutorials head over to the project's wiki:
https://github.com/alex-gutev/tridash/wiki
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)