magic.lambda

magic.lambda is where you will find the “programming language keywords” of Hyperlambda. It is what makes Hyperlambda Turing complete, and contains slots such as [for-each], [if], and [while]. If you want to learn more, this is probably where you should start.

Notice, you do not need to master these slots to use Magic - the Hyperlambda Generator writes the code for you from plain English. This reference exists for when you want to read, understand, or hand-modify what the machine created.

Reference documentation

The slot reference is organised by concept, with one page per concept.

How Hyperlambda invokes slots

At the heart of Hyperlambda is the [eval] slot. This slot is responsible for executing your lambda object and follows a couple of simple rules. All nodes starting with a ”.” will be ignored, and [eval] will not try to raise these nodes as signals. This has two benefits.

  1. You can create “hidden” slots, that are only accessible from C#.
  2. You can use nodes starting with ”.” as data nodes, separating function invocations from data.

[eval] makes Hyperlambda “super functional” in nature. Below is an example of a Hyperlambda piece of code, that illustrates this, by adding a “callback” lambda object to its [while] invocation as a [.lambda] node, that will be invoked once for every iteration of your while loop.

.no:int:0

while
   lt
      get-value:x:@.no
      .:int:20
   .lambda

      // Your lambda goes here.
      log.info:Howdy from while
      math.increment:x:@.no

Hyperlambda tokens

The separating of a node’s name and its value is done by using a : character. To the left is the node’s name, and to the right is its value. The value of a node can also be a C# type of string, using double quotes, and even single quotes, or prefix your opening double quote with an “@” character, allowing you to use carriage returns in your strings the same way you can in for instance C#. Below are some examples.

.str1:"   This is a \r\n  string"
.str2:' This is also a string '
.str3:@"This
    is
  also a
      string"

Strings in Hyperlambda can be escaped with the exact same semantics as you would escape your C# strings, including referencing UNICODE characters in your strings. Hyperlambda is always serialized using UTF8, so you can add any UNICODE characters in your Hyperlambda you wish. Just make sure you save your files as UTF8 if you are using an external code editor to edit your Hyperlambda files.

How to comment your Hyperlambda code

Hyperlambda accepts comments the exact same way C# does, and you can use either multiline comments or single line comments, like the following example illustrates.

/*
 * Multiline comment.
 */

// Single line comment.

You cannot put comments on lines containing nodes, and comments must be indented the same amount of indentations as the nodes they are commenting, implying the nodes below them. Below is an example.

.data
   foo1:bar1
   foo2:bar2

for-each:x:@.data/*

   // This is correct indentation.
   set-value:x:@.dp/#
      .:Loop was here ...

Since Hyperlambda is using spaces (SP characters) to denote scope, indentation is important, also for comments. If you de-indent the above comment, you might get unpredictable results, in particular if you’re serializing and de-serializing your Hyperlambda preserving comments. Comments should as a general rule of thumb be applied with the same amount of indentation as the node below them.

Hyperlambda data segments

Hyperlambda does not separate between a “variable” and a “function invocation”. Hence, a node might serve as both at the same time. This allows you to dynamically modify your lambda structure, as you traverse it and execute it. But this creates another problem for you, which is that you will need a mechanism to store data. This is accomplished by prefixing a node’s name with a . character, at which point the Hyperlambda evaluator will ignore it, as it is traversing your tree, and not attempt to signal that particular node as a slot. Think of all nodes starting with a . character as “data segments”, or variables for that matter. Below is an example where [eval] will simply ignore the [.src] node and the [.dest] node, not attempting to invoke these as slots, but treat these as “data nodes”.

.src:foo
.dest
set-value:x:@.dest
   get-value:x:@.src

If you change name of the above [.src] node to simply [src], your code will raise an exception, with an error such as follows “No slot exists for [src]” since this slot doesn’t exist in your Hyperlambda vocabulary - Unless you for some reasons have an installation where this slot has been explicitly added to your vocabulary.

Hyperlambda documentation conventions

When we document Hyperlambda slots, and nodes, which are almost the same, we will document the node’s name with square brackets surrounding it, such as [this] illustrates, where “this” is referencing a node, and is the name of a node. We will also make such node references bold, to make them more easy to see.

Lambda expressions

Hyperlambda is heavily using “lambda expressions”. Think of these like XPath, except instead of referencing XML nodes they’re referencing Hyperlambda nodes. You can find the documentation for expressions in the magic.node project.

Topics

  • Hyperlambda internals - Everything is a slot in Hyperlambda.
  • Hyperlambda structure - Hyperlambda is the textual representation of a node structure, where each node has a name, an optional value, and a collection of children nodes.
  • Extending Hyperlambda with C# - To understand the relationship between C# and Hyperlambda, it might be beneficial for you to analyze the following code.