• 99 bottles of beer on the wall

    Andrey Kalmatskiy5 days ago 0 comments

    There is a famous song:

    99 bottles of beer on the wall, 99 bottles of beer.
    Take one down and pass it around, 98 bottles of beer on the wall.
    1 bottle of beer on the wall, 1 bottle of beer.
    Take one down and pass it around, no more bottles of beer on the wall.
    No more bottles of beer on the wall, no more bottles of beer.
    Go to the store and buy some more, 99 bottles of beer on the wall.

     This song is sometimes used in computer science to compare languages wikipedia.

    And even more, there is a dedicated website, that collected 1500+ variations of this program in different languages.

    Let's look how this program can be written in Argentum:

    using sys {String, log}
    using utils { forRange }
    using string;
    forRange(-99, 1, (count) {
        bottles = (c, n) {
            c == 0 ? "{}
                {n}o more bottles
            " : "{}
                {c} bottle{c != 1 ? "s"}
            {bottles(-count, "N")} of beer on the wall, {bottles(-count, "n")} of beer.
            {count == 0
                ? "Go to the store and buy some more"
                : "Take one down and pass it around"
            }, {bottles((99 - count) % 100, "n")} of beer on the wall.

     Unlike code in Wikipedia, this solution does the thing:

    • it correctly adds the ending (s) to the second line,
    • it adds the "Go to the store" statement,
    • it adds "No more" to the beginning of the verse where it's needed,
    • it uses the correct case for "N" letter,
    • it follows DRY principle.

    All in all, despite its young age Argentum succeeded in solving this question in a straightforward and effective way (it compiled to 20k standalone Windows executable).

  • Argentum got Generics

    Andrey Kalmatskiy7 days ago 0 comments

    Argentum classes and interfaces can be parameterized:

    class UnorderedMap(Key, Value) { ... }
    interface InStream(T) { ... }

    These parameters can be used in inheritance, field and method declarations as well as inside methods.

    class Map(K, V) {
       +Array(Pair(K, V));            // Base class parameterized with our class parameters
       getAt(key K) ?V { ... }        // Class parameters affect types of method prototypes
       setAt(key K, newVal V) { ... }
       forEach(visitor (K, V)void) { ... } // visitor lambda is typed with class parameters.
    class Pair(A, B) {
      a = ?A;  // field `a` of type `Optional(A)` initialized with `none`
      b = ?B;  // Field types also depend on class parameters.

    Right now the internal implementation of generics is does not allow instantiation-of and casts-to the parameters, but I can easily add them to the language in the future.

    So bottom line is:

    • Now it become very easy to implement a rich container and standard algorithms library right in the Argentum language without using C/C++.
    • Switching to generics allowed to remove all type-casts from all examples, tests and tutorials. It dramatically simplified source code.

    These generics do not introduce additional code, do not consume memory and do not cost CPU time.

  • Argentum got string interpolation

    Andrey Kalmatskiy05/18/2023 at 14:05 0 comments

    result = db.query("{}
         SELECT name, id
         FROM users
         WHERE name LIKE '{ encodeSql(request.userMask) }%'
         LIMIT {request.page * xPageSize}, {xPageSize};
    request.mode == Json
       ? response.send(result.toJson())
       : response.send("{}
                result.forRecords((record) { "{}
                      <li data-id="{  record["id"]  }">
                          {  record["name"]  }

     In this example we use string interpolation twice:

    • to build an SQL query
    • to convert query results to HTML

    This SQL query is a simple multiline text string with { placeholders } . Placeholders are Argentum expressions that return everything convertible to strings.

    HTML example demonstrates two nested interpolated strings - one for <ul> and one for nested <li>s.

    More on string interpolation: here.

  • Argentum got raw multiline string literals

    Andrey Kalmatskiy05/17/2023 at 20:20 0 comments

    // Program
         I'm a multiline "raw" string
    // Prints:
    I'm a multiline "raw" string

     These strings have no problems of their siblings in other languages:

    • No need for any special termination symbol/sequence - it's done by indentation.
    • Source code indentation is not included in the string.
    • Additional indentation can be added in the string to help formatting the output.
    • Line end encoding is controlled by developer. It doesn't depend on source code formatting. Make it CR, LF or any combinations.
    • Extra indentation, can go in form of tabs or spaces, this is also under developer's control.
    • Argentum also takes in account such peculiar details as last line endings and indentations.

    More examples and details are here: multiline-string-constants

  • Interop with C/C++

    Andrey Kalmatskiy05/08/2023 at 02:56 0 comments

    Argentum can natively call C/C++ functions, pass primitives, objects and raw structures (with sys_Blob object). Example:

    In C/C++

    #include <stdio.h>
    #include "../argentum/src/runtime/runtime.h"
    bool ag_fn_io_writeFile(AgString* name, AgString* content) {
      FILE* f = fopen(name->ptr, "wb");
      if (!f) return false;
      bool r = fputs(content->ptr, f) >= 0;
      return r;

    In Argentum (file io.ag):

    using sys { String; log; }
    fn writeFile(name String, content String) bool;
    writeFile("1.txt", "File data") ? log("done")

    More details are here: ffi-tutorial

  • Argentum got const objects and shared pointers

    Andrey Kalmatskiy04/27/2023 at 17:18 0 comments

    Anrgentum objects can be turned immutable with prefix freeze operator "*". 

    class Point {
       x = 0;
       y = 0;
       set(x int, y int) this { this.x := x; this.y := y; }
    p = *Point.set(10, 42);
    // now point p is immutable
    p.x += 1; // compilation error, `p` is *Point, and cannot be modified.

    Immutable objects are shared across object hierarchies and threads.

    There can be declared a methods, specifically callable to immutable objects and methods that cam be called on any objects - regardless their mutable status:

    class Node {
       name = "";
       chilren = Array;
       -isLeaf() bool { children.size() == 0 } 
    // method `isLeaf` can be called on any Node - frozen or not

    Frozen pointers can reference one object from different other objects. They represent the "aggregation" relationships in terms of UML. With adding of this mechanism Argentum now supports all UML object relations:

    • Composition with unique "@pointers" to mutable objects
    • Aggregation with shared "*pointers" to immutable objects
    • Association with non owning "&pointers".

    Details are here: http://aglang.org/.....shared-pointers-to-immutable-objects

  • Argentum objects got parent pointers and safe-n-fast object reattachments

    Andrey Kalmatskiy04/27/2023 at 01:55 0 comments

    Each object can tell who is its parent.
    These parent pointer are maintained automatically at a very low cost (single move instruction).
    This ability simplifies the handling of document data models and can facilitate integrity checks if needed.


    Function sys_GetParent returns

    • object in which field this object is located,
    • or array object if it's in an array,
    • or null if this object is not nested in another object.

    Function result is ?sys_Object.

    This parent pointers also assist a new "splice" operation, that allows to extract an existing object from one part of the object hierarchy and insert it in other place:

    temp = object.field;           // save the link to object stored somewhere
    object.field := newValue;  // make it not stored there anymore
    // or
    object := newValue;         // or destroy the hierarchy it belonged
    anotherParentObject.field @= temp  // "splice" this object in another place.

     This allows to reorganize object hierarchies in safe and effortless manner (previously it required a copy operation).

    Details and more examples are in this post.

  • Improved modules and name resolution

    Andrey Kalmatskiy04/18/2023 at 20:23 0 comments

    Today Argentum got small but fundamental improvements:

    • Names are isolated in modules.
    • Explicit module dependencies.
    • lightweight imports.

    How it was previously (file `demo.ag`):

    using sdl;
    using utils;
    using gui;
    class Scene{
        sdl = sdl_Sdl;
        w = sdl_Window;
        rnd = utils_Random;
        flare = sdl_Texture;
        star = sdl_Texture;
        background = sdl_Texture;
        foreground = sdl_Texture;

    How it is now:

    using sdl { Window, Sdl, Texture }
    using gui { Actor, Group }
    class Scene{
        sdl = Sdl;
        w = Window;
        rnd = Random;
        flare = Texture;
        star = Texture;
        background = Texture;
        foreground = Texture;

    Previously any compound names like `sdl_image_mySurface` were able to be created and used in any package. And they always had to be written in full.

    Since now names should follow rule: `packageName_functionOrClassName` (for example: `sdlImage_mySurface` or from example above `demo_Scene`. And since names are bound to a module, no need to write them in that long form.

    All names defined in a module `demo` are automatically `demo_*`.

    When a module declares some dependency with the `using` directive, it may list all names to import and use in short form: `using gui { Actor; Group; }`

    If names from different imports collide, give them aliases: `using gui { Control=Actor; }`
    Now `Control` can be used instead of `gui_Actor`.

    TL;DR: Argentum names just got better.

    More on names: link
    New compiler and stdlib version: windows demo

  • Fizz-Buzz.ag

    Andrey Kalmatskiy04/11/2023 at 14:12 0 comments

    This is a working solution for the famous fizz-buzz coding interview question.

    using string;
    using utils;
    b = string_Builder;
    forRange(1, 101, (i) {
       i % 3 == 0 ? b.putStr("fizz");
       i % 5 == 0 ? b.putStr("buzz");
       b.pos == 0 ? b.putInt(i);

    Details, explanations are in the tutorial: aglang.org/tutorial-1-fizz-buzz

    How to install the compiler and configure VSCode: aglang.org/how-to-play-with-argentum-in-vscode

  • Project website - aglang.org

    Andrey Kalmatskiy04/09/2023 at 18:55 0 comments

    Argentum programming language got a website: https://aglang.org

    • documentation,
    • blog,
    • downloads,
    • tutorials,
    • discussions etc.

    All main announces will be dubbed at both Hackaday and AgLang.org