33. Esempi
33.0 First Look
Costrutti caratteristici, nessuna API key. Stesso programma di Examples/Basics/first_look.malda e dell'Avvio rapido nell'Indice. -> Review lega il prompt allo schema. Senza await, la chiamata è un template reso; validate("Review", …) è lo stesso controllo che await eseguirebbe sul JSON del modello.
schema Review {
summary: string;
issues: string[];
}
prompt codeReview(code, language) -> Review {
system: "You are an expert reviewer of {language}.",
user: "Review this {language} code:\n\n{code}"
}
var rendered = codeReview("function add(a, b) { return a + b; }", "javascript");
io.print(rendered.user);
var checked = validate("Review", {
"summary": "Looks fine",
"issues": []
});
if (checked.ok) {
io.print("schema ok: " + checked.data.summary);
} else {
io.print("schema failed: " + checked.error);
}
33.1 Hello World
io.print("Hello, World!");
33.2 Esempio di classe semplice
Spiegazione: 11. Classi e oggetti.
class Person {
public var name;
public var age;
function Person(name, age) {
this.name = name;
this.age = age;
}
public function introduce() {
io.print($"Hi, I'm {this.name} and I'm {this.age} years old.");
}
}
var person = new Person("Alice", 25);
person.introduce();
33.3 Esempio di ereditarietà
Spiegazione: 11. Classi e oggetti §11.3.
class Animal {
public var name;
function Animal(name) {
this.name = name;
}
public function speak() {
io.print(this.name + " makes a sound");
}
}
class Dog extends Animal {
function Dog(name) {
super(name);
}
public function speak() {
io.print($"{this.name} barks: Woof!");
}
}
var dog = new Dog("Buddy");
dog.speak();
33.4 Funzione fattoriale
function factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
var result = factorial(5);
io.print($"Factorial of 5: {result}");
33.5 Classe Calculator
class Calculator {
private var result;
function Calculator() {
this.result = 0;
}
public function add(value) {
this.result = this.result + value;
return this;
}
public function getResult() {
return this.result;
}
}
var calc = new Calculator();
calc.add(10).add(20);
io.print($"Result: {calc.getResult()}");
33.6 FizzBuzz
function fizzBuzz(n) {
var i = 1;
while (i <= n) {
if (i % 15 == 0) {
io.print("FizzBuzz");
} else if (i % 3 == 0) {
io.print("Fizz");
} else if (i % 5 == 0) {
io.print("Buzz");
} else {
io.print(i);
}
i = i + 1;
}
}
fizzBuzz(20);
33.7 Manipolazione di array
var numbers = [1, 2, 3, 4, 5];
var sum = 0;
var i = 0;
while (i < numbers.length) {
sum = sum + numbers[i];
i = i + 1;
}
io.print($"Sum: {sum}");
33.8 Esempio di Input/Output
Input da console più conversione. Per file, path e ambiente: 12. Input/Output.
var name = io.input("What is your name? ");
var ageStr = io.input("What is your age? ");
var age = int(ageStr);
io.print($"Hello, {name}! You are {age} years old.");
if (age >= 18) {
io.print("You are an adult.");
} else {
io.print("You are a minor.");
}
33.9 Esempio di agente semplice
Questo è un buon punto di transizione dopo i fondamenti del linguaggio. Mostra come le funzionalità AI first-class di MALDA si appoggino alla stessa sintassi introdotta negli esempi precedenti.
var client = new OpenRouterClient();
var agent = new Agent(
"Assistant",
"helper",
"You are a helpful assistant.",
client
);
var response = agent.think("What is 2+2?");
io.print(response.content);
33.10 Modalità di output del comando test
# Human-readable (default)
malda test
# Structured CI payload
malda test --format ci
# Write deterministic regression artifacts for failing properties
malda test --write-regression
# Write regressions to a custom directory
malda test --write-regression --regression-dir ./artifacts/regressions
33.11 Starter di scaffolding
# Scaffold a secure web API starter
malda new webapi my-api
# Scaffold a fullstack starter
malda new fullstack my-app
# Scaffold a browser canvas game
malda new game my-game
# Scaffold a canvas game plus @GET/@POST scores
malda new game my-scores --fullstack
# Override generated project naming tokens
malda new webapi my-api --name SalesPortal
# Overwrite scaffold files in an existing directory
malda new fullstack . --force
# Skip tests scaffolding
malda new webapi api-lite --no-tests
Gli starter generati includono le convenzioni di default di malda test, pattern riutilizzabili di helper per la sicurezza, esempi di configurazione di baseline per sicurezza/rate-limit, file di profilo ambiente in config/environments/ e config placeholder per deploy e osservabilità. Il template game salta quelle config HTTP; il passo successivo è malda play app.malda. malda new game --fullstack salta anch'esso le config HTTP e si compila con --mode fullstack invece di malda play.
33.12 Backend JavaScript (modalità API)
Compila il sorgente MALDA in JavaScript per il browser e usa l'API helper del DOM:
malda compile Examples/Web/js/hello_dom.malda --mode js -o Examples/Web/js/hello_dom.js
malda compile Examples/Web/js/counter.malda --target js -o Examples/Web/js/counter.js
var root = dom.query("#app");
if (root != null) {
dom.clear(root);
var button = dom.create("button");
dom.setText(button, "Click");
dom.append(root, button);
function handleClick() {
println("clicked");
}
dom.on(button, "click", handleClick);
}
Il backend JavaScript supporta anche i tipi somma e i pattern match in modalità API:
type Response = Ok(value) | Err(message);
var r = Ok(42);
var text = match r {
case Ok(v): "value: " + v;
case Err(msg): "error: " + msg;
};
println(text);
33.13 Backend JavaScript (modalità template)
I file sorgente in modalità template usano l'estensione .malda.html e supportano interpolazione e blocchi di istruzioni:
malda compile Examples/Web/js/hello_template.malda.html --mode js -o Examples/Web/js/hello_template.generated.js
<div class="hello-template">
<p>Message: {{ "Hello" }}</p>
{% var count = 2; %}
<p>Count: {{ count }}</p>
</div>
Carica malda-js-runtime.js prima dello script del template compilato nella pagina host.
33.14 Backend JavaScript (API canvas di gioco)
Costruisci un primo gioco interattivo nel browser usando game.* in modalità JavaScript:
malda compile Examples/Games/game_bounce.malda --mode js -o Examples/Games/game_bounce.js
var x = 100;
var speed = 220;
function update(dtMs) {
var step = (speed * dtMs) / 1000;
if (game.isKeyDown("arrowleft")) {
x = x - step;
}
if (game.isKeyDown("arrowright")) {
x = x + step;
}
}
function render() {
game.clear();
game.fillRect(x, 140, 40, 40, "#33cc66");
game.drawText("Use arrows", 10, 24, "#ffffff", "14px monospace");
}
game.createCanvas(640, 360, "#app");
game.setBackground("#202830");
game.start(update, render);
Punti chiave: crea il canvas prima di disegnare/avviare, scala il movimento con dtMs e carica malda-js-runtime.js prima dello script compilato. Vedi Examples/Games/game_runtime_smoke_test.html per una pagina host di smoke test diretta nel browser. Per blit di un atlas PNG e una camera che scorre, compila Examples/Games/game_sprite_smoke.malda. Per fronti di tasti, tocchi e gamepad, compila Examples/Games/game_input_smoke.malda. Per overlap AABB e cerchi, compila Examples/Games/game_collision_smoke.malda. Per un side-scroller breve che usa immagini, camera, AABB, fronti di tasti, sample SFX e startFixed insieme, compila Examples/Games/malda_platform.malda. Per un sample cave a tile (stile Boulder Dash: gravità, diamanti e lucciole), compila Examples/Games/maldadash.malda.
33.14.1 Audio di gioco (campione rapido v1)
var startedAudio = false;
function update(dtMs) {
if (!startedAudio && (game.isKeyDown(" ") || game.isMouseDown(0))) {
game.audioInit();
game.audioSetMasterVolume(0.4);
startedAudio = true;
}
if (game.isKeyDown("a")) {
game.audioPlayTone(440, 80, "square", 0.2);
}
}
game.createCanvas(640, 360, "#app");
game.setBackground("#202830");
game.start(update, null);
L'audio v1 usa le API game.audio* in modalità JavaScript. La superficie API è volutamente stabile per gli script di gioco MALDA esistenti.
33.14.2 Blit del buffer pixel
Scrivi un frame CPU con game.setPixel, poi caricalo in un solo putImageData tramite game.blitPixels(). Sono accettati anche array RGB/RGBA packed. Compila il sample ray tracer con:
malda compile Examples/Games/ray_tracer.malda --mode js -o Examples/Games/ray_tracer.js
game.createCanvas(320, 180, "#app");
game.createPixelBuffer();
function renderScanline(y) {
var x = 0;
while (x < 320) {
game.setPixel(x, y, x % 256, y % 256, 80);
x = x + 1;
}
}
function update(dtMs) {
renderScanline(0);
}
function render() {
game.blitPixels();
}
game.start(update, render);
I colori sono 0–255. Le scritture setPixel fuori dai limiti vengono ignorate. Preferisci questo percorso a un fillRect per pixel. Vedi Examples/Games/ray_tracer.malda.
33.15 Backend JavaScript (API scena three.js)
Costruisci una prima scena 3D nel browser usando three.* in modalità JavaScript. L'API scene, il loop, l'ordine di caricamento e i kernel shader sono in 26.10 API scene three.js:
malda compile Examples/Games/three_cube.malda --mode js -o Examples/Games/three_cube.js
var width = 800;
var height = 500;
var renderer = three.createRenderer(width, height, "#app");
three.setClearColor(renderer, "#101722");
var scene = three.createScene();
var camera = three.createPerspectiveCamera(70, width / height, 0.1, 100.0);
three.setPosition(camera, 0, 0, 5);
var geometry = three.createBoxGeometry(1, 1, 1);
var material = three.createStandardMaterial({ "color": "#44aaff" });
var cube = three.createMesh(geometry, material);
three.add(scene, cube);
var light = three.createDirectionalLight("#ffffff", 1.1);
three.setPosition(light, 2, 3, 4);
three.add(scene, light);
function render() {
three.render(renderer, scene, camera);
}
Punti chiave: carica Examples/Web/wwwroot/vendor/three.min.js prima di malda-js-runtime.js, poi lo script MALDA compilato, poi chiama MaldaApp.main(). Vedi Examples/Games/three_runtime_smoke_test.html per una pagina host diretta. Per una map PNG, un cubo glTF e lookAt, compila Examples/Games/three_textured.malda.
33.15.1 Materiali shader
Sposta il lavoro per-pixel sulla GPU con three.createShaderMaterial e three.setUniform. Il contratto (tipi, sottoinsieme, chiavi di glsl.compile, rename nell'IDE) è in 26.10.1 Kernel shader. Compila il tracer in tempo reale con:
malda compile Examples/Games/three_shader_raytracer.malda --mode js -o Examples/Games/three_shader_raytracer.js
malda compile Examples/Games/three_shader_path_tunnel.malda --mode js -o Examples/Games/three_shader_path_tunnel.js
@shader()
function vertexMain() {
vUv = uv;
gl_Position = vec4(position.xy, 0.0, 1.0);
}
var vert = glsl.compile({
varyings: ["vec2 vUv"],
functions: ["vertexMain"],
main: "vertexMain"
});
var material = three.createShaderMaterial({
"vertexShader": vert,
"fragmentShader": frag,
"uniforms": { "uTime": 0 }
});
three.setUniform(material, "uTime", t);
Usa three.createOrthographicCamera(-1, 1, 1, -1, 0, 1) e PlaneGeometry(2, 2) per un pass a schermo intero. Vedi Examples/Games/three_shader_raytracer.malda. Un tunnel path-marching in stile ShaderToy è Examples/Games/three_shader_path_tunnel.malda (Frostbyte, CC-BY-NC-SA-4.0).
33.16 Esempio rapido di property testing
property intIdentity(x) {
return (x + 0) == x;
}
malda test --iterations 80 --seed 1337
Per la guida completa al property testing (decoratori di capability, semantica di parità, shrinking e workflow di regressione), vedi Property testing.
33.17 Pipeline AI (RAG)
Generazione retrieval-augmented end-to-end usando l'operatore pipe (|>), il retriever VectorDB, i prompt e l'output JSON tipizzato. Esempi:
Examples/Prompts/rag_pipeline.malda— pipe inlineExamples/Prompts/rag_function_pipeline.malda— pipeline confunctionnominate
dotnet run --project MaldaLang -- Examples/Prompts/rag_pipeline.malda
dotnet run --project MaldaLang -- Examples/Prompts/rag_function_pipeline.malda
Schema della pipeline:
schema Answer {
text: string;
sources: string[];
}
prompt answerPrompt(question, context) -> Answer {
system: "Answer using only the provided context.";
user: "Context:\n{context}\n\nQuestion: {question}"
}
function embedText(text) {
return embedBagOfWords(text, 16);
}
var vdb = new VectorDB(16, "single");
vdb.init(embedText);
indexInto(vdb, docs);
var retriever = vdb.asRetriever({ topK: 2 });
var context = question |> retriever.get |> formatRetrievedDocs;
var parsed = mockResponse |> parseJson("Answer");
// With an LLM client (inline pipe or named function):
// await (question |> retriever.get |> formatRetrievedDocs
// |> (ctx) => answerPrompt(question, ctx) |> runPrompt(client) |> parseJson("Answer"));
function ragAnswer(question, client) -> Answer {
return question |> retriever.get |> formatRetrievedDocs
|> (ctx) => answerPrompt(question, ctx) |> runPrompt(client) |> parseJson("Answer");
}
// var result = await ragAnswer(question, client);
Vedi anche: 7. Espressioni (operatore pipe), 13. Funzioni built-in (helper della pipeline AI), 15. VectorDB (asRetriever) e 10. Prompt (dichiarazioni schema).
33.18 UI server-driven (ui.*)
API del linguaggio: 24. Componenti server Web UI (parti da 23. Panoramica Web UI). Campioni offline in Examples/Web/:
ui_event_loop.malda— ciclo corretto mount → dispatch → pull → setState → renderui_counter_dashboard.malda— contatore più hook di lifecycle e snapshotui_state_lifecycle.malda— peek vs get-or-create, pin, default poisonui_form_workflow.malda/ui_controls_showcase_minimal.malda— form e catalogo dei controlliui_resync_flow.malda— snapshot / resync quando gli alberi divergono
dotnet run --project MaldaLang -- Examples/Web/ui_event_loop.malda
dotnet run --project MaldaLang -- Examples/Web/ui_counter_dashboard.malda
Vedi anche
- 11. Classi e oggetti - Altri esempi di classi
- 16. Supporto database - SQLite, Postgres, SQL Server
- 34. Property testing - Property, shrinking, regressione
- 15. VectorDB - Similarity search e API retriever
- 13. Funzioni built-in -
loadDocuments,indexInto,runPrompt,parseJson - 24. Componenti server Web UI - alberi
ui.*, fragment e props dei controlli