Preemptive scheduling coroutine programming language
Tags: programming, language, coroutine, linux
Published: 2021-01-10 10:52:00

The concept of coroutine must be familiar to everyone now. After all, not only LUA, Go or Kotlin but also C++, they are all support coroutines.
But different languages have different implementations. Such as LUA, coroutines will be scheduled when someone called yield() or resume().
A new language introduced to you today is a scripting language of coroutine preemptive scheduling based on time slices. That is, each coroutine does not need to explicitly call certain functions to give up control, but according to the weight of execution time to control whether to be suspended or run.

Its name is **Melang**

- Official site: https://melang.org/
- Repo: https://github.com/Water-Melon/Melang
  [![Alt Text](https://res.cloudinary.com/practicaldev/image/fetch/s--nXV1bEgV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dst6c2h02d9anmx28gt0.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--nXV1bEgV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dst6c2h02d9anmx28gt0.png)

We will discuss the following:

- features
- usage scenarios

## Features

For a language, it must have flow control, array, dict, structure or class, etc. These in Melang are no different from other languages. So we will focus on the following:

#### Coroutine preemptive scheduling

In Melang, **each script task is an independent coroutine**, and coroutines' execution environments are isolated. But they can communicate with each other by the message queue functions.
Let's look at two examples:

- running multi-tasks by melang execution file

  There are two script files:

```
 //a.mln
 while (true) {
   @mln_print('a');
 }
```

```
 //b.mln
 while (true) {
   @mln_print('b');
 }
```

Then I execute the following command:

```
 $ melang a.mln b.mln
```

After execution, you will see the screen print a and b alternately, as follows:

```
 ...
 b
 b
 b
 a
 a
 a
 a
 a
 ...
```

And using `top` command will find out that only one process (and also only one thread) is performing these two tasks.
Melang scheduling does not occur in the function `mln_print`, but will try to switch during the processing of each statement.

- start up multi-tasks in a Melang task

```
 //launcher.mln
 @mln_eval('a.mln');
 @mln_eval('b.mln');
```

We create a new script file named `launcher.mln` to start up `a.mln` and `b.mln` by calling function `mln_eval`. And then execute:

```
 $ melang launcher.mln
```

The output is the same as previous example.

#### Reflection

> Reflection means that the class to be operated is known at runtime, and the complete structure of the class can be obtained at runtime and the corresponding method can be called. -- quoted from a netizen

In Melang, the concept of class is called Set, but it is more similar to the structure in C, but also supports function definitions.
Let's look at a simple example:

```
Human {
  name;
  age;
  @init (name, age) {
    this.name = name;
    this.age = age;
  }
}
```

Here we define a Set named Human, which has two member variables: `name` and `age`, and a method `init`.
The general instantiation code is as follows:

```
me = $Human;
```

This instantiates a `Human` object named `me`.
However, we can also instantiate it like this:

```
str = 'Human';
me = $str;
```


The result is the same.

Then we can call the method of the object:

```
me.init('Tom', 18);
```

------

In Melang, not only Set can be obtained by a string, but also functions and object methods can be used in this way.

Examples for function:

```
@foo ()
{
  @mln_print('foo');
}
a = 'foo';
a();
```

Here we define a function, and we call it indirectly by a string variable.



Example for object method:

```
Human {
  name;
  age;
  action;
  @init (name, age) {
    this.name = name;
    this.age = age;
  }
}

me = $Human;
me.action = 'init';
me.action('Tom', 18);
@mln_print(me.name);
```

As you can see in this example, we call the method of an object by a string member variable.

#### Injection

For an instantiated object, we can still add (or inject) some members and methods to it, for example:

```
Human {
}

someone = $Human;
someone.age = 20;
@mln_print(someone.age);
```

The output is 20. The member variable `age` was successfully added to the object `someone`.

**Note**: The injection is defined for the object, not Set. Therefore, if you instantiate Human again, there is still no `age`.

The above example is the simplest injection. Melang also provides function `set` and `get` similar to other scripts.



Let's look at an example of method injection:

```
Human {
  age;
}

@printAge()
{
  @mln_print(this.age);
}

someone = $Human;
someone.age = 20;
someone.print = printAge;
someone.print();
```

This example will still output 20, but this time it is output by `mln_print` called in the injected method `printAge`.

#### Reactive programming

As we can see in web front-end programming, a variable will be monitored by a set of functions. When the value changes, the callback function will be called. (Note that, in Melang, even if the new value is the same as the old one, it also will be called)

Example:

```
@eventHandler(newdata, userData)
{
  @mln_print(newdata);
  @mln_print(userData);
}
n = 0;
@mln_watch(n, eventHandler, 'this is an useData');
for (; n < 5; ++n)
  ;
```

Here, variable `n` will be tracked by calling the function `mln_watch`. When the value of `n` changed, the `eventHandler` function would be called.

We will see the following output:

```
1
this is an useData
2
this is an useData
3
this is an useData
4
this is an useData
5
this is an useData
```

#### Synchronous code, executed asynchronously

In Melang, code is written in a synchronized form. The advantage is logical coherence.

In traditional languages, synchronous writing also means synchronous processing, so the performance is low. But in Melang, the interpreter will execute completely asynchronously.

Example:

```
//a.mln
while (true) {
  @mln_msgQueueSend('queue', 'a');
  ret = @mln_msgQueueRecv('queue');
  @mln_print(ret);
}
```

```
//b.mln
while (true) {
  ret = @mln_msgQueueRecv('queue');
  @mln_print(ret);
  @mln_msgQueueSend('queue', 'b');
}
```

These two scripts use the message queue functions to send and receive messages from each other and print them out. For each task, its logic is sequential. For example, `a.mln` must send a message first, then receive the message, and then print. If `b.mln` does not send a message to `a.mln`, then `a.mln` will be suspended while receiving the message.

The above is just a simple example, and it is the same when it comes to network I/O. When data arrives on the socket, the interpreter will receive it, then return to the script layer, and change the script task from the suspended state to the running state.

## Usage Scenarios

The current usage scenario of Melang is mainly **embedded in other applications**, which is basically the same as LUA. The Melang project on Github is a launcher. The launcher will call the script-related functions in the core library for initialization and execution. And of course, **the core library is also open source**.

Melang's core library provides many interfaces such as algorithms, data structures, event mechanisms, multi-process and multi-threaded frameworks. Based on this library, not only can obtain melang script, but also reduce development costs.

In addition, if an application uses the event processing interface provided by the core library, not only events can be processed, but scripts can also be executed in the same thread.

Melang provides a basic function library. Besides string, file system and network IO operations, it also provides functions for accessing MySQL8 and a series of functions such as encryption, decryption and communication.



------

Although the core library has been updated and upgraded for several years, the language is still in its infancy. And we still need to make a lot of efforts on it. Looking forward to your attention to this project. Thanks for reading.