It automatically prevents all memory leaks. It doesn't use GC, so no pauses. It's compiled to machine code. It's crazy safe and fast.
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
Argentum got a JSON module with both Parser and Writer.
Let's try Writer in action:
We'll use the same classes as in JSON Parser example:
class Point{
x = 0f;
y = 0f;
}
class Polygon {
name = "";
points = Array(Point);
isActive = false;
}
This function converts an array of Polygons into a JSON string:
fn polygonsToJson(data Array(Polygon)) str {
Writer.useTabs().arr {
data.each `poly _.obj {
_("name").str(poly.name);
_("active").bool(poly.isActive);
_("points").arr\poly.points.each `pt _.obj {
_("x").num(double(pt.x));
_("y").num(double(pt.y))
}
}
}.toStr()
}
JSON module for Argentum programming language allows to parse JSONs directly in application data structures, skipping the creation of JSON DOM. This takes two times less memory and reduces the time overheads by three-folds. The usual alternative to DOM parsers is streaming SAX parser, that requires application to have cumbersome state machine to handle data. Argentum JSON module doesn't use it either.
JSON Parsing in Argentum is simple and extremely effective.
For example, if we have such data structures:
class Polygon {
name = "";
points = Array(Point);
isActive = false;
}
class Point{
x = 0f;
y = 0f;
}
... and we want to read JSONs of this structure:
[
{
"active": false,
"name": "p1",
"points": [
{"x": 11, "y": 32},
{"y": 23, "x": 12},
{"x": -1, "y": 4}
]
},
{
"points": [
{"x": 10, "y": 0},
{"x": 0, "y": 10},
{"y": 0, "x": 0}
],
"active": true,
"name": "Corner"
}
]
... we can do it with this function:
using json { Parser }
fn readPolygonsFromJson(data str) Array(Polygon) {
Array(Polygon).{
json = Parser.init(data);
json.getArr\_.append(Polygon)-> json.getObj `f
f=="active" ? _.isActive := json.getBool(false) :
f=="name" ? _.name := json.getStr("") :
f=="points" ? json.getArr\_.points.append(Point)-> json.getObj `f (
f=="x" ? _.x := float(json.getNum(0.0)) :
f=="y" ? _.y := float(json.getNum(0.0)));
json.success() : log("parsing error {json.getErrorMessage()}{json.getErrorPos()?" at {_.offset}"}");
}
}
As you can see this function contains just:
It also checks and handles all format errors. And it is all in just 12 lines of code.
Despite its size, this function handles all the edge cases:
Let's call this function for completeness:
myPolygons = readPolygonsFromJson("
[{
"active": false,
"name": "p1",
"points": [ {"x": 11, "y": 32}, {"y": 23, "x": 12}, {"x": -1, "y": 4}]
},{
"points": [{"x": 10, "y": 0}, {"x": 0, "y": 10}, {"y": 0, "x": 0}],
"active": true,
"name": "Corner"
}]
")
Pretty high-level for a language that compiles to tiny standalone machine code executables and runs at the speed of C++?
Details are here https://aglang.org/json-module/
Now it's possible to try the Argentum programming language online.
Playground allows to play with a number of pre-existing examples as well as start from scratch. It opens to the old good modify-compile-run-repeat game. Also it allows to go by the number of existing tutorials and try-on all the examples from the argentum website posts.
All details and a link to the playground is here: https://aglang.org/playground/
Happy hacking! (but please don't break my Raspberry Pi on which it all runs)
Argentum compiler and runtime library successfully ported to ARM-64.
It builds code for ARM-64.
All compiled demos work fine on ARM-64/Raspberry Pi with tiny memory footprint and little CPU consumption.
There are many platforms ahead: ARM/Android, ARM/OSX, WASM, RISCV.
Argentum cURL bindings gives full support for reach http(s), ftp... functionality.
using httpClient{ get, Response }
...
get("https://google.com", app.&onFetched(r Response){
log("Result code={r.status}: response size={r.body.capacity()}");
})
httpClient_Request
object allows to customize requests by adding different verbs, request headers etc.httpClient_Response
object allows to get access to response headers, status code, response body and all request data.Example:
Sqlite.open("../demo/mydb.sqlite", xReadWrite) ?
_.query("
SELECT "id", "name", "avatar"
FROM "table"
LIMIT 0, 20
", xSimpleQuery)
.execute() row {
id = row.intAt(0);
name = row.stringAt(1);
ava = row.stringAt(2);
log(`${id} ${name} ${ava}`);
"))
This prints, depending on the actual database content:
1 Andy 0x4563 2 Paula 0x2321
The SQLiteFfi
argentum module has multiple feature not shown in the example:
sqliteFfi
is a low level API, you can build any query execution strategies atop of it.Currently sqliteFfi
links the full database engine inside the application that uses it, but this can be easily switched to DLL/so if needed.
using sys { Map }
class Pt{ // A user-def class.
x = 0; // Its fields
y = 0;
call(ax, int, ay int) this { x:= ax; y := ay } // One of constructors.
}
m = Map(String, Pt) // Declare map with string keys and Pt values.
("Alpha", Pt(1, 2)) // Fill it with data.
("Bravo", Pt(-1, 42));
log(
m["Aplha"] // Access element by key.
? `Pt(${_.x}, ${_.y})` // Check it and convert to string.
: `Not found`); // Handle if no such element.
This will output: Pt(1, 2).
Maps are not built-in entities in Argentum, in fact even Arrays are not built-in. They are all mere classes of standard library. And since all Argentum classes are extendable, you can always add arbitrary methods to arrays and maps.
m.each() k v {
log(`key: ${k} x: ${v.x} y: ${v.y}`);
}
In this example `each` is the ordinary method implemented for map class in one of `utils` modules.
Any user type can be a key.
Argentum:
Map class requires keys to be frozen objects. This prevents from common error in other languages then by modifying map keys a map can be brought to incoherent state.
There are owning maps, maps of weak pointers and maps of shared pointers to immutable objects. So maps follow all Argentum rules of object composition, sharing and thread-safe handling - so no races, no crashes, no overheads. And topology aware copy operation supports map as well:
m1 = @m; // Makes a full deep copy of the map
This code not only copies the map along with all its values (keys are shared since they are immutable) but also it handles cross-references between map elements preserving object graph topology. In other languages this operation requires peculiar hand-written code, while in Argentum it's automated.
Internally Maps are implemented as flat, open addressed, 2^n grow, linear probe, robin hood hash-tables. So they are fast and not that much memory consuming.
Argentum ported to Linux and run (both compiler and the compiled demo) on SteamOS
To run the Argentum Demo on Ubuntu/Debian:
# Download package
wget -O aglan_0.0-1_amd64.deb \
https://github.com/karol11/argentum/releases/download/win-lin-demo-v0.0.12/aglan_0.0-1_amd64.deb
# ...And install it
sudo dpkg -i aglan_0.0-1_amd64.deb
To run the Argentum Demo on Steam Deck (or Arch Linux), follow these steps: https://aglang.org/install-argentum-demo-on-the-steamdeck-arch-linux/
Demo contains fully functional compiler, runtime, examples and build script.
Argentum threads act as lightweight processes that share the same address space.
Immutable objects are freely shared across all threads while mutable ones belong to exactly one thread. Though threads can pass mutable objects one another.
Threads can acts as workers having no internal mutable state or as microservices with state.
Threads communicate with task queues. So no synchronization primitives needed, no races, no deadlocks.
Moving to multithreaded mode didn't turn reference counters into atomic ones.
Example:
using sys{ Object, Thread, setMainObject, log }
class App { // Holds mutable state of the main thread.
// Worker thread, having Object as its internal state.
worker = Thread(Object).start(Object);
}
app = App;
setMainObject(app);
log("Started on main thread\n");
// Post a new "workerCode" task to the worker Object
// Since it's passed to the object of other thread
// this code will be executed on that thread.
app.worker.root().&workerCode(callback &()) {
log("Hello from the worker thread\n");
// Post another task, that we received as a parameter
callback~();
}~(app.&endEverything() {
// This "endEverything" task is connected to the
// main thread object. So it will be activated
// on the main thread. We pass in to the `callback`
// parameter.
log("Shutdown from the main thread\n");
// `?Object` is a null-pointer of type `Object`.
// `setMainObject` here deletes previous App instance
// and as such stops worker thread.
// And since there is no application state object anymore,
// application ends.
setMainObject(?Object);
});
This code uses one existing and one new operator
Create delegate:
receiver.&delegateName(parameters) { code }
Post delegate to its `receiver` thread queue as an asynchronous task and transfer all parameters to that thread
delegate~(parameters);
More details: https://aglang.org/multithreading/
New Windows demo: https://github.com/karol11/argentum/releases
with `src\threadTest.ag` example.
Argentum compiler builds a DWARF-compatible debug info, And it's all integrated with VSCode:
So far it supports:
It has special handling for pointers to functions, lambdas and delegates, strings and limited support for arrays (it shows only 20 first elements).
So far it shows only static type of object by pointers. As a temporary work-around you can use watch expressions with type casts (they can also be used to access any array elements beyond 20 elements boundary).
All details are here: https://aglang.org/argentum-debugger-v1/
Create an account to leave a comment. Already have an account? Log In.
Hellow, Andrey!
I have a few questions:
1) it looks like it's Windows only now - how difficult it is to support other OS (Linux or iOS)?
2) it's 64-bit x86 only, isn't it? how difficult it is to add new architecture (ARM or RISC-V)?
3) according to this
https://aglang.org/how-the-argentum-language-makes-fast-dynamic_cast-and-method-dispatch-with-just-four-processor-instructions/
you have both classes and interfaces - any plans for "mixins"? ;)
Hi there,
1.
Yes, I have plans for every planform. In fact the first iterations were originally developed on Linux. As soon as I complete a couple of last milestone-1 features, I'll port it back to Linux and add WASM and Android and maybe iOS/OSX.
2.
I believe that 32-bit architectures will die sooner than the product will hit the first release. So I have no plans for supporting the 32-bit floats and ints. But everything might change later.
Regarding ARM/RISC-V, I'll definitely add its direct support, but it might work right now with llvm tool chain. Try:
`agc -g -emit-llvm -S -src \argentum-demo\src -start graph -o graph.ll`
this makes you a llvm bitcode text, that can be compiled to any arch with
`clang -o0 -c graph.ll -o graph.o`
and linked accordingly with `src/runtime/runtime.*`
3.
Yes. I have plans for mixins, in fact they will have a pretty trivial implementation. But it's for milestone 2.
Become a member to follow this project and never miss any updates
Help me make an example of MySQL and Argentum? I need to display any one table via http. Thank you very much.