JaernCloud Programming Language

This page provides an overview of the JaernCloud Programming Language (JCPL), its syntax and notable language features. Web developers used to HTML, CSS and JavaScript should feel right at home. C# developers will recognize aspects such as Lambdas and LINQ and be able to write Services that augment the JCPL with traditional imperative coding.

The JaernCloud Programming Language is Domain Specific Language for Web Development. In broader terms it's a dynamic object-oriented programming language written in C# on top of the Dynamic Language Runtime. The object-oriented aspects of the language focus on tree structures and their transformations. The syntax is a hybrid inspired by CSS, JavaScript, HTML, LINQ and specifically target at unifying web development into a single coherent language.

Language Design Goals

The JaernCloud language was designed with the following in mind:
  • Short, concise and expressive syntax.
  • Minimal learning curve for web developers, allowing them to leverage existing experience with MVC frameworks and languages such as JavaScript, CSS, HTML, C# and LINQ.
  • Trees, nodes and transformations are first class citizens in the language.
  • Fundamental aspects of web programming are first class citizens in the language. This includes client technologies such as HTML, CSS, DOM and AJAX, while the server side includes data modelling and persistence, dependency injection, LINQ to name a few.
  • Integration with other .NET languages using the Dynamic Language Runtime.
  • Integration with Visual Studio 2010.
  • Convention over configuration.

JaernCloud Language Introduction

We have a PDF version of the JaernCloud Language Introduction which is a great way of getting started with JaernCloud.

10 Things to know about JaernCloud

The following list outlines some of the basic concepts and rules on which JCPL is built. Things will become more apparent as we walk through an example after the list.
  1. All objects in JCPL are nodes in a tree, and by that definition they have parent and child nodes
  2. Declaring a node in the tree is like declaring a new variable using an identifier
  3. The identifier for a node is made up of three concepts: tag names, tag ids, tag classes
  4. Top level nodes in the tree are required to have a unique identifier
  5. The identifier scope of a node is determined by its parent
  6. Nodes can inherit from other nodes using node selector expressions that match identifiers in parent scopes
  7. A node can inherit from multiple nodes
  8. A node has a value that may be undefined, or up to multiple values. In case of multiple values, the last declared in the inheritance hierarchy takes effect
  9. When node A inherits from node B, values and child nodes from B are merged into node A
  10. Nodes can choose to augment the default inheritance behavior based on which node is attempting to inherit. For example, when a node inherits from the built-in "integer" node, a new integer node with it's very own integer as value is returned and merged into the inheriting node.

Ajax Counter Example - A Walk-through

This section uses a simple Ajax counter example to put things into context. The example implements a page which displays a counter that is incremented using ajax when the link is clicked.

// ajax counter example

model#counter {
    count : integer
page#index {
    counter : model#counter
    -> add { counter.count++ }

css#site {
   body {
	font-family: Verdana;
view#index : page#index, css#site, html {
    body {
        p { "Counter: {counter.count}" }
        a { "Click me" -> ajax add }

First we declare a global model node with the id counter. We will use this node to store the number of times the user clicked the increment link on the page. Model is one of the reserved node names in JaernCloud and already has behavior built-in. As you might have guessed, model nodes represent the data model of the web application. Model nodes can be anything from short lived to database persisted. This is also called the bean/object scope, and will be familiar to developers who used the Spring or similar frameworks. In JaernCloud we refer to it as object scope (not be be confused with identifier scope).

In this example we didn't choose an object scope for the model. This means that JaernCloud will choose an object scope for us based on how we use the model. Since we have an Ajax action that increments the counter in the model, the model will be conversation scoped, which means that each traditional GET request uses it's own model, but it will be reused as long as we perform ajax requests. This in turn means that the integer kept in the count node of the model can be incremented.

Next, we declare a page node, which is also one of the built-in nodes. The purpose of a page node is to gather all the models and other information that the view node will need access to. Also the page node provides the functionality a view can invoke in response to client interactions, such as the link that increments a counter. For this example we bring in the model instance and make it available to the view as a node named counter. Below the counter we declare an action node using the "->" operator. The action is named add and has one rule which increments the counter. Page nodes are request scoped.

Before we get to the view node, we declared a simple css node with the id site. Like model and page, the css node is one of the built-in nodes. It's the last remaining piece before we have all the nodes that make up a view. The css node is a special node in JaernCloud for a number of reasons:
  • Children of the css node can be other css nodes or a traditional css rule like the CSS Specification outlines.
  • If a child node is a traditional CSS rule JaernCloud considers it to be a unnamed nodes - no name, class or id. It's just a tag selector.
  • When a node is unnamed it will be placed as a child node to any node that matches the tag selector. This is is essentially the behavior a browser has.

With this node structure for CSS you can reuse existing skills and add if needed the node transformations of JaernCloud to achieve inheritance for CSS rules. Also, it's worth noting that since the JaernCloud compiler natively understands the relationship between CSS nodes and HTML nodes, refactoring either without breaking code just became a whole lot easier.

The view node is where everything comes together. Like the page node, a view node is request scoped and one of the built-in nodes. The view node is a typical example of multiple inheritance. In this case we bring in page#index to get access to the counter node and the add action. We also inherit from css#site to use the site style sheet for the page. Finally we inherit from html that contains all the default HTML markup used to render the page in valid HTML. The rules for inheritance allows us to override any of the nodes the view inherited from html - one example would be to specify a title.

When a view node is declared it's made available as a URL on the web server based on the following:
  • The id of the view itself
  • If the view is in a sub folder of the web project, this folder name is prefixed to the URL
  • The id index is considered the default id for each folder

In this case, let's say we're in the root of the web project. This means that the view will be available at "/" since the folder and ids all collapsed into empty strings. This is the default "by convention" URL mapping behavior for views, but you're free to tweak the URL mappings if you want.

Reserved node names

The following nodes are built-in and provide behavior such as specialized inheritance.

Reserved keywords

Syntax and Operators

The following is an overview of the operators available in JaernCloud.

Operator category Operators
Node inheritance : ,
Node inheritance selector $
Node inheritance global selector $$
Node body { } ;
Node id #
Node class .
Node action ->
Node event @
Node template ...
Node attributes = " '
Node validation .. < <= > >= !=
Node URL mappings / **
Node Parameter ?
Member access .
Logical ! && ||
Indexing [ ] ..
Increment, decrement ++ --
Arithmetic + - * / %
Relational == != < > <= >=
Backslash \


  • single quote '
  • double quote "
  • variable expansion

Last edited Sep 27, 2011 at 5:30 PM by jimmeyer, version 43


No comments yet.