June 2017

Volume 32 Number 6

[C#]

Make C# More Dynamic with Hyperlambda

By Thomas Hansen

Traditionally, there have been just two types of programming languages: statically compiled languages and dynamically interpreted languages. What if there’s actually a third type of programming language, one that fits in neither of these categories and has the potential to make all other languages seem hopelessly rigid in comparison?

Hyperlambda is that language—a Turing-complete execution environment built entirely upon Active Events (see my previous article at msdn.com/magazine/mt795187). Hyperlambda is neither an interpreted language nor a compiled language. It doesn’t even have syntax. Hyperlambda is a non-programming language, perhaps even an anti-programming language. Technically, it’s not even a programming language at all. At its core, Hyperlambda is simply a relational file format that allows you to declare tree structures. Arguably, it has more in common with HTML and XML than with C# and JavaScript. It turns out, though, that tree structures just happen to be able to describe what we often refer to as execution trees.

Execution trees are what your CPU actually executes. All programming instructions can basically be understood as branches of a tree, which your CPU moves through as it evaluates your code. For instance, an if/else block creates two possible branches that are mutually exclusive, and your CPU chooses only one, depending on the results of the condition in the if statement. Essentially, what your computer does as it executes code is to move through an execution tree, manipulating its memory in the process. This implies that if you can describe an execution tree and manipulate memory, you can also describe anything you’ve previously described using C# and JavaScript.

Everything Is a Tree

Just like everything is a “list” in Lisp, everything is a “tree” in Hyperlambda. Here’s an example of some Hyperlambda pseudocode that creates an execution tree after being parsed:

if:condition
  do-x:argument1
else
  do-y:argument1

Parsing this code results in a lambda object. This lambda object, or execution tree, can be evaluated by invoking the eval Active Event in Phosphorus Five (P5). You can think of an Active Event basically as a “function object” that allows you to invoke a method created in, for instance, C#, with a graph object or a tree object as its only argument. P5 implements the Active Event design pattern.

Once such a lambda object has been created, the eval Active Event in P5 sequentially executes the root node’s children nodes, invoking these as Active Events, from top to bottom. The lambda object created in the previous example contains four nodes, two of which are root nodes. Hence, eval will execute the “if” before it executes the “else.”

Therefore, a lambda object becomes the “DOM structure” Hyperlambda creates. If I wanted to, I could’ve used XML instead of Hyperlambda to describe this tree structure. It just so happens that Hyperlambda is the superior method for describing such tree structures. It often helps to think of Hyperlambda as HTML or XML, and lambda objects as the resulting DOM structure.

Hyperlambda has an extremely simple syntax. All nodes can have a name, a value and children nodes. Here are all its major control structures:

  • A colon separates names and values of nodes.
  • Two spaces opens up the children collection of nodes.

A node’s value can optionally have a type declaration, squeezed in between the name and its value. The type declaration is optional, though, and rarely used. String is the default type declaration in Hyperlambda.

What Makes Hyperlambda Unique

A static language, such as C++ or C#, compiles its code down to some machine-executable thing up front, before it starts executing the result. A dynamic language, such as JavaScript, normally interprets the code on the fly, as it’s executing the code. Hyperlambda, in contrast, does neither. Instead, you declare an execution tree, which is parsed by P5, producing lambda objects that are then evaluated using the eval Active Event in P5. The lambda objects you create don’t even consider syntax, and you can use any file format capable of declaring relational tree structures to declare your lambda objects, which means that Hyperlambda ends up being no more of a programming language than HTML or XML are. However, because it’s still a Turing-complete execution environment, it allows you to do everything you can do with any other programming language. Arguably, I could’ve used HTML to declare my lambda objects, at which point HTML would’ve become a Turing-complete programming language.

Branching Your Tree

Every keyword in Hyperlambda is simply an Active Event. Invoking these Active Events often results in recursively invoking eval, according to some sort of condition. This makes Hyperlambda extremely extendible. Creating a new keyword literally means creating five lines of code. Here’s an example in C#:

[ActiveEvent (Name = "what-is-the-meaning-of-life?")]
private static void foo (ApplicationContext context, ActiveEventArgs e)
{
  e.Args.Value = 42;
}

In fact, both the if and else keywords are created as Active Events like this.

You don’t have to use C# to create Active Events or keywords. You can also create your own keywords in Hyperlambda:

create-event:what-is-the-meaning-of-life?
  return:int:42

The observant reader might realize at this point that although Hyperlambda is definitely a very high-level abstraction, at some philosophical level it’s also a very low-level abstraction—arguably far lower than any other existing programming language, because what you’re modifying isn’t code but the actual execution tree. This characteristic of Hyperlambda has huge benefits, the same way the DOM model has huge benefits for HTML and XML. First of all, it enables extremely flexible and self-modifiable code. This means that the separation between what is normally thought of as creating code and executing code becomes much thinner—allowing for code that does a little bit of both. Evaluating a lambda object with some input data might easily create new logic and additional branches in your execution tree. For example, if you don’t like a particular if/else block for some reason, you can dynamically remove it, even after you’ve started evaluating the lambda object containing it. In fact, your execution tree might look completely different, depending on the input data you supply to your lambda objects.

Just as you can use the DOM model to modify parts of your HTML page in JavaScript, you can use the “lambda object model” to modify parts of your lambda objects during execution. Literally, your execution tree becomes a dynamic entity that can change during execution.

Transforming back and forth between the Hyperlambda file format, which is serializable and persistent in nature, and lambda objects, which are execution trees, is as easy as invoking an Active Event.

Finding Your Branch

Among Hyperlambda’s other odd traits is the fact that it has no variables. I don’t mean no variables in the F# sense, where every­thing is immutable. I literally mean Hyperlambda has no variables! At this point, of course, you’re skeptical. After all, being able to change the state of your execution tree and memory is key to creating a Turing-complete execution environment. However, if you can change the state of your execution tree, you actually don’t need what we traditionally refer to as variables.

In Hyperlambda, everything can change. Changing anything in Hyperlambda simply implies referencing the nodes you wish to change and supplying a source for your change operation. So, the first thing that’s needed is a way to reference nodes in your tree, and this is done with lambda expressions, like so:

_data:Thomas
if:x:/@_data?value
  =:Thomas
  say-hello:Yo boss
else
  say-hello:Yo stranger

This code shows one lambda expression, which refers to the _data node’s value and is supplied as an argument to the if Active Event invocation. This if invocation compares the result of the lambda expression to the static value “Thomas,” and if the value of “_data” equals “Thomas,” it will evaluate the lambda object inside the if node. Otherwise, it will evaluate the lambda object in the else node.

A lambda expression can reference any nodes in your tree, and results in a subtree, based upon the original tree. The relationship between a lambda expression and a tree structure is somewhat analogous to the relationship between SQL and a table. Lambda expressions are easily visualized by those who have created XPath expressions. You can compare them to LINQ or “pre-compiled enumerators,” if you wish. The latter is actually how they’re implemented. If you believe that building LINQ queries dynamically adds value, purely logically you must believe that lambda expressions might possess value.

Pruning Your Tree

At this point, all that’s needed to have a Turing-complete execution environment is the ability to change parts of the tree. Here, I’m doing so with the “set” Active Event:

_input:Thomas
_output
if:x:/@_input?value
  =:Thomas
  set:x:/@_output?value
    src:Yo boss
else
  set:x:/@_output?value
    src:Yo stranger

The set Active Event basically works like the assignment operator in C#. At this point, we have a Turing-complete “non-programming language” that allows you to do everything you’re used to doing in a traditional programming language—without ever actually having created a programming language or even having considered syntax. Instead, you modify the execution tree directly as the lambda object is evaluated.

There are more Active Events you can use to modify your tree. For instance, “add” appends a bunch of nodes to the result of a lambda expression, leading to one or more additional nodes, while “insert-­before” and “insert-after” works similarly to add, except that they inject one or more nodes before or after a bunch of nodes. To remove nodes, values, or names is as easy as not supplying a source to set, at which point it will simply remove the node, its value, or its name, depending on what type declaration you use for your expression.

Using constructs like these makes C# a super-dynamic programming language by giving the programmer the tools needed to be able to change the execution tree directly. Arguably, these traits of Hyperlambda make it the most dynamic programming environment on the planet by far. Even super-dynamic languages, such as Lisp and JavaScript, seem hopelessly static and rigid in comparison to Hyperlambda.

At this point, you might realize that in Hyperlambda, there’s absolutely no difference between data and logic—logic is data and there are no semantic differences at all between the two. This implies that you can just as easily change your logic as you can your data, which, in turn, results in a super-dynamic execution model where your execution tree might completely change during its execution. Just how cool this is can be illustrated with a few highly instructive use cases.

Nurturing Your Tree

Use case 1: Imagine you have 100 records in your database. Each record contains some Hyperlambda. If you wish, you could select all these records, transform them into lambda objects and append them to a destination lambda object, evaluating their combined result afterward. You could even create a new single function object out of these records, persist them to a file on disc and use this file in the same way you’d invoke a function.

Use case 2: If you want, you can evaluate only half of a function, removing the parts of the function you don’t want to execute. As far as I know, no other programming languages on the planet have this capability. It happens to be an extremely useful feature.

Use case 3: You can, if you need to, extract half of the lambda objects from five different functions, creating a single new function derived from the “better parts” of your original functions.

How is this possible? One lambda object can transform any other lambda object the same way an XSLT file can transform an XML file. If you don’t want to execute any while loops in your system, for whatever reason, you can easily create a lambda object that transforms all of your while loops and turns them into for-each loops and have it run in the background as an automated process.

In case you hadn’t realized, this is how HTML works in relationship to its DOM model. In Hyperlambda, modifying lambda objects is as easy as inserting, modifying or deleting an HTML element in your DOM with JavaScript. If you think this capability adds value to HTML, purely logically you must agree that this could potentially add value to “logic.” Hyperlambda opens up a completely new dimension with regard to software development.

Use case 4: Consider the CMS in System42 (bit.ly/2pwMOY9). This CMS allows you to create lambda pages, which instead of simply displaying static HTML, are 100 percent dynamic and interactive in nature. “Big deal,” some might argue, claiming that PHP can at least in theory do the same thing. However, these lambda pages are also reusable components. The dynamic nature of Hyperlambda means you can, for instance, check for the existence of a “parent-­widget” argument during the execution of your lambda page and, if it exists, instead of creating a page, you can inject the same page as a user control into another widget on your page.

In fact, you don’t even have to modify your original page; you can instead transform its lambda object before you evaluate its “create-widget” invocation. To categorize things as absolutes the way you’re used to in traditional programming languages is completely meaningless in Hyperlambda.

The result is that every single lambda object you create in Hyperlambda is also a potentially reusable component you can inject into other parts of your system. This implies that you can incrementally create increasingly complex systems, building on systems you’ve previously created. In a traditional programming language, you’d have to choose between building a system or building a reusable component. In Hyperlambda, such mutually exclusive choices are meaningless, and everything tends to become a little bit of everything else. Hyperlambda’s reusability features completely dwarf everything you’ve ever seen before in your programming life.

Use case 5: In Hyperlambda, you can actually recursively execute a folder on disc, passing in arguments to the execution, eliminating everything that used to constrain you in traditional programming. Or you can invoke a file exactly as you’d invoke a function, having the invocation of your file return multiple values to its caller. You can also easily invoke the body of an HTTP POST request transmitted to your server, effectively replacing every single Web service endpoint you’ve ever created with five to 15 lines of code. All of these are things I do almost every single day as I use Hyperlambda.

Use case 6: In Hyperlambda, even thinking about a Web page as purely a Web page is meaningless because just by replacing a single assembly in your application pool you can easily create a Windows Forms application using the exact same code. In Hyperlambda, reusing the same code base for your Web apps and Windows Forms apps is actually ridiculously easy—even the GUI parts of your code.

When I show Hyperlambda to other software developers, some tend to dismiss it because Hyperlambda seems to be much more verbose than traditional programming languages. For instance, the previous code example could easily have been described with a single line of code in C#, while in Hyperlambda it took nine lines. For simple tasks, Hyperlambda is admittedly sometimes more verbose. However, Hyperlambda features one trait that mitigates this issue—the capability to transform lambda objects, which gives you code that’s much less verbose in the long run. So, basically, you pay a small price up front—more verbose code in the short run—to end up with far less verbose code in the long run. This allows you to deliver far more functionality with far less effort. Hyperlambda enables exponential software productivity growth. Let that last sentence sink in a little bit, please.

Hyperlambda’s Hello World

The following is the “Hello World” application created in Hyperlambda. If you paste this code into, for instance, a lambda page in the System42 CMS, you’ll create a button that, when clicked, changes its inner value to “I was clicked.” Download P5, and try it out by starting the Apps/CMS app. Then create a lambda page and paste in this code:

create-widget:foo-widget
  element:button
  class:btn btn-default
  innerValue:Click me!
  onclick
    set-widget-property:foo-widget
      innerValue:I was clicked

Seven lines of Hyperlambda arguably replace potentially hundreds of lines of code in JavaScript, C#, or HTML, depending what framework, library, or language you use to create something similar. And if you read through the code carefully, you can probably guess what HTML markup it will produce. Hyperlambda tends to be closer to natural language than other programming languages. Linguistically, it resembles the way humans naturally convey information to other humans more closely than, for example, C# or JavaScript.

As an additional bonus, if you create your own Windows Forms assembly, using an alternative implementation of the previously mentioned create-widget Active Event, you can use the exact same code to create a Windows Forms application.

Is Hyperlambda a Silver Bullet?

I’ve been accused of advertising silver bullets for as long as I’ve advocated Active Events. I admit that some of my claims probably sound like magic. And, yes, Hyperlambda creates more verbose code initially, as well as adding more overhead to the execution of your programming instructions, due to its internal implementation semantics. I also occasionally find bugs, and I do refactor my things, resulting hopefully in better code. Obviously, Hyperlambda is not perfect.

However, Hyperlambda’s biggest problem is actually in your head. Hyperlambda completely invalidates everything you’ve been taught for the last 50 years as best practices for software development. And it does it with style, putting its money where its mouth is!

At the end of the day, though, the answer to whether Hyperlambda is a silver bullet is not one I can give you. This is something you’ll have to figure out for yourself. It may help to check out an example of a GMail clone, Sephia Five, built entirely in Hyperlambda (github.com/polterguy/sephia-five). Sephia Five features PGP cryptography and 100 perfect perfect virus and malware protection, and it works on all devices capable of displaying HTML. Sephia Five is also several orders of magnitudes more efficient in bandwidth usage than GMail. And its initial release was literally built in five days, from scratch. All of these claims can be checked, verified, and mathematically reproduced and proven!

To learn more about Hyperlambda, feel free to read the guide at github.com/polterguy/phosphorusfive-dox. And you can download Hyperlambda along with Phosphorus Five at github.com/polterguy/phosphorusfive.


Thomas Hansen has been creating software since he was 8 years old, when he started writing code using the Oric-1 computer in 1982. Occasionally he creates code that does more good than harm. His passions include the Web, AJAX, Agile methodologies and software architecture.

Thanks to the following Microsoft technical expert for reviewing this article: James McCaffrey


Discuss this article in the MSDN Magazine forum