Aista – Magic Cloud – Generate a CRUD app in seconds

Categories
Hyperlambda

An introduction to Hyperlambda

The purpose of Hyperlambda is to have a programming language that allows your computer to generate most of your code.

An introduction to Hyperlambda – Aista

The purpose of Hyperlambda is to have a programming language that allows your computer to generate most of your code.
However, sometimes you need to manually modify the generated code yourself, and/or create Hyperlambda code manually,
at which point you’ll need to understand Hyperlambda. Hyperlambda is extremely easy to learn though, and you can
probably teach yourself most of its basics in less than 10 minutes. This article is an introduction to Hyperlambda
and gives you an overview of Hyperlambda from a bird’s perspective.

Structure

Syntactically Hyperlambda resembles YAML, however it has its own unique syntax, and even though it has the same readability
traits as YAML, it is not the same. In theory we could have used YAML, JSON, or XML to create Hyperlambda, but that would
increase its verbosity, resulting in more difficult to read code. However, its structure is easily understood in 5 minutes,
since it is literally just a text representation of a tree structure. Hyperlambda’s structure is based upon “nodes”,
and each node has 3 properties.

An introduction to Hyperlambda – Aista

  • Name
  • Value
  • Children

To illustrate imagine the following Hyperlambda.

.data
  foo1:bar1
  foo2:bar2

The above Hyperlambda consists of 3 nodes. The first node is called [.data]. This node has two children called [foo1]
and [foo2]. Both of these nodes have a value each being “bar1” and “bar2”. The colon separates the node’s name and
its value, and 3 spaces opens up the children collection. To play around with Hyperlambda you can use Magic’s “Evaluator”
component. Below is a screenshot of a slightly more complex example.

An introduction to Hyperlambda – Aista

The Hyperlambda evaluator

The above example is of course more complex than our first code snippet, but it still follows the exact same structure
being name/value/children. In the above example the [while] node is given two children arguments; One condition node being
its [lt] parts, and another lambda object being its [.lambda] parts. The [while] loop will execute its
[.lambda] object for as long as its condition is true. The condition again is an [lt] condition, implying “less than”.
Translating the above Hyperlambda to English hence becomes the following.

Execute .lambda while .no has a value less than 20

Inside [.lambda] we’re creating a log entry before we increment the [.no] value. Magic
contains many similar conditions, such as “more than”, “equal”, etc – In addition to a lot of additional “keywords”.
Refer to the magic.lambda documentation for an exhaustive list.

Code is data

The reasons why Hyperlambda is so good at creating and modifying code, is because there is no difference in Hyperlambda
between “code” and “data” – Implying code is data. The same way we can modify data structures such as XML, YAML, or
the HTML DOM for that matter, Hyperlambda allows for modifying its code. If you want to change the invocation to [log.info]
in the above screenshot to [log.error] this is as easy as adding the following Hyperlambda to the top of your code.

set-name:x:../**/log.info
  .:log.error

An introduction to Hyperlambda – Aista

This trait of Hyperlambda makes it very easy to create “self evolving code”, that somehow changes an existing snippet
of code to do something completely different. This trait of Hyperlambda is crucial for its ability to automatically generate
code and is the reason why it can with such ease create and generate code 100% automatically for you. When you think about
“how weird” Hyperlambda is, please understand its reasons for being weird. Hyperlambda’s “weirdness” allows us to easily
create templated snippets of code that we use as the foundation for some process automatically generating custom code, by
parametrising our code dynamically, such that we can modify it according to our specific needs.

Everything is code

The natural realisation of the above is that all data is also code. This creates a problem for us since we might
want to create nodes we don’t want to “execute”. This is achieved by starting a node’s name with a ”.”. This
instructs the Hyperlambda execution engine that this node should not be executed but simply ignored by the
Hyperlambda execution engine. This is what allows us to create “variables”, and/or nodes containing “data”.
You can see examples of such nodes in our previous code snippets and screenshots.

Expressions

Hyperlambda doesn’t have “variables”. This is because everything is a variable in Hyperlambda, including function
invocations, arguments to functions, etc. This creates a problem for us, being that we need some mechanism to modify
node names, node values, and their children collection. This is where expressions comes into the picture. An expression
allows us to reference any node in our Hyperlambda object. An example of such an expression can be seen in the above
screenshot where our invocation to [get-value] has the value of :x:@.no. Its :x: part declares it as an expression
type, while the @.no part is the actual expression. An expression is similar to chained LINQ statements in that it is a list
of IEnumerable objects, that reacts upon each other in a chain. Below is a slightly more complex expression to illustrate
the point.

.data
  foo1:bar1
  foo2:bar2
  foo3:bar3
 
set-value:x:../*/.data/*/foo2
  .:Hyperlambda was here

If you execute the above Hyperlambda in your Magic’s “Evaluator” component, you will see it changes the value “bar2”
to “Hyperlambda was here”. This is because the expression we give our [set-value] invocation basically says
the following.

Give me the root node, then all its children, then filter away everything not having the name of ‘.data’, find its children again, and filter away everything not having the name of ‘foo2’

When the expression is done filtering our nodes, we’re left with only the [foo2] node, at which point [set-value]
changes its value. To understand expressions and type declarations in Hyperlambda you might benefit from reading
about magic.node diving deeper into both expressions, iterators, and Hyperlambda’s typing
system. However, think of expressions as “pointers into your Hyperlambda object”, where each pointer is composed
from a chain of “iterators”, where each iterator is separated by a slash (/), and your expression as a whole can
point to zero or more nodes.

Slots

Hyperlambda doesn’t really understand the idea of function invocations. Instead everything is a “slot” in Hyperlambda.
However, for all practical concerns a “slot” is similar to a function invocation in a traditional programming language.
Magic contains hundreds of slots for all sorts of scenarios, and in the documentation for Magic we often refer to
these using square brackets in bold text. To modify parts of your Hyperlambda the following slots are your
most important friends.

  • [set-value] – Changes the value of one or more nodes
  • [set-name] – Changes the name of one or more nodes
  • [add] – Adds a bunch of children to some node
  • [insert-before] – Inserts a bunch of nodes before some node
  • [insert-after] – Inserts a bunch of nodes after some node
  • [remove-nodes] – Removes nodes

By combining the above slots you have everything you need to be able to change your Hyperlambda objects as they
are executing, resulting in a Turing complete programming language, even though it technically doesn’t have neither
functions nor variables. To see which slots are available you can click CTRL+SPACE on Windows or
FN+CONTROL+SPACE on a Mac while your code editor has focus to open the autocomplete drop down. Below is a screenshot
of the autocomplete drop down from Hyper IDE.

Hyperlambda autocomplete

Snippets

Magic’s “Evaluator” component contains a lot of Hyperlambda snippets illustrating some aspect of Hyperlambda. If
you click the “Load” button you can load existing Hyperlambda snippets demonstrating some aspect of the programming
language for you. The easiest way to start learning Hyperlambda is probably to go through these snippets, understand
what they do, for then to apply similar constructs in your own Hyperlambda. The [while] loop in the first screenshot
in this article is one example of such a snippet. You can also save your own snippets as you’re playing around with
Hyperlambda. Below is a video where I demonstrate Hyperlambda and what you can achieve with it.

Orchestration

Hyperlambda is an “orchestration programming language”. This implies that it is a super high level language,
intended for “orchestrating” programming building blocks. For these reasons some would argue it’s not
a “real” programming language, which would be a correct assessment. If you’re creating quick sort functionality
or polygon rendering algorithms in Hyperlambda, you’re doing something wrong. Hyperlambda is not intended for
algorithm heavy snippets, even though technically it is possible to implement anything in it. To understand
Hyperlambda’s position, realise its purpose is to sit between your algorithm heavy low level code, and the client,
“orchestrating” your low level building blocks, giving you dynamic capabilities on your code as a whole.

An introduction to Hyperlambda – Aista

Hyperlambda is for your code the same as YAML is for your pipelines, configurations, and Kubernetes cluster, in
that it allows you to “configure” your code together, using declarative concepts, from a high level abstraction
layer, where you don’t have to think about the internal details of your executing code. However, where YAML allows
you to configure deployment of your applications, Hyperlambda allows you to “configure” your application instead
of manually coding it using low level programming languages such as C# or Java. However, when that’s said, the
entirety of Magic is actually created in Hyperlambda, implying its middleware, the IDE, the SQL editor, everything
in fact, including the crudifier – And you can actually find this code inside your “system” folder if you’re
using Hyper IDE to check out its code. If you’re using heavy recursion, lots of nested while loops, and dozens
of temporary variables in your Hyperlambda code, you would probably be better creating this part of your code
in C# and expose your C# code as a “high level slot” to your middleware instead.