compiled, leak-free, no-GC, fast, small, modular, type-safe, memory-safe high-level simple programming language
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
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"}
"
};
log("{}/
{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:
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 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:
These generics do not introduce additional code, do not consume memory and do not cost CPU time.
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("{} <ul>{ result.forRecords((record) { "{} <li data-id="{ record["id"] }"> { record["name"] } </li> "}) }</ul> ")
In this example we use string interpolation twice:
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.
// Program
log("
Hello,
I'm a multiline "raw" string
");
// Prints:
Hello,
I'm a multiline "raw" string
These strings have no problems of their siblings in other languages:
More examples and details are here: multiline-string-constants
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;
fclose(f);
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
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:
Details are here: http://aglang.org/.....shared-pointers-to-immutable-objects
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.
sys_getParent(existingObject)
Function sys_GetParent returns
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).
Today Argentum got small but fundamental improvements:
How it was previously (file `demo.ag`):
using sdl;
using utils;
using gui;
class Scene{
+gui_Group;
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{
+Group;
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
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);
sys_log(b.newLine().toStr());
});
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
Argentum programming language got a website: https://aglang.org
All main announces will be dubbed at both Hackaday and AgLang.org
Create an account to leave a comment. Already have an account? Log In.
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More