1. Introduction
1.1 Overview
MALDA: The AI-First Programming Language is a modern, object-oriented programming language designed for building AI agents and automation workflows. With native support for LLM integration, agent orchestration, and multi-agent systems, MALDA makes it simple to create intelligent, autonomous applications.
The language features a clean, readable syntax, essential control structures, built-in I/O capabilities, and full object-oriented programming support including classes, inheritance, and polymorphism. What sets MALDA apart is its first-class AI capabilities - built-in classes for LLM clients, conversations, agents, and tools that enable developers to build sophisticated AI applications with minimal code.
The page header is the shipping toolchain version (the same number as the CLI). Core language semantics are specified in malda-language-1.0.
prompt + schema + validate, no API key). If you are new to programming, learn the core language next: io.print, variables, input, conditionals, loops, and functions. After the core path, branch into Testing and Quality, Data and Databases, and Browser Apps. Both journeys lead into the same AI-first runtime.
What Does MALDA Stand For?
MALDA: Multi Agent Language with Development Automation - The name MALDA reflects the core principles and design philosophy of the language:
- Multi Agent: Native support for orchestrating multiple AI agents working together. MALDA provides built-in classes and runtime support for creating, coordinating, and managing multiple autonomous agents that can collaborate on complex tasks, share context, and work in hierarchical systems.
- Language: A complete programming language with syntax, runtime, and tooling. MALDA is not just a framework or library - it's a full-featured programming language with its own syntax, interpreter, compiler, desktop IDE, and development tools.
- Development: A toolchain for building and shipping real software, not only for scripting an AI layer on top of another stack. The interpreter, the compiler to standalone executables and JavaScript, the IDEs, the language server, and the built-in testing and database support cover the whole build cycle.
- Automation: Automation of that development work, in both directions. Coding agents can write MALDA: the compact language pack in
docs/llm/teaches the syntax to a model that has never seen it, and language-server diagnostics close the feedback loop - MALDA itself was built heavily with coding agents, and the two largest showcases in this repository (Examples/Agents/secondbrain_semantic.maldaandExamples/RalphWiggum/) were written entirely by coding agents. In the other direction, MALDA programs automate development work themselves, because prompts, tools, agents, endpoints, and durable workflows are language constructs rather than library calls: a program can read a specification, generate code, run tests, and deploy the result.
The unified runtime that makes this possible is described next.
1.2 AI Unified Runtime Architecture
MALDA is built on the foundation of AI Unified Runtime Architecture - a unified system where the programming language runtime, AI capabilities, agent framework, tool ecosystem, and deployment are integrated into a single, cohesive architecture. Unlike traditional approaches that combine separate libraries and frameworks, MALDA provides a unified runtime where everything works together seamlessly.
What is AI Unified Runtime Architecture?
AI Unified Runtime Architecture means that AI capabilities are not added as external libraries or frameworks, but are built directly into the language runtime itself. This creates a unified system where:
- Language Runtime: The interpreter executes code and manages program state
- AI Runtime: LLM clients, conversations, agents, and tools run in the same process
- Agent Orchestration: Multiple agents coordinate within the same runtime environment
- Tool Ecosystem: Tools are part of the runtime, not external plugins
- Deployment Runtime: Compiled executables embed the MALDA runtime and AI capabilities. Some external dependencies (e.g., SQL Server/PostgreSQL client libraries, LLamaSharp native DLLs) may require additional DLLs alongside the executable
Traditional Approach vs. Unified Runtime
In traditional approaches, building AI applications requires combining multiple separate components:
- Programming language runtime (e.g., Python interpreter)
- AI framework library (e.g., LangChain)
- LLM client SDK (e.g., OpenAI SDK)
- Custom tool system
- Separate deployment/packaging system
This creates overhead from library calls, serialization between components, and complex setup requirements.
With AI Unified Runtime Architecture, all these components are integrated into a single runtime:
- No framework setup - AI capabilities are native to the language
- No library overhead - direct execution within the runtime
- Unified error handling and type safety across all operations
- Single executable deployment - MALDA runtime and AI capabilities embedded. Some external dependencies may require additional DLLs
Core Components
Unified Language Runtime
The language interpreter includes AI capabilities as first-class features. Classes like LLMClient, Agent, and Conversation are built into the language, not imported from external libraries.
Integrated AI Runtime Layer
AI operations execute within the same runtime as regular code operations. This provides:
- Direct memory access - no serialization overhead
- Unified type system - same types for language and AI operations
- Synchronous and asynchronous execution support
- Integrated error handling
Unified Agent Orchestration Runtime
Multiple agents run in the same process and can:
- Share memory space and context
- Communicate directly without external protocols
- Access the same tool ecosystem
- Coordinate execution efficiently
Unified Tool Ecosystem Runtime
Tools are integrated into the runtime:
- Built-in tools (file operations, etc.) are part of the runtime
- Custom tools created with
@Tooldecorator are automatically registered - Tool execution happens in-process with the language runtime
- No external tool discovery or registration needed
Unified Deployment Runtime
The compiler embeds the MALDA runtime and AI capabilities into standalone executables:
- Interpreter Mode: Embeds interpreter + source code + AI runtime
- Transpiler Mode: Transpiles to C# with native AI runtime integration
- Result: Single .exe file with the MALDA runtime embedded. Some external dependencies (e.g., SQL Server/PostgreSQL client libraries, LLamaSharp native DLLs) may require additional DLLs to be deployed alongside the executable
Benefits
- Performance: No library call overhead, direct memory access, optimized execution paths
- Simplicity: No framework setup, native syntax, fewer dependencies, less boilerplate
- Type Safety: Unified error handling, type checking across AI operations, compile-time validation
- Developer Experience: Single IDE for language and AI, integrated debugging, unified documentation
- Deployment: Single executable with embedded MALDA and AI runtime. Some external dependencies (e.g., database client libraries) may require additional DLLs, but most applications deploy as a single file
How MALDA Implements It
MALDA's implementation of AI Unified Runtime Architecture consists of four layers:
- Layer 1: Core Runtime - Lexer, Parser, AST, RuntimeValue, Environment, Execution Engine
- Layer 2: AI Runtime - LLMClientInstance, Conversation, AgentInstance, ToolInstance, and specialized agent classes
- Layer 3: Integration Layer - Language Service, AI Chat Service, Debugger, Compiler (all unified)
- Layer 4: Deployment Runtime - Compiler that embeds the MALDA runtime and AI capabilities (interpreter mode) or transpiles with native integration (transpiler mode). Some external dependencies may require additional DLLs
This architecture makes MALDA truly "AI-first" - not a language with AI features added, but a language where AI is fundamental to the runtime architecture itself.
1.3 Language Features
Core Language Capabilities
MALDA includes:
- Variables and data storage
- Arithmetic and logical operations
- Conditional branching (if/else)
- Loops (while, for)
- Functions/procedures
- Named prompt templates (
prompt) - Input/output operations
- Recursion support
- Object-oriented programming (classes, objects, inheritance)
- AI Agent Orchestration: Native support for LLM integration, multi-agent systems, and intelligent automation
Core Language Features
- Dynamic Typing: Variables can hold values of any type
- Type Coercion: Automatic conversion between compatible types (int ↔ float)
- Block Scoping: Variables are scoped to blocks with proper shadowing
- Arrays: Dynamic arrays with built-in methods (append, pop, shift, concat)
- String Interpolation:
$"..."syntax for embedded expressions - Recursion: Full support for recursive function calls
- Inheritance: Single inheritance with method overriding
- Static Members: Class-level fields and methods
AI-First Core Features
- LLM Client:
LLMClientclass for OpenAI-compatible API integration (OpenAI, OpenRouter, LMStudio, OLLAMA, etc.) - Default local LLM: When no client is provided, agents and prompts use the Qwen/Qwen2.5-0.5B-Instruct local model (downloaded as a GGUF build from Hugging Face on first use)—no API key required
- Local LLMs:
LlamaCppClientclass for local inference using LLAMA.cpp with GGUF models - OpenRouter Client:
OpenRouterClientclass for remote models with automatic API key configuration - Conversation Management:
Conversationclass with automatic tool call handling and parallel read-only tool execution (default on) - Tool System:
Toolclass with OpenAI function calling format support - Prompt templates: named
promptdeclarations with parameter interpolation, schema-validatedawait, and Mode B/C tools — see 10. Prompts - Custom Tools:
@Tooldecorator for defining custom LLM tools from MALDA functions - Agent Class:
Agentclass for autonomous agents with roles and instructions - Specialized Agents:
CodingAgent,MALDACodingAgent,GitAgent, andDevAgentwith pre-configured tools - Multi-Agent Orchestration: Support for multiple agents working together, including hierarchical systems with
addSubAgent - Agent Dashboard: Automatic status reporting to central dashboard (no MALDA script changes required)
- Working Directory Safety: Path validation for file operation tools
⚠️ Important: Autonomous agent systems with tool access pose significant security and operational risks. See 18. Agent Orchestration for a detailed disclaimer and risk mitigation strategies before deploying agents in production.
Web & API Features
- Database Support:
SqlServerClient,PostgresClient, andSqliteClientclasses for database operations with parameterized queries and query builder API - Web Server:
HttpServerclass for serving HTML - REST API:
RestServerclass with decorator-based routing (@GET,@POST, etc.) - UI Web Framework:
@PAGEand@AIPAGEwith component library support for building full-stack applications with MALDA backend and server-rendered UI - MCP Server:
MCPServerclass for exposing MALDA functions as MCP tools - UI Generation:
generateUI()function andHTMLCacheclass for LLM-generated HTML - LLM Server:
LLMServerclass for creating LLM REST API servers
1.4 Development Environments
WPF Desktop IDE
- Native Windows application using AvalonEdit
- Syntax highlighting
- IntelliSense/auto-completion
- Full debugger with breakpoints, step-through, variable watch, call stack
- Error diagnostics with real-time reporting
- Compiler integration
- Model browser and downloader
- External MCP server configuration
- Opt-in virtual tabs for a single physical
.maldafile, enabled with// @malda-section Nameseparators - Coexists with classic multi-file composition through
include(included files remain normal physical files)
1.5 Compiler
The MALDA compiler supports dual-mode compilation:
- Interpreter Mode: Embeds source code, uses runtime interpreter
- Transpiler Mode: Transpiles MALDA to C#, native execution
Both modes produce standalone .exe files with the MALDA runtime embedded. Some external dependencies (e.g., SQL Server/PostgreSQL client libraries, LLamaSharp native DLLs) may require additional DLLs alongside the executable.
1.6 Source Composition: include, using, import, export
MALDA has three ways to bring code in from elsewhere, and one way to control what a file offers to others. All four are top-level only.
| Form | What it does |
|---|---|
include "path/file.malda"; | Composes source: loads and parses another MALDA file into the current program, as if its text were part of it. |
using PackageName; | Loads an installed package module and merges its exported symbols into the current scope. |
import "path/file.malda"; | Loads a local file as a module and merges only its exported symbols. |
import { a, b } from "path/file.malda"; | Same load, but merges only the named exports into the current scope. |
import alias = ...; | Same, but binds the exported symbols to a single namespace object instead of the current scope. |
export function/class/var/type/schema | Marks a declaration as part of this file's public surface. |
When to use each
- Use
includewhen you are simply splitting one program across several files and want everything visible everywhere. - Use
importwhen a file is a reusable unit with a deliberate public surface, especially when you want its symbols behind a namespace. - Use
usingfor external reusable libraries installed as packages.
export and the default surface
export can prefix a function, a class, a var, a type, or a schema declaration:
// math_utils.malda
export function add(a, b) {
return a + b;
}
export var VERSION = "1.0";
export type Result = Ok(value) | Err(msg);
export schema Contact { name: string; }
function internalHelper(x) { // not exported
return x * 2;
}
export. A module with no export at all publishes every top-level symbol (including type / schema). Adding your first export to an existing file therefore hides everything you did not mark — use export type / export schema when the module already exports values.
Importing into the current scope or behind a namespace
Without an alias, exported symbols are merged into the current scope. A name that already exists is not overwritten, so the importing file always wins on collisions:
import "shared/math_utils.malda";
print(add(2, 3)); // 5
print(VERSION); // "1.0"
// internalHelper(2); // not available: never exported
Selective import pulls a subset of that surface (missing or non-exported names are errors). Offline goldens: Examples/Modules/selective_import.malda, Examples/Modules/export_type_schema.malda — see also docs/selective-imports.md.
import { add, VERSION } from "shared/math_utils.malda";
print(add(2, 3));
print(VERSION);
// unused(); // not imported, even if exported by the module
import { Result, Contact } from "types_lib.malda";
var r = Ok(42); // constructors arrive with export type Result
var ok = validate("Contact", dict { "name": "Ada" });
With an alias, the same symbols are grouped into one object, which avoids collisions entirely:
import mathUtils = "shared/math_utils.malda";
print(mathUtils.add(2, 3)); // 5
print(mathUtils.VERSION); // "1.0"
The same two forms apply to packages, with a dotted package name in place of the string path:
import App.Core;
import UI = App.Web.Components;
Package names beginning with System, Microsoft, or Windows are resolved as .NET namespaces through the interop layer rather than the package manager. See 30. .NET Interop.
Failing to resolve a target is a runtime error: Package or module not found: Name for packages, and the underlying file-not-found message for file imports.
Path and safety behavior for include
includeis allowed only at top-level scope (not inside blocks likeif,while, or function bodies).- Relative include paths resolve from the directory of the file containing the include statement.
- Absolute paths are also supported.
- Circular include chains are rejected with a parse error.
In Desktop IDE, virtual tabs do not replace include: they are an editor view over one physical file. They are created only when the source contains explicit // @malda-section Name separators. Include resolution remains file-based and works the same as before.
// Local file composition: everything from these files becomes part of this program
include "shared/math_utils.malda";
include "features/orders.malda";
// Package import into the current scope
using App.Core;
// Package import behind a namespace object
using UI = App.Web.Components;
1.7 Quick Example
Characteristic constructs first (same program as Examples/Basics/first_look.malda). -> Review binds the prompt to the schema. Without await, the call is a rendered template — no API key. validate("Review", …) is the same check await would run on the model JSON.
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);
}
Core syntax uses the same statements. Prefer namespaced calls (io.print); flat print still runs. File, path, and environment I/O: 12. Input/Output.
io.print("Hello, World!");
var name = "Alice";
var age = 25;
var pi = 3.14159;
var isActive = true;
var numbers = [1, 2, 3, 4, 5];
numbers.append(6);
function greet(name) {
return "Hello, " + name + "!";
}
io.print(greet("Bob"));
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("Charlie", 30);
person.introduce();
See Also
- 3. Lexical Structure - Learn about syntax basics
- 4. Data Types - Understand MALDA's type system
- 33. Examples - More complete examples