GSLF

Gioele Stefano Luca Fierro. Software Engineer, Philosopher, Signal Hacker.

::] UNIMATRIx - A Sandbox for Emergent Behavior in LLM-Driven Agent Societies

Multi-agent LLM systems have spent the last two years drifting from research curiosity to load-bearing infrastructure. Most of these systems are teleological, agents are pointed at a goal and the framework grinds toward it. UNIMATRIx takes the opposite stance. It is a Python project that wires up a small population of LLM-backed agents, gives each one a personality, a role, and a social class, and then steps back to see what happens. No win condition. No reward signal. Just conversations, votes,...
Read post

[UNIMATRIx] Concept of an AI society simulation

What happens if a group of agents, with different personalities, roles, and social positions, are given rules that require them to form a democratic society? I started from this question to create UNIMATRIx, an open source software project, a sociological experiment, a testbed to understand and find definitions of the LLMs' ways of thinking. The setup: roughly fifty AI agents, all running off one model, sharing a single simulated society. Each has a name, a personality, a backstory, and a stati...
Read post

02. Coding Sound in c++: the toolchain

Before writing code, it is necessary to understand the software environment that transforms human-readable text into a functioning audio plugin. This collection of software is referred to as the "toolchain." In this course, we utilize a specific set of tools standard in the Windows audio development industry. The process begins with the Source Code, which is the C++ text you write. This text is processed by a Compiler, a program that translates your commands into machine code (...
Read post

00. Coding Sound in c++: introduction

Welcome to Coding Sounds in C++ learning path. This module serves as the blueprint for everything we are about to build together. Many audio programming tutorials simply show you how to generate a sine wave and leave you there, but this course is fundamentally different because it is entirely project-based and coding focused. By the end of our time together, you will have built a fully functional VST3 and AU plugin that you can load into any Digital Audio Workstation like Ablet...
Read post

Rustlers Atom 2.11: Returning references

Returning references is one of the most common stumbling blocks for new Rustaceans. The rule is simple but strict: You cannot return a reference to something created inside the function. Why? Because when the function returns, its stack frame is destroyed. Any variable created inside that function (that isn't returned by ownership) is dropped. If you returned a reference to it, you would be pointing to freed memory. The Dangling Reference (Forbidden) fn create_dangling() ->...
Read post

Rustlers Atom 2.10: Move vs Clone Semantics

Understanding the memory layout of growable collections like String and Vec is the key to understanding why Moves are fast and Clones are expensive. A String (or Vec) is made of three parts stored on the Stack: Pointer: Points to the data on the heap. Length: How much data is currently used. Capacity: How much space is allocated before we need to ask the OS for more. The actual data (the letters of the string) lives on the Heap. We can prove how this works by inspecting t...
Read post

Rustlers Atom 2.9: RefCell/Cell interior mutability

In rust you cannot mutate data behind a shared (immutable) reference. But what if you need to? What if you have a struct that is logically immutable to the outside world, but needs to update an internal counter, a cache, or a log? This pattern is called Interior Mutability. Rust provides safe wrappers that let you bend the rules by moving the checks from compile time to runtime. Cell<T>: Copying in and out Cell is for types that implement Copy (like integers or boolean...
Read post

Rustlers Atom 2.8: Cow<T> - Clone On Write

Sometimes you want to efficiently return a string slice &str (no allocation) but sometimes you need to modify that string before returning it, which requires a String (heap allocation). Do you return String every time and pay the allocation cost even when you didn't change anything? Do you return Option<String> and make the caller confuse? Rust provides a standard enum for this exact scenario: std::borrow::Cow (Clone-on-Write). Cow is a smart wrapper that can hold ei...
Read post

Rustlers Atom 2.7: Reborrowing

If Rust strictly followed the "Move" rule for mutable references, programming would be incredibly tedious. Technically, a &mut T is not Copy. This means if you pass a mutable reference to a function, it should be moved into that function, and the original variable holding that reference should become unusable. But . . . this code works: fn modify(x: &mut i32) { *x += 1; } fn main() { let mut data = 10; let r = &mut data; modify(r); // r is moved into...
Read post

Rustlers Atom 2.6: NLL (non-lexical lifetimes)

For a long time, Rust’s concept of a "lifetime" was strictly tied to lexical scope—the curly braces {}. If you created a reference inside a block, the compiler assumed that reference lived until the closing brace }, period. This was safe, but annoying. It often rejected valid code because the compiler wasn't smart enough to see that you were done with a variable before the block ended. Since the 2018 edition, Rust uses Non-Lexical Lifetimes (NLL). The borrow checker now looks...
Read post

Rustlers Atom 2.5: Scope, Drop and distruction determinism

Rust uses Resource Acquisition Is Initialization (RAII). This means the life of a resource (memory, file handle, network socket) is tied directly to the life of the variable bound to it. In garbage-collected languages, objects are cleaned up "eventually." In Rust, cleanup is deterministic. It happens exactly when the owner goes out of scope. This is handled by the Drop trait. When a value’s scope ends, Rust automatically calls its drop function. struct CustomSmartPointer { dat...
Read post

Rustlers Atom 2.4: The Borrow Checker Rules

The Borrow Checker is the part of the compiler that enforces memory safety without a garbage collector. These rules are non-negotiable. They prevent data races—the situation where two pointers access the same memory, at least one is writing, and there is no synchronization. The Two Laws of Borrowing RULE 1 - The Validity Rule References must always be valid. You cannot have a reference pointing to memory that has been freed (dangling pointer). // Valid reference let x = 10;...
Read post

Rustlers Atom 2.3: Mutable and immutable borrow

Owning values is great, but moving them around constantly is stupid. Often, you want to let a function use a value without taking responsibility for freeing it. In Rust, this is called borrowing. You borrow a value by creating a reference. References are pointers that are guaranteed to be valid and align with Rust’s safety rules. There are two types. Immutable Reference &T An immutable reference allows you to read data but not change it. You create one by adding & bef...
Read post

Rustlers Atom 2.2: `Copy` and `Clone` traits

A type that implements Copy behaves much like the old-school C integers: when you write let b = a;, the value is copied rather than moved; passing it to a function copies it; returning it from a function copies it as well; and in all these cases, the original value is still valid and can continue to be used. All the primitive scalar types you met in chapter 1 are Copy: this includes integers like i32, u64, and usize, floating-point numbers like f32 and f64, as well as bool and ...
Read post

Rustlers Atom 2.1: Rust ownership explained

Ownership is Rust’s replacement for the garbage collector, manual free, and “hope nothing double-frees” all at once. It’s a compile-time bookkeeping system with one simple law: Every value has exactly one owner. When the owner goes out of scope, the value is dropped. That’s it. Everything else is consequences. Scopes and owners Start with the smallest example. Here x owns the value 42. When the inner block ends, x goes out of scope and its storage is released. fn main() { {...
Read post

Rust stdt now with Date & Time management

I am pleased to announce the release of stdt version 0.0.6. In the Rust ecosystem, date and time handling is often delegated to heavyweight crates like chrono or time. While these are excellent for comprehensive production needs, there is a distinct need for lightweight, zero-dependency implementations for standard formats. Version 0.0.6 introduces stdt::date, a domain-specific module focusing on strict RFC 3339 and ISO 8601 parsing, validation, and formatting. The Architecture The main idea o...
Read post

Rustlers Molecule 1A: ToDo CLI Application

This molecule stitches together only the atoms 1.1–1.10. No structs, no macros beyond formatting, no external crates. You’ll see how far you can get with just: expressions and statements (1.1), scalars (1.2), tuples/arrays/slices (1.3), bindings and mutability (1.4), if / match (1.5), loops (1.6), functions (1.7), &str vs String (1.8), conversions (1.9), and formatting (1.10). We’ll build a single-file program: Stores tasks in todo.txt in the current directory (simple pe...
Read post

Rustlers Atom 1.10: Formatting

Rust’s formatting is compile-time checked. Placeholders must match the values and the traits they implement. This are the available macros: println! prints to stdout with a newline. print! prints without a newline. eprintln! prints to stderr. format! builds a String (no I/O). println!("Hello, {}!", "world"); let s = format!("{} + {} = {}", 2, 3, 2 + 3); Formatting use this Placeholders and specifiers: {} → uses the value’s Display human-readable implementation. {:?} → us...
Read post

Rustlers Atom 1.9: Numbers and conversions

Rust keeps numeric conversions explicit and typed. You choose how to convert so the compiler can enforce safety. as as performs a primitive cast right now, even if information may be lost (e.g., narrowing or sign changes). Use it when you know what you’re doing. fn main() { let a: u16 = 500; let b: u8 = a as u8; // 500 → 244 (wraps modulo 256) let x: f32 = 3.9; let y: i32 = x as i32; // truncates toward zero → 3 println!("{b}, {y}"); } Integers ...
Read post

Random in Rust with stdt

__ .___ __ _______/ |_ __| _// |_ / ___/\ __\/ __ |\ __\ \___ \ | | / /_/ | | | /____ > |__| \____ | |__| \/ stdt on GitHub | stdt on crates.io The stdt Rust library (v0.0.5) now provides minimal, non-cryptographic PRNG utilities for generating integers, floating-point values, and random selections. Seeds are derived from the current time in nanoseconds combined with a hashed thread ID. Inputs are mixed with a SplitMix-inspired multiply-rotate s...
Read post

Rustlers Atom 1.8: Strings

Strings in Rust are collections of UTF-8 bytes, wrapped in safe abstractions. &str &str (read “string slice”) is a view into UTF-8 text. It doesn’t own the data — it borrows it. String literals like "hello" are of type &'static str (a slice baked into the program’s binary). fn main() { let greeting: &str = "Hello, world!"; println!("{}", greeting); } You can think of &str as a window into some existing string data. Because it borrows, it’s ligh...
Read post

Rustlers Atom 1.7: Functions

Functions in Rust are explicit and predictable. You define a function with fn, name it in snake_case` and declare parameters with type annotations: fn main() { greet_to("Gioele"); } fn greet_to(name: &str) { println!("Hello, {name}!"); } Rust requires type annotations for all parameters — they’re not optional. This makes functions self-documenting and ensures compile-time clarity. A function body is a block expression, and, just like before, the last expression w...
Read post

TèchnoSophìa 7.2 Augustine: Linear Time and Progress

_____________________________________________________________________________ ______ __ / / / ) / , ---/-------__----__---/__----__----__----\--------__------__---/__--------__- / /___) / ' / ) / ) / ) \ / ) / ) / ) / / ) _/______(___ _(___ _/___/_/___/_(___/_(____/___(___/___/___/_/___/_/___(___(_ ...
Read post

Rustlers Atom 1.6: Loops: `loop`, `while`, `for`

Rust gives you three looping constructs. There’s no hidden behaviours, no accidental infinite loops, and no implicit coercions. Each kind of loop expresses a specific intent. loop: The Infinite Primitive loop is the most fundamental looping construct. It runs forever unless you explicitly stop it with break. fn main() { let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; // Break with a value ...
Read post

TèchnoSophìa 7.1 Augustine: Useful Arts vs. Voluptuary Arts

_____________________________________________________________________________ ______ __ / / / ) / , ---/-------__----__---/__----__----__----\--------__------__---/__--------__- / /___) / ' / ) / ) / ) \ / ) / ) / ) / / ) _/______(___ _(___ _/___/_/___/_(___/_(____/___(___/___/___/_/___/_/___(___(_ ...
Read post

Rustlers Atom 1.5 - Flow Control

Rust’s control flow is an extension of its expression-oriented design: every conditional and pattern match produces a value. if Unlike in C or Python, if returns always a value. The branches must evaluate to the same type. fn main() { let temperature = 25; let weather = if temperature > 30 { "hot" } else if temperature < 10 { "cold" } else { "mild" }; println!("The weather is {}", weather); } Here, the entire if block y...
Read post

Rustlers Atom 1.4 - Variables, binding, shadowing, mutability

Rust variables are bindings: a name tied to a value. By default, they are immutable. Immutable vs mutable fn main() { let x = 5; // x = 6; ❌ compile error let mut y = 5; y = 6; // ✅ works println!("y = {}", y); } The mut keyword makes intent explicit. No silent mutation is allowed in rust. Shadowing Instead of mutating, you can re-declare the same name. fn main() { let spaces = " "; let spaces = spaces.len(); // new binding, new type print...
Read post

TèchnoSophìa 6.3 The Skeptics: The Suspension of Progres

_____________________________________________________________________________ ______ __ / / / ) / , ---/-------__----__---/__----__----__----\--------__------__---/__--------__- / /___) / ' / ) / ) / ) \ / ) / ) / ) / / ) _/______(___ _(___ _/___/_/___/_(___/_(____/___(___/___/___/_/___/_/___(___(_ ...
Read post

TèchnoSophìa 6.2 The Stoics: Logos and Coherence

_____________________________________________________________________________ ______ __ / / / ) / , ---/-------__----__---/__----__----__----\--------__------__---/__--------__- / /___) / ' / ) / ) / ) \ / ) / ) / ) / / ) _/______(___ _(___ _/___/_/___/_(___/_(____/___(___/___/___/_/___/_/___(___(_ ...
Read post

Rustlers Atom 1.3 - Composite Types: tuple, array, slice

Rust’s composite types let you pack values together and work with them as a unit. They are minimal but powerful, and you’ll use them everywhere. Tuples A tuple can hold multiple values of different types. fn main() { let point: (i32, i32, i32) = (3, 4, 5); // Destructure let (x, y, z) = point; println!("x = {}, y = {}, z = {}", x, y, z); // Access by index println!("First: {}", point.0); println!("Second: {}", point.1); // Function returning a t...
Read post