Pruning your Hyperlambda tree
Tags: webdev, programming, tutorial
Published: 2022-06-19 10:46:00

Since we've now established that Hyperlambda is a unique meta programming language, with the capacity to [dynamically construct graph objects](https://dev.to/polterguy/hyperlambda-a-meta-programming-language-31np), a natural question becomes; _"How do we modify these graph objects?"_ The answer to that question is almost as easy to understand as CRUD itself, because at Hyperlambda's core exists a handful of slots capable of modifying your execution trees. The main ones are as follows.

* __[set-value]__ - Changes a node's value
* __[set-name]__ - Changes a node's name
* __[add]__ - Adds nodes to another node's children collection
* __[insert-before]__ - Inserts nodes before some specified node
* __[insert-after]__ - Insert nodes after some specified node
* __[remove-nodes]__ - Removes the specified node(s)

The above list of slots allows you to orthogonally modify your tree structures anyways you see fit. Below is an example of using the **[add]** slot with a static source.

```
.destination
add:x:@.destination
   .
      foo:bar
```

Executing the above in your Evaluator results in the following.

```
.destination
   foo:bar
add:x:@.destination
```

All of the above slots can also be combined. The above example for instance adds a list of statically declared nodes into the **[.destination]** node. Sometimes you want to add nodes from one node-set to another, at which point you can combine the **[add]** node with the **[get-nodes]** slot, such as illustrated below.

```
.src
   foo1:bar1
   foo2:bar2
   foo3:bar3
.destination
add:x:@.destination
   get-nodes:x:@.src/*
```

If you execute the above Hyperlambda in the evaluator, its result will resemble the following.

![Adding nodes from one node collection to another](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6djjy9qk4zozxx2dfbge.png)

Such simple trickery as illustrated above, allows you to have complete control over the way you create and modify your lambda objects. The **[set-name]** and **[set-value]** slots works in a similar fashion, either taking a statically declared value, or some other nested slot retrieving the source. Below is an example.

```
.dest1
.dest2
.src1:foo
set-value:x:@.dest1
   .:value
set-name:x:@.dest2
   get-value:x:@.src1
```

After executing the above in your Magic Evaluator component, you'll be given the following result.

```
.dest1:value
foo
.src1:foo
set-value:x:@.dest1
   .:value
set-name:x:@.dest2
   get-value:foo
```

## Lambda transformations

As you've probably realised by now, executing a lambda object typically transforms that lambda object into something else. Hence, the same lambda object cannot be executed twice and expecting the same result. Magic of course automatically takes care of this for you, by giving you a _"fresh copy"_ of your original Hyperlambda file as you invoke it, for then to discard the lambda object after execution. However, this has huge advantages when it comes to _dynamically generating code_.

This is what allows you to start out with something, and end up with something else, a requirement for dynamically generating code of course. Hence, everything is literally about _"transformations"_ at Magic's core.

Fundamentally, this model of thinking about code is actually much easier to understand for the human mind, since it's much closer to the way any computer process works, in that it takes input, acts upon the input, and produces a result. So even though [your brain probably has suffered severe damage du to too much OOP](https://dev.to/polterguy/oop-a-software-development-mass-psychosis-9n4), this is a much more natural process of thinking about computing for most.

## Database fun

Assuming you've already [installed the Chinook database](https://dev.to/polterguy/create-a-web-api-backend-in-seconds-no-coding-required-2mji), let's create a new file in Hyper IDE, and name our file _"foo.get.hl"_ and put that file into our _"chinook"_ folder. Below is a screenshot of how to create a new file in Hyper IDE.

![Creating a new file in Hyper IDE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqebtrr3op4h22crc8cq.png)

Make sure you have selected your _"chinook"_ folder before you click the _"New file"_ button. This will bring up a modal dialog resembling the following. Make sure you name your file _"foo.get.hl"_.

![New file dialog in Hyper IDE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0j6ubq47dh741aqo6r2t.png)

This will create a new HTTP GET endpoint for you, where you can put any Hyperlambda you wish. Copy and paste the following Hyperlambda into the file, and click the _"Active file/Save"_ action menu button afterwards.

```
sqlite.connect:chinook
   sqlite.select:@"select ar.Name, count(*) as count
     from Album al, Artist ar where al.ArtistId = ar.ArtistId
     group by al.ArtistId
     order by count desc
     limit 5"
   return:x:-/*
```

Below is a screenshot of how it should look like as you save your file.

![Saving a file in Hyper IDE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/umy7udffwci8ewvjyxqv.png)

Notice, you can also use the keyboard shortcut ALT+S on Windows or OPTION+S on Mac to save your active files faster.

If you click the action menu called _"Active file/Invoke..."_ you can now immediately invoke your HTTP endpoint. This should look like the following.

![Invoking your HTTP endpoint](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fkvqa3ei1ukfzj2daczb.png)

Notice how the **[return]** keyword simply returns a list of nodes. You could replace the code with the code below, which would give you a _"weird result"_.

```
sqlite.connect:chinook
   sqlite.select:@"select ar.Name, count(*) as count
     from Album al, Artist ar where al.ArtistId = ar.ArtistId
     group by al.ArtistId
     order by count desc
     limit 5"
   return-nodes:x:..
```

The above of course returns your entire lambda object as JSON back to your client, which is only possible because fundamentally in Magic there is no difference between code and data. Below is parts of the result invoking the above would result in.

```
[
  {
    "sqlite.connect": {
      "sqlite.select": [
        {
          "Name": "Iron Maiden",
          "count": 21
        },
```

## The Hyperlambda space time continuum

In a way, this is the computing equivalent of the space time continuum, where there is no difference between space and time, the same way Hyperlambda doesn't discriminate between code and data.

> In Hyperlambda code IS data and vice versa

Initially this is super weird if you've created software in a traditional programming language, but after a while it becomes easily understood, and frees your mind in ways difficult to understand initially. And most importantly of course ...

> It allows the machine to create the code


![The space time continuum of showing your tongue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/um7g0hvvvsoaoky22t06.jpeg)