Common programming languages lack flexibility, which has led to the emergence of dozens of programming languages over the past decades. Those languages typically share a lot of common concepts and only differ in specific aspects. This situation burdens programmers with the necessity of learning multiple languages or using several languages even within a single project. Whenever a new technology emerges along with a new language, programmers need to learn this language from scratch. Most of this effort is wasted since much of the language repeats the same ideas found in its predecessors. Moreover, tool and library developers also need to support these new languages, resulting in significant wasted efforts from all parties involved and a significant increase in complexity and fragmentation in the software industry.

Alusus language solves this problem by making the language flexible and its features dynamically extensible during the compilation of the user's program, without the need to rebuild the compiler or make changes to its setup. This saves a lot of time and effort for both technology producers and users. Developers of new technologies will no longer need to create an entirely new language from scratch. Instead, they can simply create the new needed feature and deploy it as a library that can be imported into Alusus programs. These extension libraries have almost complete freedom to modify the language, such as adding new grammar rules or modifying code generation units of the compiler.

Advantages


There are many reasons why a single language for every programming need is not only useful, but necessary:
  • Reduce the learning curve for programmers.
  • Increase the quality of software products. The more languages involved in a single product, the lower the quality of that product.
  • Increase the creativity of programmers. Often programmers skip on useful technologies just because they don't support the language they are using.
  • Reduce development cost. Needing more languages for a project means higher cost for that project.
  • Speed up advances in software technologies instead of scattering the development efforts among many languages.
  • Simplify the hiring of programmers. The more languages are in use within the community, the more dividid the community is, the harder it is to find the right programmer, and the harder it is for the programmer to find the right employer.
  • Simplify the cooperation between different software teams.
  • Increase the reusability of software components.
  • Allow mixing more software technologies inside the same program.
In addition to the benefits mentioned above, Alusus is designed to make the following possible:
  • Simplify the utilization of computer resources for maximum performance since you are no longer confined within language limitations.
  • Allow the community to participate in the development of the language and simplify that process.
  • Allow the language to support more features without complicating the syntax.
  • Simplify the setup of development environments.
  • Allow the programmer to work at different levels depending on the need of his application. Depending on the libraries in use, the language can act as a high level language, a low level language, or a mixture of the two.
  • Provide more flexibility in controlling the results of the compilation. For example, you can generate an executable file, interpret the source code and execute it on the fly, or mix the two like generating an executable file and running unit tests on the fly during compilation.

How?


Alusus language enables programmers to expand the language by providing the following capabilities:
  • Interoperability between the compiler and the user's code, i.e. the code being compiled. This means that programmers can communicate with Alusus' compiler from within their program to read or modify compiler data, or even create new code programmatically.
  • Compile-time execution, which allows executing parts of the user's code during the compilation process. This enables adding new code on the fly or modifying code that is currently being compiled.
  • Dynamic grammar rules, where the grammar rules are stored in the compiler as data rather than being hard coded. This allows the user's program to add new grammar rules dynamically.
  • Dynamic compiler components, which allows modification of the compiler code itself. In other words, a specific library can dynamically modify the compiler code by, for example, replacing a certain function with another.

Multiple Code Generators


The flexibility of Alusus language allows it to be connected to multiple code generators. This means that different parts of the same program can be compiled or executed using different code generators. This idea is contrary to frameworks like LLVM, JVM, and .NET. For example, the LLVM framework provides a single executable code generation unit that is linked to front-end interfaces for multiple languages. Alusus, on the other hand, serves as a unified language interface that can be linked to multiple code generation backends based on the program's needs.

Integrating with different code generators can be done from within the code being compiled, or from a library imported by that code.

This capability allows the programmer to keep their project unified within a single code base, and organize code parts based on their functionalities rather than the environment in which they will be executed, as we will see in later examples. It also enables the creation of more comprehensive libraries than what is possible in common languages. For example, a library can contain both the user interface code and the corresponding server code for a specific feature, all within a single library without the need to split it into separate server and user interface libraries.

Comparison


There are three important differences between Alusus and mainstream languages in terms of extensibility:
  • Traditional languages can only be extended statically, i.e. by modifying the compiler and releasing a new version, whereas in Alusus you only need to provide an extension library, without needing to modify the compiler itself. The following graph details the difference in the two processes:

    Steps in orange are steps the authors of the extensions have no control over which makes it harder to incorporate extensions into those languages. In addition to delays and complexities, the maintainers might not accept to incorporate the extensions to begin with. These complexities do not exist with Alusus because all the authors need to do in Alusus is to host their extensions online for them to be instantly available to everyone.
  • The decentralized design of Alusus makes it easier to develop its features independently from each other as it's illustrated in the following graph:

    As explained in the previous section, Alusus also provides mechanisms to reduce the possibility of conflicts.
  • Some languages may allow extensions in the form of plugins that can be configured on a per-system basis. This in contrast to Alusus' per-project loading of language extensions. In other words, two different projects on the same system can use two different sets of extensions. In addition to that, in Alusus you don't need to change system configuration to load different extensions, instead the source code of your program loads the extensions it needs with the 'import' command; no configuration is needed on the system.

Examples


The following example illustrates the closure feature in Alusus language. Alusus compiler does not have built-in support for closures and does not understand the keyword `closure`. However, the library loaded at the beginning of the example adds this feature along with the required grammar rules. It can be observed in the example that the closure automatically distinguishes between different types of variables accessed within its body, and prepares the required payload accordingly. It includes the variable 'p' in the closure payload because it is a local variable, while it does not include the variable 'g' because it is a global variable. Similarly, it does not include the variable 'q' because it is not used within the function. This level of control in language extensions is impossible in common languages because it requires interoperability between the library and the compiler.

import "Srl/Console";
import "closure";

use Srl.Console;

def g: Int;

func getClosure (): (closure (Int)) {
    def p: Int = 2;
    def q: Int = 4;
    return closure (a: Int) {
        print("closure arg: %d\n", a);
        print("closure payload var: %d\n", p);
        print("global var: %d\n", g);
    };
}

def c: closure(Int) = getClosure();

g = 1;
c(3);

// Output:
// closure arg: 3
// closure payload var: 2
// global var: 1

The following example illustrates adding new features to facilitate database integration and writing query statements. In the example, it can be observed that it starts with importing the package manager, which is used to download and import a library directly from the web (in this case, from the GitHub repository). This library, in turn, adds new features to match model classes with their corresponding tables in the database and provides grammar rules for writing conditions in query statements.

In the `addCar` function, you can see that the user does not need to write SQL statements to add a new record. Instead, the library automatically deduces them from the modifiers that decorates the class and its attributes. In the `findCars` function, the search condition is written in Alusus language itself, as if you were writing an expression in a conditional statement. The compiler in turn translates this condition into an SQL where clause.

import "Apm";
Apm.importFile("Alusus/Rows", { "Rows.alusus", "Drivers/Postgresql.alusus" });
use Srl;
use Rows;

@model["cars"]
class Car {
    define_model_essentials[];

    @notNull
    @primaryKey
    @Uuid
    @column
    def id: String;

    @VarChar["50"]
    @column
    def name: String;

    @Float
    @column["car_price"]
    def price: Float;
}

def db: Db(PostgresqlDriver(ConnectionParams().{
    dbName = "alusus";
    userName = "alusus";
    password = "alusus";
    host = "0.0.0.0";
    port = 5432;
}));
if !db.isConnected() {
    System.fail(1, String("Error connecting to DB: ") + db.getLastError());
}

db.schemaBuilder[Car].create();

function addCar(name: String, price: Float) {
    def c: Car;
    c.id = generateUuid();
    c.name = name;
    c.price = price;
    db.save[Car](c);
}

function findCars(maxPrice: Float): Possible[Array[SrdRef[Car]]] {
    return db.from[Car].where[price <= maxPrice].select();
}

The following example illustrates writing a full stack web app that contains both server-side and user interface code within a single file. The example starts by using the package manager to load the Web Platform library. Web Platform distinguishes backend endpoint functions using the `@beEndpoint` modifier and automatically integrates their calls into the web server. Functions decorated with `@uiEndpoint` modifiers are compiled by WebPlatform into WebAssembly and are served on the web server at the route mentioned in the modifier's parameter. In this example `postMessage` and `getMessages` are added as endpoints served at `/messages` route, whereas the `main` function is translated into WebAssembly and served at the `/` route. In the future calls to backend functions will be automatically translated into HTTP requests.

import "Build";
import "Apm";
Apm.importFile("Alusus/WebPlatform");
use Srl;
use WebPlatform;

//==============================================================================
// Backend

def MAX_MESSAGES: 12;
def messages: Array[String];

@beEndpoint["POST", "/messages"]
func postMessage (conn: ptr[Http.Connection]) {
    def postData: array[Char, 1024];
    def postDataSize: Int = Http.read(conn, postData~ptr, postData~size);
    if messages.getLength() >= MAX_MESSAGES messages.remove(0);
    messages.add(String(postData~ptr, postDataSize));
    Http.print(conn, "HTTP/1.1 200 Ok\r\n\r\n");
}

@beEndpoint["GET", "/messages"]
func getMessages (conn: ptr[Http.Connection]) {
    def response: String = String.merge(messages, "<br>");
    Http.print(conn, "HTTP/1.1 200 Ok\r\n");
    Http.print(conn, "Content-Type: text/plain\r\n");
    Http.print(conn, "Cache-Control: no-cache\r\n");
    Http.print(conn, "Content-Length: %d\r\n\r\n", response.getLength());
    Http.print(conn, response.buf);
}

//==============================================================================
// Frontend Pages

@uiEndpoint["/"]
@title["WebPlatform Example - Chat"]
func main {
    def onFetch: closure (json: Json);

    Window.instance.setView(Box({}).{
        style.{
            height = Length.percent(100);
            justify = Justify.SPACE_BETWEEN;
            display = Display.FLEX;
            layout = Layout.COLUMN;
        };
        addChildren({
            Header(),
            Box({}).{
                style.{
                    width = Length.percent(100) - Length.pt(10);
                    padding = Length4.pt(5);
                    display = Display.FLEX;
                    layout = Layout.COLUMN;
                    flex = Flex(1);
                };
                addChildren({
                    Text(String()).{
                        style.{
                            width = Length.percent(100);
                            height = Length.percent(100);
                            fontColor = Color(50, 50, 50);
                            fontSize = Length.pt(20.0);
                        };
                        onFetch = closure (json: Json) {
                            def status: Int = json
                                .getObject("eventData")
                                .getInt("status");
                            if status >= 200 and status < 300 {
                                def data: String = json
                                    .getObject("eventData")
                                    .getString("body");
                                if this.getText() != data {
                                    this.setText(data);
                                }
                            } else {
                                // TODO: Notify user.
                            }
                        };
                    }
                });
            },
            TextEntry().{
                width = Length.percent(100) - Length.pt(3);
                height = Length.pt(50);
                onNewEntry = closure (newData: String) {
                    sendRequest(
                        "POST", "/messages",
                        "Content-Type: application/text", newData, 10000,
                        closure (Json) {}
                    );
                    sendRequest("GET", "/messages", null, null, 500, onFetch);
                };
            }
        })
    });

    startTimer(500000, closure (json: Json) {
        sendRequest("GET", "/messages", null, null, 500, onFetch);
    });

    runEventLoop();
}

//==============================================================================
// Project Control

Console.print("Starting server on port 8010...\nURL: http://localhost:8010/\n");
runServer({ "listening_ports", "8010", "static_file_max_age", "0" });

There are no limits to what libraries can do, and there are no limits to the number or type of libraries that can be loaded at any time. Alusus language imposes no restrictions on the number of grammar rules that can be added, and it provides features to minimize the possibility of conflicts between grammar rules. For more information, please refer to the language design in the documentation page.

F.A.Q.


Alusus is Arabic for 'The Foundations', which reflects the design of the language since it provides the foundations on which any programming feature can be built. Also, the Core of the language only provides the foundations of the language and leaves the rest to be provided by libraries.

The source code is available for everyone to use free of charge even for commercial purposes, but the license under which the source code is released is more restricted than GPL.

Alusus is released under Alusus Public License, Version 1.0, which allows the free use of the language for any purpose including commercial purposes, but the license prevents the user from releasing a modified version of the language without permission from the project maintainers. Visit the license page for more details.

The project is still in its infancy and its maintainers are trying at this point to avoid fragmentation at such an early stage. The main reason to avoid licenses like GPL is that those licenses allow anyone to release a modified version which may result in multiple languages not compatible with each other.

Yes, when the project becomes more mature and stable we intend to release it under GPL. There isn't yet any schedule for this but most probably version 1.0 will be the version that goes out under GPL.

Absolutely. We are actively looking for volunteers. Please contact us for more information.

The compiler (Core) is written in C++17 and uses STL. The standard libraries are written using C++17, STL, and LLVM.

Currently, Alusus supports Linux and macOS. We are providing pre-built binaries for Linux, while on macOS you'll need to built it from source. You can run the pre-built Linux binaries on Windows through WSL, but we are planning to provide native support for Windows in the future.