Aista – Magic Cloud – Generate a CRUD app in seconds

Hyperlambda Course 101

In this course we will walk you through everything you need to know to become a professional Hyperlambda software developer in 5 hours. The course starts with the hello world application, and goes through every aspect of Hyperlambda to turn you into a master.

Get started

First you’ll have to create a Magic demo cloudlet. The cloudlet will serve as your development environment, so there are no downloads required to get started. You can create as many databases and write as much Hyperlambda and SQL in your cloudlet as you wish. Notice, unless you upgrade to a professional cloudlet within a month, the cloudlet will be automatically destroyed.

Sign up below and create a new Magic demo cloudlet if you haven’t already done so, and let’s get started.

Create a new backend cloudlet
Session 0, Introduction

This is the introduction to the course where we will be talking about Hyperlambda in general to give you some motivation to go through the course. Your instructor is Thomas Hansen the CEO of Aista.

If you need help during the course, you can either chat with us directly from hub, or create a ticket from inside hub, allowing you to attach screenshots and show us your code. Our typical response time is less than 2 minutes.

Session 1, Hello World

In this session we will create our hello world HTTP endpoint in Hyperlambda. We will also look at Hyperlambda’s syntax, and see how to save Hyperlambda snippets on your server for later.

The course is intended to be a hands on course, so you will have the most value out of it if you manually write the same code as I am writing as I am going through concepts. At the bottom of this page you will find all Hyperlambda snippets I create, but please try to write out the code yourself before simply copying and pasting what I do.

Session 2, How the Machine Creates the Code

In this session we will go through how the machine can create code, and create some Hyperlambda snippets that automatically generates code for us.

First we will dynamically create Hyperlambda code and store it into a database, allowing us to look at the SAL database designer. Afterwards we will create Hyperlambda snippets that modifies our existing endpoints. You will learn how to use the SQL database designer, the CRUD generator, in addition to the basics of Hyperlambda transformations.

Session 3, Changing your Tree

In this session we will look at how we can modify our Hyperlambda graph objects, or tree structures. We go through constructs such as [add], [insert-before], [set-value] and [set-name].

These are the basic building blocks of Hyperlambda that allows it to generate self evolving code, and results in that the machine can create your code.

Session 4, Dynamic slots and Executing files

In this session we will look at how we can modify our Hyperlambda graph objects, or tree structures. We go through constructs such as [add], [insert-before], [set-value] and [set-name].

These are the basic building blocks of Hyperlambda that allows it to generate self evolving code, and results in that the machine can create your code.

Session 5, Multi threaded Programming

In this session we will teach you how to create multi threaded Hyperlambda code. Multi threaded programming allows your machine to execute multiple code snippets at the same time, and is often referred to as parallelised execution.

Although Hyperlambda is a very high level programming language, it has some unique scalability traits, and also allows you to easily apply multi threaded programming constructs, allowing you to create high performance software, typically much better performing than the equivalent PHP and Python programs.

Session 6, The LowCode Angular CRUD datagrid generator

In this session we will look at the Angular code the CRUD generator automatically generates for us, and analysie it, to help you maintain it and extend it yourself.

The Angular datagrid generator creates a starting point for you automatically. You typically still need to modify the generated result. This video teaches you how to understand the Angular code Magic generates.

Session 7, Authentication, Authorisation and JWT

In this video you will learn how the authentication and authorisation parts works in Magic and Hyperlambda. In addition we will study JWT, and look at how Magic internally secures your data by using cutting edge security concepts preventing malicious users from accesing your data.

This creates the foundation you will need to implement your own authentication and authorisation logic.

Session 8, Analysing the CRUD generator's output

In this session we will analyse the CRUD API generator’s output, to understand the code magic creates as it is automatically generating your CRUD API.

We will look at how each CRUD verb transforms into an HTTP verb. We will look at how each CRUD verb encapsulates a CRUD SQL slots form Hyperlambda. And we will look how Magic allows you to pass in arguments to your endpoints by creating Hyperlambda endpoints wrapping one of the CRUD verbs from SQL.

Session 9, Exercise, create a custom authentication endpoint

This is an exercise video, where I will give you a specification for a Hyperlambda endpoint, allowing users to authenticate, such that you’re using your own custom database for usernames and passwords.

It will teach you how to create a custom authentication database, how to read records from said database, and verify the passwords are corrrectly given by the client, before you create a valid JWT token and returns to caller.

Session 10, The solution to the authentication exercise

In this session I will show you how I would solve the exercise from the previous session, by creating a custom authentication endpoints myself, following the specification given previously.

We will look at [auth.ticket.create], and other constructs, such as [if] and [else]. In addition we will create our own login endpoint, accepting a username and a password, and verify the username and password combination is correct before returning a JWT token to the caller.

Session 11, The [unwrap] keyword

When dealing with dynamic lambda objects such as those found in Hyperlambda, we sometimes need to forward evaluate expressions, implying evaluate expressions before they are being executed.

In this video we will teach you how the [unwrap] keyword allows you to do just that. And how it is crucial to understand, especially when dealing with lambda objects passed around, or returned from slots.

Session 12, Create a CRM system exercise

In this session I will give you a specification for a CRM system I want you to create.

Before you start smashing your keyboard, I encourage you to think about how you can leverage components from Magic to your advantage. Some examples here are SQL Studio and its database designer, the CRUD generator, and the frontend datagrid generator.

Session 13, Implementing a CRM system

In this video I will show you how I would tackle the specification from the previous exercise, by creating a CRM system myself, and finishing the whole project in no more than 21 minutes.

I will show you some tricks related to visually designing your database using SQL Studio. I will show you some tricks related to the CRUD generator. And at the end of the video, I will show you a complete micro CRM system.

Session 14, Exercise, create a task management system

In this session I will give you a specification for a task management system I want you to create.

Also with this exercise it becomes important to imagine how you can leverage the automation constructs in Magic before you start pounding out code. Remember, the whole idea about Magic, is that the machine can create your code. Use it for what it is worth.

Session 15, Implementing a Task Management System

Here I will show you how I would chose to solve the exercise from the previous session, by implementing a task management system myself.

This time we will look at how you can generate a CRUD API twice wrapping the same database table, allowing you to apply different business logic each time. This allows you to create fairly complex type of functionality, still without having to manually code anything at all.

Session 16, What can you use Hyperlambda for?

In this session I will talk loosely about what you can use Hyperlambda for, explaining the benefits, while giving you some example use cases for things it’s useful for.

Since Hyperlambda is arguably a “4th generation programming language”, there are things you cannot use it for. In this video I will give you an honest assessment of where it is useful and where it falls short.

Session 17, Record slicing in Hyperlambda

In this video I will show you a nice feature in Hyperlambda, how it implicitly allows for “record slicing”, which when it comes to SQL and data manipulation, simplifies your life as a developer a lot.

Record slicing is the ability to do partial record updates, and it’s at the core for everybody being serious about creating multi user systems, since it eliminates an entire axiom of problems related to data manipulation and race conditions.

Session 18, Database CRUD slots and SQL slots

In this video I will go through the different ways Hyperlambda allows you to access your SQL database.

In Magic there are two different ways of manipulating and reading your data; There are the CRUD slots, and the basic SQL based slots – The latter allowing you to execute “raw” SQL towards your database.

Session 19, Branching and looping

In this session we will go through conditional branch statements, such as [if] and [else]. In addition we will look at how to create loops and iterate over data nodes.

Conditional branching and looping is at the core of every programming language, and what allows you to apply “logic” to your code. This session teaches you the basics of how to apply these constructs into your own Hyperlambda code.

Session 20, When the Machine Speaks with the Machine

In this video we will look at how to semantically transmit Hyperlambda code from one machine to another machine.

This might sound like madness, since it allows another machine to execute code on your machine. However, in Hyperlambda, this is quite easy to apply in a secure manner, preventing the client from transmitting malicious code, by only allowing the client to use a subset of your server’s [vocabulary].

Session 21, Web sockets in Hyperlambda

Web sockets allows the server to “push” data to the client. This is useful for a lot of different use cases, such as chat clients, stock tickers, etc.

In this session I will teach you how to use web sockets in Hyperlambda, allowing you to push data from the server through a bi-directional socket, allowing both parties to push data to the other party.

Session 22, Exercise, create a Chat Client

In this session we will give you another exercise. This time we ask you to implement a chat client. It doesn’t have to be complex or support multi users, multiple chat rooms, or anything fancy. The idea is just to get your creativity started.

You will have to use web sockets to pull this through, correctly at least. The exercise will therefor teach you how to “push” data from the server to the client, in addition to that it will also force you to create some Angular frontend code.

Session 23, Automatically generated Unit Tests

Unit tests are the foundation for being able to apply changes to your project. Magic allows you to automatically create unit tests, testing some parts of your code automatically, without having to manually write said tests.

In this session I will show you how you can use this feature from Magic to automatically generate “assumptions” that allows you to invoke some HTTP endpoint, and sanity check that it returns the expected result.

Session 24, Create a web API with SQL

In this session we will look at how Magic allows you to create a web API using nothing but SQL.

This is particularly useful if you’re highly skilled in SQL, but don’t know how to create a web API using for instance C#, Java, Python or PHP. This allows you to leverage your SQL skills, to create web APIs, without knowing anything but SQL, while have Magic taking care of things such as authentication, authorisation, argument passing, etc.

Session 25, Interceptors

Interceptors is one of those highly useful declarative constructs, that allows you to “intercept” HTTP invocations, for then to put common logic into your interceptor.

In this session I will show you how to create such interceptors, some of their advantages, and how the Magic endpoint resolver recursively and automatically applies your interceptor Hyperlambda.

Session 26, The Task Scheduler

One of Magic’s components is the Task Scheduler. This component allows you to dynamically create Hyperlambda tasks, for then to schedule these tasks as you see fit, to execute either at a specific time in the future, or at some pre defined interval you declare.

In addition we will look at how we can automatically create tasks, facilitating for business. process workflows, where some dynamic snippet of code is persisted into your database, for then to being executed as some “trigger” is occurring in the future.

Hyperlambda snippets

Below you can find some of the snippets we are creating during the course. To understand what they do, please watch the above video course, and refer back to the relevant snippet when I’m using it in the course.

tutorial-01-01
.foo
   foo1:bar1
   foo2:bar2
   foo3:bar3
.foo2
   foo4:bar4
      foo5:bar5
.dest
for-each:x:@.foo/*
   add:x:@.dest
      get-nodes:x:@.dp/#
tutorial-02-01
.lambda
   http.get:"https://microsoft.com"
   if
      eq:x:@http.get
         .:int:200
      .lambda
         log.info:Microsoft.com seems to be fine!
   else
      log.error:Microsoft.com is NOT OK!!
lambda2hyper:x:@.lambda/*
data.connect:code
   data.create
      table:snippets
      values
         content:x:@lambda2hyper
tutorial-02-02
.lambda
data.connect:code
   data.read
      table:snippets
      columns
         content
      limit:-1
   for-each:x:@data.read/*/*
      add:x:@.lambda
         hyper2lambda:x:@.dp/#
eval:x:@.lambda
tutorial-02-03
/*
 * Script that formats all Hyperlambda files recursively within
 * the specified folder.
 */
.folder:/modules/northwind/
io.file.list-recursively:x:-
for-each:x:-/*
   if
      strings.ends-with:x:@.dp/#
         .:.hl
      .lambda
         io.file.load:x:@.dp/#
         hyper2lambda:x:-
            comments:true
         remove-nodes:x:@hyper2lambda/*/auth.ticket.verify
         lambda2hyper:x:@hyper2lambda/*
            comments:true
         io.file.save:x:@.dp/#
            get-value:x:@lambda2hyper
tutorial-02-04
/*
 * Script that formats all Hyperlambda files recursively within
 * the specified folder.
 */
.folder:/modules/northwind/
io.file.list-recursively:x:-
for-each:x:-/*
   if
      strings.ends-with:x:@.dp/#
         .:.hl
      .lambda
         io.file.load:x:@.dp/#
         hyper2lambda:x:-
            comments:true
         insert-before:x:@hyper2lambda/*/data.connect
            .
               auth.ticket.verify:admin, root, guest, foo-bar
         lambda2hyper:x:@hyper2lambda/*
            comments:true
         io.file.save:x:@.dp/#
            get-value:x:@lambda2hyper
tutorial-04-01
slots.create:foo
   math.add:x:@.arguments/0
      get-value:x:@.arguments/1
   return:x:-
tutorial-04-02
slots.create:foo
   math.add:x:@.arguments/0
      get-value:x:@.arguments/1
tutorial-05-01
/*
 * Creates 4 fire and forget threads.
 */
fork
   http.get:"https://aista.com"
fork
   http.get:"http://microsoft.com"
fork
   http.get:"https://google.com"
fork
   http.get:"https://dzone.com"

/*
 * Creates 4 threads and waits for all threads to return
 * before it proceeds.
 */
join
   fork
      http.get:"https://aista.com"
   fork
      http.get:"http://microsoft.com"
   fork
      http.get:"https://google.com"
   fork
      http.get:"https://dzone.com"

/*
 * Creates 4 sequentially invoked HTTP GET invocations.
 */
http.get:"https://aista.com"
http.get:"http://microsoft.com"
http.get:"https://google.com"
http.get:"https://dzone.com"
tutorial-05-02
// Thread number 1, loads a file, concatenates to it, and saves the file again.
fork
   .lambda1
      semaphore:semaphore-thread
         io.file.load:/foo.txt
         strings.concat
            get-value:x:@io.file.load
            .:"Appended by lambda object 1\r\n"
         io.file.save:/foo.txt
            get-value:x:@strings.concat
   eval:x:@.lambda1

// Thread number 2, loads a file, concatenates to it, and saves the file again.
fork
   .lambda2
      semaphore:semaphore-thread
         io.file.load:/foo.txt
         strings.concat
            get-value:x:@io.file.load
            .:"Appended by lambda object 2\r\n"
         io.file.save:/foo.txt
            get-value:x:@strings.concat
   eval:x:@.lambda2

Hyperlambda Endpoints

Below you can find the Hyperlambda HTTP endpoints we are creating during the course.

tutorial01.get.hl

.arguments
   name:string
   age:int

strings.concat
   .:"Hello there "
   get-value:x:@.arguments/*/name
   .:", you are "
   get-value:x:@.arguments/*/age
   .:" years old"

unwrap:x:+/*
return
   result:x:@strings.concat

tutorial02.get.hl

.foo
   foo1:bar1
   foo2:bar2
   foo3:bar3
.foo2
   foo4:bar4
      foo5:bar5
.dest
for-each:x:@.foo/*
   add:x:@.dest
      get-nodes:x:@.dp/#
lambda2hyper:x:../*
log.info:x:-
return:x:@.dest/*

tutorial03.get.hl

/*
 * Example of how to secure your API endpoint using JWT and
 * the internals of Hyperlambda's JWT token slots.
 */

// Throws an exception unless user belongs to root or admin role.
auth.ticket.verify:root, admin

return
   result:Hello World from a secure endpoint

tutorial04.get.hl

.data
   foo1:bar1
   foo2:bar2

unwrap:x:+/*
return
   value1:x:@.data/*/foo1
   value2:x:@.data/*/foo2

tutorial05.get.hl

.arguments
   name:string

if
   eq:x:@.arguments/*/name
      .:Thomas
   .lambda
      return
         result:Hi boss!
else-if
   eq:x:@.arguments/*/name
      .:John
   .lambda
      return
         result:Hi John!
else
   return
      result:Hi stranger!

tutorial06.post.hl

/*
 * Allows the caller to (securely) pass in Hyperlambda to
 * our endpoint and execute it, allowing the caller to
 * specify the logic to execute, and what data to return.
 */
.arguments
   body:*
.accept:application/hyperlambda

// Loading Hyperlambda from [body] argument.
io.stream.read:x:@.arguments/*/body

// Ensuring we return raw Hyperlambda to caller.
response.headers.set
   Content-Type:application/hyperlambda

// Transforming to Hyperlambda and adding lambda into [.lambda] object.
add:x:+/*/.lambda
   hyper2lambda:x:@io.stream.read

// [whitelist] invocation preventing malicious slots from being executed.
whitelist

   // Slots caller is allowed to invoke.
   vocabulary
      add
      insert-before
      insert-after
      set-value
      set-name
      vocabulary
      slots.vocabulary
      for-each
      while
      if
      else-if
      else
      strings.concat
      return
      return-nodes
      unwrap
   .lambda

// Returning lambda object to caller.
lambda2hyper:x:@whitelist/*
return:x:-

interceptor.hl

data.connect:crm
   .interceptor

foo.get.hl

data.select:select * from status
return:x:-/*

Create a LowCode CRUD API in seconds

Create a cloudlet and start generating LowCode CRUD APIs within seconds