Language Profile
Resumen rapido del posicionamiento tecnico del lenguaje (paradigma, ejecucion y tipado).
| Pregunta |
Respuesta corta |
Detalle |
| Es multiparadigma? |
Si |
Combina estilo imperativo/procedural, OOP MVP (class/interface)
y funciones de primera clase con modelado dinamico de datos
(list/object/map/set).
|
| Paradigma dominante |
Imperativo/procedural |
Flujo principal basado en mutacion de estado, bloques,
if/while/for/switch,
funciones y llamadas explicitas. |
| Paradigma menos dominante |
Funcional ligero |
Hay funciones de primera clase y composicion por funciones, pero no hay
lambdas/closures/HOF nativos del lenguaje en esta fase. |
| Es compilado o interpretado? |
Ambos |
--mode interpret ejecuta via interprete;
--mode compile compila AOT con LLVM (exe,
obj, ir) y puede usar runtime bridge para features
dinamicas. |
| Tipado estatico o dinamico? |
Dinamico con hints opcionales |
Variables sin tipo son dinamicas. Tipos declarados y type hints en funciones
se validan en runtime. --mode analyze agrega chequeos estaticos
auxiliares, no tipado estatico total. |
En practica: Clot apunta mas a productividad imperativa con flexibilidad dinamica, y menos a
tipado estatico estricto global. OOP MVP ya esta disponible en modo interprete.
Scope
Documenta el estado de Clot al 2026-03-07. La cobertura corresponde a
parser,
interpreter, static analyzer, backend LLVM AOT, runtime bridge, i18n y modulos disponibles.
| Area |
Incluido |
No incluido |
| Lenguaje |
Tipos, funciones, OOP MVP (class/interface), enum,
while, for clasico, for-each,
do-while, switch, break,
continue, pass, const,
in, throw, try/catch/finally,
defer, import |
Pattern matching, async/await nativo de lenguaje, OOP avanzado
(protected/abstract/final) |
| Libreria base |
output, input, cast/type/assert/throw, file I/O, async task I/O, math,
clot.core.exceptions |
HTTP nativo, JSON parser nativo, fechas avanzadas |
| Tooling |
--mode interpret|compile|analyze, i18n es/en, runtime bridge
automatico para features no cubiertas por AOT nativo |
Package manager dedicado |
Audience Paths
Application Developer
- Tutorial
- Language Reference
- Library Reference
- FAQs
Runtime Contributor
- Language and type validations
- Reporting Issues
- Contributing workflow
- History and migration notes
Compiler Contributor
- What is New (AOT/runtime bridge)
- Language constraints for LLVM mode
- General/Global indices
- Contributing and testing matrix
Style and Conventions
- Todos los ejemplos usan sentencias terminadas con
; cuando aplica.
- Se usa
snake_case para variables y nombres de modulo.
- Documenta siempre las precondiciones de funciones que toquen archivos o tipos numericos
restringidos.
- Para semantica exacta de errores, usa
--lang en si deseas diagnosticos en
ingles.
Highlights
| Area |
Update |
Impact |
| Numeric model |
int por defecto con BigInt dinamico (sin overflow fijo) |
Mayor seguridad en enteros y menos errores por rango |
| Tipos nuevos |
float, decimal, char,
tuple, set, map, null,
function |
Mayor expresividad y modelado de datos |
| Control flow |
for clasico, for-each,
do-while, switch/case/default,
break, continue, pass,
finally y defer |
Flujo mas expresivo, mas cercano a Java en cabeceras y con mejor control de
salida de bloques |
| Immutability & membership |
const + operador in |
Bindings inmutables y pruebas de pertenencia para colecciones, object y
string |
| Error system |
throw(value) +
catch(Tipo)/catch(Tipo err) +
finally + modulo
clot.core.exceptions |
Captura por tipo y jerarquia de excepciones para codigo OOP |
| OOP MVP |
class/interface, extends, implements,
constructor, get/set, super,
protected, abstract |
Encapsulacion y modelado por objetos con validaciones de contrato en runtime
|
| String ergonomics |
Escapes en strings (\n, \t, etc.) +
interpolacion "Hola {nombre}" |
Menos concatenacion manual y mejor legibilidad |
| List ergonomics |
append(value), acceso encadenado lista[i].prop,
encadenamiento general obj.a().b().c() y repeticion
[null] * n |
API de colecciones mas natural para uso diario |
| Function ergonomics |
return multilinea (cerrando con ;) |
Permite retornos complejos sin forzar una sola linea |
| I/O output |
print (sin salto), println, printf,
constante endl |
Control fino de salida y formato |
| Math module |
factorial, sqrt, pow,
log, ln, exp, trig, gcd,
lcm |
Cobertura numerica base para ciencia/ingenieria |
| Analyzer |
--mode analyze para errores/warnings previos a runtime con
resolucion cross-file de imports |
Deteccion temprana de fallas comunes en proyectos multi-archivo |
| Compiler/runtime |
Runtime bridge static|external |
Balance entre peso de binario y autonomia |
| Engine organization |
Builtins movidos a src/interpreter/interpreter_builtins.cpp
|
Mejor separacion de responsabilidades dentro del interprete |
| Enum |
Declaracion multilinea + enum_name/enum_value |
Mejor ergonomia y introspeccion de enum |
Compatibility Notes
Si venias de un comportamiento donde funciones sin return fallaban al usarse en
expresion,
ahora retornan null de forma implicita.
print() sin expresion sigue siendo invalido; usa println()
para solo salto de linea.
long mantiene rango estricto de 64 bits signed.
double ya no es el default para enteros literales; int
(BigInt) es el default.
for mantiene cabecera estilo Java
(for (init; cond; update):) y tambien acepta
for item in coleccion: sin parentesis para rangos/iterables simples.
continue; solo es valido dentro de bucles. Si aparece dentro de un
switch anidado en un bucle, continua la iteracion del bucle externo.
defer solo acepta sentencias simples y se ejecuta en orden LIFO al salir del
bloque actual.
return puede abrirse en una linea y cerrar en otra; el terminador
; sigue siendo obligatorio.
in verifica elementos en list/tuple/set,
claves en map, nombres de propiedad en object y substring en
string.
- En LLVM AOT nativo aun no hay lowering dedicado para
switch,
for-each, do-while, finally,
defer ni el operador in; compile mode puede resolverlos via
runtime bridge.
Instalacion Rapida
Instala Clot con los binarios de release y ejecuta tu primer archivo en minutos.
Linux / macOS
- Ejecuta el instalador.
- Reabre la terminal si es necesario.
- Corre
clot programa.clot.
curl -fsSL https://raw.githubusercontent.com/jclot/ClotLang/master/scripts/install.sh | bash
clot programa.clot
Windows (PowerShell)
- Ejecuta el instalador.
- Reinicia la terminal para actualizar PATH.
- Corre
clot programa.clot.
iwr -useb https://raw.githubusercontent.com/jclot/ClotLang/master/scripts/install.ps1 | iex
clot programa.clot
Los binarios de release se publican sin LLVM (solo modo interprete). Para usar
--mode compile, compila desde fuente con LLVM instalado.
Personalizacion
# Linux/macOS: fijar version o prefijo
CLOT_VERSION=v0.2.0 CLOT_PREFIX=~/.local curl -fsSL https://raw.githubusercontent.com/jclot/ClotLang/master/scripts/install.sh | bash
# Windows: fijar version o ruta
$env:CLOT_VERSION="v0.2.0"
$env:CLOT_INSTALL_DIR="C:\Ruta\Clot"
iwr -useb https://raw.githubusercontent.com/jclot/ClotLang/master/scripts/install.ps1 | iex
Checksums
# Linux/macOS
shasum -a 256 clot-linux-x86_64.tar.gz
# Windows
Get-FileHash clot-windows-x86_64.zip -Algorithm SHA256
Desinstalar
bash scripts/uninstall.sh
iwr -useb https://raw.githubusercontent.com/jclot/ClotLang/master/scripts/uninstall.ps1 | iex
Quickstart
Desde la raiz del repo, primero compila con CMake y luego ejecuta el binario generado.
Si ya instalaste con los binarios de release, puedes saltar directo a los ejemplos y la guia
de Control Flow.
# Opcion recomendada (presets WSL)
cmake --preset wsl-release
cmake --build --preset build-release -j4
# binario: ./build/wsl-release/clot
# Opcion directa (sin presets)
cmake -S . -B build -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCLOT_ENABLE_LLVM=ON
cmake --build build -j4
# binario: ./build/clot
cmake --build ...: build normal (sin forzar paralelismo).
-j4: 4 tareas en paralelo (acelera compilacion).
-jN: fija N tareas en paralelo (ej. -j8).
--parallel: paralelismo automatico segun el sistema.
--parallel N: paralelismo fijo con N tareas.
# Ejecutar en modo interprete
./build/wsl-release/clot hello.clot
# Analisis estatico
./build/wsl-release/clot hello.clot --mode analyze
# Compilar AOT con LLVM (si disponible)
./build/wsl-release/clot hello.clot --mode compile --emit exe -o hello
Si usaste la opcion sin presets, reemplaza ./build/wsl-release/clot por
./build/clot en los comandos.
// hello.clot
name = "Clot";
print("Hola, {name}\\n");
printf("%s %d\\n", "Version", 1);
Control Flow
Clot mantiene su estilo de bloques con : y cierres explicitos, pero ahora
cubre el repertorio de control de flujo que normalmente se espera en un lenguaje imperativo
moderno: while, for clasico, for-each,
do-while, switch, break,
continue y pass.
const long limit = 6;
sum = 0;
for (int i = 0; i < limit; i++):
if(i == 1):
continue;
endif
if(i == 4):
break;
endif
sum += i;
endfor
for (const item in [10, 20, 30]):
println(item);
endfor
for i in range(3):
println(i);
endfor
switch(sum):
case 5:
println("five");
break;
default:
pass;
endswitch
do:
sum -= 1;
while(sum > 0);
println("na" in "banana");
println("name" in {name: "Ada"});
for (init; cond; update): acepta declaraciones, mutaciones o expresiones
simples en init y update.
for (item in coleccion): y for item in coleccion: iteran
listas, tuple, set, map, object o string; const en el binding es
opcional.
switch usa fallthrough estilo Java hasta encontrar break; o
terminar el bloque.
pass; es un placeholder valido y no ejecuta ninguna accion.
El operador in es dual: sirve en for-each y tambien como
prueba de pertenencia. En map busca claves; en object busca
nombres de propiedad.
Ejemplo rapido de for
// for clasico
for (int i = 0; i < 3; i++):
println("classic {i}");
endfor
// for sobre rango numerico
for i in range(3):
println("range {i}");
endfor
Strings, Listas y Encadenamiento
// Escapes + interpolacion
user = "Ada";
total = 3;
print("Hola {user}\\n");
println("Tienes {total} notificaciones");
println("precio=" + 300.0); // conversion implicita a string
println("Plantilla {{user}}"); // imprime: Plantilla {user}
// append en listas
tasks = [];
tasks.append("build");
tasks.append("test");
println(tasks[1]); // "test"
// acceso encadenado
records = [{meta: {name: "Ana"}}];
println(records[0].meta.name);
// inicializacion por repeticion
slots = [null] * 4;
println(len(slots)); // 4
// encadenamiento general de llamadas
class Counter:
public int value = 0;
public func Counter add(delta: int):
this.value += delta;
return this;
endfunc
public func int value_get():
return this.value;
endfunc
endclass
println(Counter().add(2).add(3).value_get()); // 5
append(value) aplica a list. Si el receptor no es lista, el
runtime reporta error.
Return multilinea
func int pair_sum(a: int, b: int):
return
(
a +
b
);
endfunc
println(pair_sum(4, 5)); // 9
En strings con interpolacion, usa {{ y }} para imprimir llaves
literales. Ejemplo: "{{}}" imprime {}.
"{}" es interpolacion vacia (error) y \{/\} no son
escapes validos.
Error comun: append (incorrecto vs correcto)
// Incorrecto: tuple no soporta append
tuple pair = tuple("a", "b");
pair.append("c"); // runtime error
// Correcto: append en list
items = [];
items.append("a");
items.append("b");
println(items); // ["a", "b"]
Functions and References
func float free_fall_height(h0: float, v0: float, t: float, g: float = 9.81):
return h0 + v0 * t - (g * t * t) / 2;
endfunc
println(free_fall_height(100.0, 0.0, 2.0)); // usa g por defecto
println(free_fall_height(100.0, 0.0, 2.0, 10.0)); // override
func inc_and_print(&x):
x += 1;
println(x);
endfunc
int n = 10;
inc_and_print(&n);
func ping():
println("pong");
endfunc
function f = ping(); // referencia a funcion
f();
println(ping()); // imprime "pong" y luego "null"
Una funcion sin return explicito retorna null implicitamente.
Si la firma declara tipo de retorno (ej. func float ...), el runtime exige
return compatible.
OOP from Zero
Si nunca has usado OOP en Clot, piensa en class como un molde (template) y en
cada objeto como una instancia creada desde ese molde.
- Define el contrato con
interface (que metodos debe exponer la clase).
- Define la clase con atributos y constructor.
- Crea objetos llamando el nombre de la clase como funcion.
- Usa
this para referirte al objeto actual.
- Usa
super(...) si heredas con extends.
interface Greeter:
func string greet();
endinterface
class Person implements Greeter:
private string _name;
constructor(name: string):
this._name = name;
endconstructor
public func string greet():
return "Hola, soy " + this._name;
endfunc
endclass
p = Person("Ada");
println(p.greet());
Tip para principiantes: empieza con private + get/set para
encapsular datos, y agrega extends solo cuando necesites reutilizar logica.
Error Handling
Clot soporta throw(value) y cuatro variantes de catch:
catch:, catch(err):, catch(Tipo): y
catch(Tipo err):.
Ademas, finally: es opcional y siempre se ejecuta al cerrar el
try. Solo se permite un bloque catch por try.
Las formas validas son try/catch, try/finally y
try/catch/finally; si aparece, finally siempre va de ultimo.
En errores runtime internos, el binding de catch recibe un string localizado;
en throw(objeto) recibe el valor lanzado.
Si una excepcion no encuentra catch compatible, la ejecucion termina con
Excepcion no capturada: Tipo: mensaje (o Unhandled Exception en
ingles).
import clot.core.exceptions;
// 1) catch(err): captura cualquier error y expone binding
try:
throw("boom");
catch(err):
println(err);
endtry
// 2) catch(Tipo err): captura por tipo + binding
try:
throw(TypeError("dato invalido"));
catch(TypeError err):
println(err.message);
endtry
// 3) catch(Tipo): captura por tipo sin binding
try:
throw(ArgumentError("faltan argumentos"));
catch(ArgumentError):
println("argument error");
endtry
// 4) catch: captura generica sin binding
try:
throw(IOError("no se pudo abrir"));
catch:
println("generic catch");
endtry
// finally y defer en accion
func demo_cleanup():
defer println("defer: ultimo en declararse, primero en ejecutar");
defer println("defer: cleanup interno");
try:
throw("boom");
catch(err):
println(err);
finally:
println("finally: cleanup del try");
endtry
endfunc
demo_cleanup();
finally es parte del flujo de excepciones del try.
defer no depende de excepciones: agenda una sentencia simple y la ejecuta
cuando el bloque actual termina, incluso si hubo return o un error propagado.
// throw sin try/catch (excepcion no capturada) usando funcion
import clot.core.exceptions;
func fail():
throw(Exception("Something went wrong"));
endfunc
fail();
// Resultado:
// Excepcion no capturada: Exception: Something went wrong
Exception Types (Current)
| Type |
Parent |
Typical Source |
Exception |
- |
Raiz para excepciones de usuario |
RuntimeError |
Exception |
Fallback generico runtime |
TypeError |
RuntimeError |
Incompatibilidad de tipos/hints |
ArgumentError |
TypeError |
Aridad/forma invalida de argumentos |
MissingArgumentError |
ArgumentError |
Llamada con argumentos requeridos faltantes |
TooManyArgumentsError |
ArgumentError |
Llamada con mas argumentos de los aceptados |
ValueError |
RuntimeError |
Valor invalido semanticamente |
RangeError |
ValueError |
Valor fuera de rango permitido |
IndexError |
RangeError |
Indice fuera de rango en lista/tuple |
NameError |
RuntimeError |
Variable o funcion no definida |
AttributeError |
RuntimeError |
Acceso invalido a propiedad/clave |
IOError |
RuntimeError |
Errores de lectura/escritura de archivo |
FileNotFoundError |
IOError |
Archivo inexistente o ruta invalida |
PermissionError |
IOError |
Permisos insuficientes sobre archivo |
FileExistsError |
IOError |
Intento de crear archivo ya existente |
FileClosedError |
IOError |
Operacion sobre archivo cerrado |
AssertionError |
RuntimeError |
Fallo de assert |
ImportError |
RuntimeError |
Fallo de resolucion/carga de modulo |
ModuleNotFoundError |
ImportError |
Modulo no encontrado en rutas de import |
// Ejemplos runtime inferidos (sin construir objeto manual):
try:
println(missing_name);
catch(NameError err):
println(err);
endtry
try:
obj = {name: "Ada"};
println(obj.age);
catch(AttributeError err):
println(err);
endtry
try:
type();
catch(MissingArgumentError err):
println(err);
endtry
try:
input("a", "b");
catch(TooManyArgumentsError err):
println(err);
endtry
try:
read_file("missing.txt");
catch(FileNotFoundError err):
println(err);
endtry
try:
sleep_ms(-1);
catch(RangeError err):
println(err);
endtry
try:
import ghost.module;
catch(ModuleNotFoundError err):
println(err);
endtry
Analyze and Compile Pipeline
- Ejecuta
--mode analyze para detectar fallas tipicas antes de runtime.
- Corre en interprete para validar comportamiento dinamico.
- Compila con LLVM cuando tu subset de programa sea compatible con AOT.
- Para QA de fases, usa el test diferencial interpret vs compile y el baseline de
benchmarks.
./build/wsl-release/clot app.clot --mode analyze --lang en
./build/wsl-release/clot app.clot --lang en
./build/wsl-release/clot app.clot --mode compile --emit exe -o app --runtime-bridge external
scripts/diff_interpret_compile.sh ./build/wsl-release/clot app.clot
benchmarks/baseline.sh ./build/wsl-release/clot
Lexical Structure
| Elemento |
Regla |
Ejemplo |
| Comentario |
Linea iniciada con // desde ese punto |
// comentario |
| Identificador |
Empieza con letra o _, permite digitos, _ y
. |
mi_var, cfg.db.host |
| String |
Delimitado con ", soporta escapes e interpolacion
{expr}; llaves literales con {{ y
}} |
"hola\\n{name} {{ok}}" |
| Char |
Delimitado con ', longitud 1 o escape valido |
'a', '\\n', '\\0' |
| Numero entero literal |
Secuencia de digitos sin punto |
42, 9223372036854775808 |
| Numero decimal literal |
Incluye punto decimal |
3.14 |
Type System (Modifier and Type Summary)
| Keyword / Type |
Runtime Representation |
Range / Precision |
Validation Rules |
Example |
const |
Variable slot inmutable |
N/A |
Requiere inicializacion inmediata; solo acepta =; protege el
binding contra reasignacion y no puede redeclararse sobre una binding ya
existente |
const long limit = 10; |
int |
BigInt dinamico |
Limitado por RAM |
Sin overflow fijo; conversiones a tipos finitos pueden fallar |
int a = 999999999999999999999; |
double |
IEEE-754 64-bit |
~15-17 digitos decimales |
Debe ser finito |
double x = 1.5; |
float |
IEEE-754 32-bit |
~6-7 digitos decimales |
Rango de float; si no cabe, error |
float y = 2.5; |
decimal |
Decimal exacto (coeficiente BigInt + escala) |
Precision decimal exacta (segun RAM/escala) |
Parse decimal valido requerido |
decimal m = cast("12.3400", "decimal"); |
long |
Signed 64-bit |
-9223372036854775808 a 9223372036854775807 |
Fuera de rango: error |
long l = 9223372036854775807; |
byte |
Entero restringido |
0 a 255 |
Fuera de rango: error |
byte b = 255; |
char |
Caracter individual |
ASCII 0..255 o string longitud 1 |
Valor invalido para char: error |
char c = 'A'; |
string |
Cadena UTF-8 cruda |
N/A |
Conversion numerica depende del contenido |
s = "texto"; |
bool |
Booleano |
true / false |
Conversion implicita via truthiness |
ok = true; |
null |
Valor nulo |
N/A |
Falsy, usado para ausencia de valor; equivalente conceptual al
None de Python |
v = null; |
list |
Vector mutable indexado |
Indices enteros >= 0 |
Indice fuera de rango: error |
arr = [1, 2, 3]; |
tuple |
Secuencia inmutable |
Indexable, no mutable con [] |
Mutacion: error |
tuple t = tuple(1, 2); |
set |
Coleccion sin repetidos |
Unicidad por comparacion de valores |
Insercion duplicada se ignora |
set s = set(1, 1, 2); |
map |
Pares clave/valor con clave no-string permitida |
Acceso por [] |
Clave no encontrada: error en lectura |
map m = map("a", 1, 2, "b"); |
object |
Pares string -> value |
Acceso por punto y por indice string |
Propiedad ausente: error en lectura |
o = {name: "Ada"}; |
function |
Referencia a funcion |
Invocable con () |
Solo acepta refs validas |
function f = ping(); |
TipoDeClase (ej. User) |
Instancia de clase nominal |
N/A |
Exige instancia de esa clase o subclase en firmas/declaraciones tipadas
|
User owner = User(); |
Clot no soporta declaraciones vacias estilo int x;. Toda binding nace con un
valor inicial. Si necesitas reservar la variable para completarla despues, usa
x = null;. null es un valor real de ausencia, no un estado
especial de "sin inicializar".
Declaraciones locales tipadas (explicitas)
Puedes declarar variables locales con tipo explicito usando la misma sintaxis de tipos del
lenguaje. La validacion ocurre en runtime al asignar y al reasignar.
string nombre = "Ada";
bool activo = true;
null vacio = null;
list bolsa = [1, "dos", true]; // tipado de contenedor
list<int> ids = [1, 2, 3]; // tipado interno fuerte
Regla practica: primero defines el tipo del contenedor
(list/map/object/tuple/set) y luego, si necesitas validacion interna fuerte,
agregas genericos (list<T>, map<K,V>, etc.).
Field Summary for Composite Types
| Type |
Field / Access |
Description |
list |
list[idx] |
Lectura/escritura por indice entero >= 0 |
tuple |
tuple[idx] |
Lectura por indice; mutacion no permitida |
set |
Iteracion/representacion |
No hay API mutadora dedicada aun; conversiones via
set()/cast |
map |
map[key] |
Permite claves de cualquier tipo comparable |
object |
obj.prop, obj["prop"] |
Claves string; obj.new = ... puede crear propiedad |
enum |
Enum.MEMBER |
Valor numerico secuencial desde 0 |
Operators
| Category |
Operators |
Notes |
| Unary |
+, -, ! |
Aplican sobre expresiones compatibles |
| Power |
^ |
Asociatividad a derecha |
| Multiplicative |
*, /, % |
Modulo por cero: error |
| Additive |
+, - |
+ concatena si hay string |
| Comparison |
<, <=, >, >=
|
Resultado bool |
| Equality |
==, != |
Comparacion profunda para colecciones |
| Logical |
&&, || |
Evaluacion booleana |
| Assignment |
=, +=, -= |
Declaracion tipada solo permite = |
| Membership |
in |
lhs in rhs revisa elementos en
list/tuple/set, claves en map, propiedades en
object y substring en string |
i++ y i-- estan soportados como shorthand en el slot
update del for clasico. No forman parte de la gramatica general
de expresiones fuera de ese contexto.
Statements
| Construct |
Syntax |
Validation |
| If / else |
if cond: ... else: ... endif |
: obligatorio; cierre con endif |
| While |
while cond: ... endwhile |
Cierre obligatorio endwhile |
| Assignment / declaration |
name = expr; y variantes tipadas/const con valor
inicial |
Toda binding requiere valor inicial; no existe declaracion vacia estilo
int x; |
| Const declaration |
const name = expr; o const tipo name = expr; |
Inmutable despues de inicializar; no acepta += ni
-= |
| For (classic) |
for (init; cond; update): ... endfor |
Cabecera estilo Java; init/update solo aceptan
declaraciones, mutaciones o expresiones simples |
| For-each |
for (item in collection): ... endfor o
for item in collection: ... endfor |
Binding opcionalmente tipado y/o const; itera
list, tuple, set, map,
object o string |
| Do-while |
do: ... while(cond); |
El cuerpo se ejecuta al menos una vez; el cierre exige
while(cond); |
| Switch |
switch(expr): case valor: ... default: ... endswitch |
Soporta fallthrough estilo Java; solo un default |
| Loop/switch flow |
break;, continue;, pass; |
break sale de bucle o switch;
continue solo aplica a bucles; pass no-op |
| Function |
func nombre(args): ... endfunc o
func tipo nombre(args): ... endfunc con
param = expr opcional |
Firma invalida o tipo no reconocido produce parse error |
| Class / Interface |
class C [extends B] [implements I]: ... endclass,
abstract class C ... endclass,
interface I: ... endinterface |
Soporta herencia simple, contratos por interface y miembros con
visibilidad/modificadores OOP (incluye protected y
abstract) |
| Constructor / Accessors |
constructor(...): ... endconstructor,
get p(): ... endget, set p(v): ... endset |
En clases derivadas, super(...) debe ser la primera sentencia
del constructor |
| Return |
return;, return expr; o return multilinea
terminado en ; |
Fuera de formato o sin ;: parse error |
| Try/catch/finally |
try: ... catch:|catch(err):|catch(Tipo):|catch(Tipo err): ...
finally: ... endtry
|
Solo un catch; requiere endtry; formato de
catch/finally estricto; formas validas:
try/catch, try/finally o
try/catch/finally; finally es opcional y va al
final |
| Defer |
defer sentencia_simple; |
Solo agenda sentencias simples; ejecucion LIFO al salir del bloque actual
|
| Import |
import modulo;, import modulo as alias;,
from modulo import simbolo;,
from modulo import simbolo as alias; |
Soporta modulo completo, alias y symbol import directo |
| Enum |
enum E { A, B }; o multilinea |
No se permite coma final |
El for-each no exige const. Estas formas son validas:
for (item in xs):, for item in xs:,
for (const item in xs):,
for (int item in xs): y for (const int item in xs):.
const solo vuelve inmutable el binding de iteracion dentro del cuerpo.
const long n = 5;
sum = 0;
for (int i = 0; i < n; i++):
sum += i;
endfor
switch(sum):
case 10:
println("ten");
break;
default:
pass;
endswitch
try:
defer println("fin de bloque");
println("id" in {id: 1});
finally:
println("cleanup");
endtry
Functions
- Parametros por referencia declarados con
& en la firma:
func f(&x):.
- En llamada, usa
&var para pasar por referencia si la firma lo requiere.
- Type hints opcionales:
func float media(a: float, b: float):.
- Tipo de retorno declarado: solo admite 1 tipo por funcion (no union
types como
int|string).
- Tipos soportados en hints de retorno/parametros:
int, double,
float, decimal, long, byte,
char, tuple, set, map,
function, string, bool, list,
object, null y tipos de clase de usuario
(ej. User, crm.models.Customer).
- Soporte de genericos en hints:
list<T>, tuple<T>,
set<T>, object<T>, map<K, V>.
- Los tipos de clase son nominales: el valor debe ser una instancia de esa clase (o una
subclase). El parser no soporta genericos nominales estilo
MiClase<T>.
- Tipado de colecciones en 2 fases:
list/object para el contenedor y
list<int>/map<string, int> para tipado interno
fuerte (incluye anidacion).
- Tambien puedes usar clases como tipo interno en colecciones:
list<User>, map<string, User>,
object<User>.
any y dynamic son alias: ambos significan tipo dinamico
(internamente equivalente a omitir el tipo).
- Sin tipo de retorno (
func nombre(...):) o con
func any nombre(...):/func dynamic nombre(...):, el retorno es
dinamico y puede variar por llamada.
- Tambien aplica a parametros:
x, x: any y
x: dynamic son equivalentes y aceptan cualquier tipo de valor.
- Nota:
any/dynamic en la doc significa "any o dynamic"; no se escribe con
barra en el codigo fuente.
- Valores por defecto soportados en parametros por valor:
func f(x: float = 1.0):.
- Las funciones son de primera clase via tipo
function.
- Si no hay
return, el valor implicito es null.
return acepta formato multilinea; el parser sigue leyendo hasta encontrar
;.
- Si declaras tipo de retorno, la funcion debe retornar un valor compatible con ese tipo.
En
func null ..., debes hacer return null; explicito.
- Las llamadas de miembro pueden encadenarse sobre resultados intermedios (por ejemplo:
builder.make().with_x(1).build()).
- Reglas de firma: los parametros sin default no pueden ir despues de uno con default;
parametros por referencia (
&) no aceptan default.
func string greet(name: string):
return "Hola " + name;
endfunc
func float add(a: float, b: float = 0.0):
return a + b;
endfunc
func touch(&x):
x += 1;
endfunc
function ref = add;
println(ref(2, 3));
func any echo_any(x: any):
return x;
endfunc
func dynamic echo_dynamic(x: dynamic):
return x;
endfunc
func show_params(a, b: any, c: dynamic):
println(a);
println(b);
println(c);
endfunc
println(echo_any("hola"));
println(echo_dynamic(42));
show_params(10, "texto", [1, 2, 3]);
Return multilinea
func int weighted_sum(a: int, b: int):
return
(
a * 2 +
b
);
endfunc
El ; final sigue siendo obligatorio. Si falta, el parser reporta
Falta ';' para cerrar return..
Firmas con tipos de clase personalizados
class User:
public string name = "anon";
endclass
func User make_user(name: string):
u = User();
u.name = name;
return u;
endfunc
func string greet_user(user: User):
return "Hola " + user.name;
endfunc
println(greet_user(make_user("Ada")));
Si un parametro/retorno esta anotado como User, pasar un valor no-instancia
produce error de tipo en runtime.
Declaraciones locales tipadas
string title = "Reporte";
bool ok = true;
null nothing = null;
// Clases en variables locales tipadas
User owner = make_user("Lin");
Tipado de Colecciones (Detallado)
El modelo actual funciona en dos fases:
tipado de contenedor y
tipado interno fuerte.
Fase 1: Tipado del contenedor
Valida que el valor sea del tipo de coleccion correcto, pero no restringe los elementos
internos.
// Contenedor tipado (interno flexible)
list datos = [1, "dos", true];
object meta = {id: 1, name: "Ana", ok: true};
tuple t = tuple(1, "x");
println(type(datos)); // list
println(type(meta)); // object
Fase 2: Tipado interno fuerte (Genericos)
Ademas del contenedor, valida recursivamente el tipo interno de cada elemento.
list<int> ids = [1, 2, 3];
tuple<float> coords = tuple(1, 2.5, 3);
set<char> letras = set('a', "b", 67);
map<string, int> score = map("ana", 10, "luis", 20);
object<int> counters = {ok: 5, fail: 1};
// Anidacion valida
list<map<string, int>> tabla = [map("a", 1), map("b", 2)];
Casos de error esperados
list<int> bad1 = [1, "2"]; // Elemento list[1] incompatible con 'int'
map<string, int> bad2 = map("ana", 10, 2, 20); // Clave map[1] incompatible con 'string'
object<int> bad3 = {ok: 1, label: "x"}; // Propiedad object.label incompatible con 'int'
Funciones con colecciones tipadas
func list<int> keep(xs: list<int>):
return xs;
endfunc
println(keep([1, 2, 3]));
// println(keep([1, "x"])); // error en argumento 'xs'
func map<string, int> mk_scores():
return map("a", 10, "b", 20);
endfunc
for-each con binding tipado
for (int n in [10, 20, 30]):
println(n);
endfor
for (list<int> row in [[1, 2], [3, 4]]):
println(row[0]);
endfor
Regla de aridad generica:
list<T>, tuple<T>, set<T>,
object<T> y map<K, V>.
Tambien se permite el tipo sin genericos (ej. tuple, map)
para compatibilidad.
OOP MVP+ (Guia Completa)
Esta seccion resume exactamente lo implementado en la fase actual para OOP
(MVP + extensiones de encapsulacion/abstraccion).
Si eres principiante total, empieza por la tabla de construcciones y luego ejecuta el
ejemplo completo.
Estado actual OOP: disponible en --mode interpret. En
--mode compile,
el lenguaje completo (incluyendo OOP) se soporta via runtime bridge cuando AOT nativo no
cubre una feature.
Construcciones OOP y para que sirven
| Construccion |
Para que sirve |
Sintaxis base |
interface ... endinterface |
Define contrato (metodos obligatorios) sin estado. |
interface I: func f(); endinterface |
class ... endclass |
Define tipo de objeto con campos, metodos y constructor. |
class C: ... endclass |
extends |
Herencia simple (una clase base). |
class B extends A: |
implements |
Implementa uno o varios contratos de interface. |
class C implements I1, I2: |
constructor ... endconstructor |
Inicializa estado del objeto al crear instancia. |
constructor(x: int): ... endconstructor |
this |
Referencia al objeto actual dentro de la clase. |
this.name = value; |
super(...) |
Llama constructor de la clase base. |
super(id); |
super.metodo(...) |
Llama implementacion heredada del metodo base. |
return super.info(); |
get ... endget |
Lectura controlada de una propiedad. |
get name(): return this._name; endget |
set ... endset |
Escritura controlada de una propiedad. |
set name(v: string): this._name = v; endset |
Modificadores OOP
| Modificador |
Significado |
Aplica a |
Nota |
public |
Visible desde fuera de la clase. |
Campos, metodos, get/set, constructor |
Es el default. |
private |
Solo visible dentro de su clase propietaria. |
Campos, metodos, get/set, constructor |
Acceso externo produce error runtime. |
protected |
Visible en la clase propietaria y subclases. |
Campos, metodos, get/set |
Acceso externo produce error runtime. |
static |
Miembro de clase (no de instancia). |
Campos y metodos |
Se invoca con Clase.miembro. |
readonly |
Campo de solo lectura luego de inicializacion permitida. |
Campos |
Instancia: solo constructor de la clase propietaria. Static: no mutable
luego de declaracion. |
override |
Declara sobrescritura de metodo heredado. |
Metodos |
Es obligatorio cuando existe metodo base. |
abstract |
Declara clase/metodo incompleto para forzar implementacion en subclases. |
Clases y metodos |
Una clase concreta no puede dejar metodos abstractos sin implementar. |
Tipos de clase en firmas (metodos, interfaces y constructores)
En OOP puedes usar tipos de clase en firmas de metodos, parametros de constructor y firmas
de interfaces. La verificacion es nominal y respeta herencia.
class User:
public string name = "anon";
endclass
interface UserReader:
func User find(id: string);
endinterface
class UserRepo implements UserReader:
public func User find(id: string):
u = User();
u.name = "id=" + id;
return u;
endfunc
endclass
class UserService:
constructor(repo: UserReader):
this.repo = repo;
endconstructor
public func string label(user: User):
return "User(" + user.name + ")";
endfunc
endclass
Ejemplo corto: abstract + protected
abstract class Report:
protected string source;
constructor(source: string):
this.source = source;
endconstructor
protected func string prefix():
return "source=" + this.source;
endfunc
public abstract func string render():
endfunc
endclass
class SalesReport extends Report:
constructor(source: string):
super(source);
endconstructor
public override func string render():
return this.prefix() + " total=42";
endfunc
endclass
report = SalesReport("Q1");
println(report.render()); // "source=Q1 total=42"
Error comun: protected (incorrecto vs correcto)
class Counter:
protected int value;
constructor(initial: int):
this.value = initial;
endconstructor
public func int read():
return this.value;
endfunc
endclass
c = Counter(7);
println(c.read()); // Correcto
println(c.value); // Incorrecto: acceso externo a protected
Ejemplo OOP completo (todo lo disponible en esta fase)
interface NamedEntity:
func string display_name();
endinterface
interface Serializable:
func string serialize();
endinterface
class Entity:
private string _id;
public static int created = 0;
public readonly string created_by;
constructor(id: string, created_by: string = "system"):
this._id = id;
this.created_by = created_by;
Entity.created += 1;
endconstructor
public get id():
return this._id;
endget
public set id(value: string):
this._id = value;
endset
public func string base_info():
return "Entity#" + this._id;
endfunc
endclass
class User extends Entity implements NamedEntity, Serializable:
private string _name;
constructor(id: string, name: string):
super(id, "admin");
this._name = name;
endconstructor
public override func string base_info():
return super.base_info() + " user";
endfunc
public func string display_name():
return this._name;
endfunc
public func string serialize():
return "{id:" + this.id + ",name:" + this._name + "}";
endfunc
public get name():
return this._name;
endget
public set name(value: string):
this._name = value;
endset
endclass
u = User("U-001", "Ada");
println(u.base_info());
println(u.display_name());
println(u.name);
u.name = "Ada Lovelace";
println(u.serialize());
println(Entity.created);
Validaciones OOP importantes (runtime)
| Regla |
Que valida |
Resultado si falla |
implements |
Que la clase implemente todos los metodos de la interface con firma
compatible. |
Error al registrar la clase. |
override |
Que sobrescritura sea explicita y compatible (aridad, static/instancia,
retorno, hints). |
Error al registrar la clase. |
private |
Que no se acceda un miembro privado desde fuera de su clase. |
Error de ejecucion por visibilidad. |
protected |
Que solo la clase propietaria o sus derivadas accedan al miembro. |
Error de ejecucion por visibilidad. |
readonly |
Que no se modifique fuera de contexto permitido. |
Error de ejecucion. |
abstract |
Que una clase concreta implemente metodos abstract heredados y que una
clase abstract no se instancie. |
Error al registrar la clase o al instanciar. |
super(...) en derivadas |
Que exista y sea primera sentencia del constructor derivado (una sola
llamada). |
Error de ejecucion. |
Errores frecuentes (con ejemplo)
// 1) Falta override
class A:
public func int f():
return 1;
endfunc
endclass
class B extends A:
public func int f():
return 2;
endfunc
endclass
// Error: metodo sobrescribe base y requiere override
// 2) super(...) no es primera sentencia
class C extends A:
constructor():
x = 1;
super();
endconstructor
endclass
// Error: super(...) debe ir primero
Collections
list_values = [10, 20, 30];
println(list_values[1]);
obj = {name: "Ada", score: 10};
println(obj.name);
obj.level = "pro";
println([{user: obj}][0].user.name);
queue = [];
queue.append("first");
queue.append("second");
println(queue[1]);
holes = [null] * 3;
println(len(holes));
tuple pair = tuple("x", 99);
set uniq = set(1, 1, 2, 3);
map dict = map("a", 1, 2, "b");
println(dict[2]);
func int inc(x: int):
return x + 1;
endfunc
holder = {ops: {inc: inc}};
println(holder.ops["inc"](10)); // llamada encadenada sobre resultado intermedio
println(20 in list_values); // true
println("a" in dict); // true (clave)
println("name" in obj); // true (propiedad)
println("da" in "Ada"); // true (substring)
Colecciones tipadas por fases
// Fase 1: tipado de contenedor (interno flexible)
list bucket = [1, "dos", true];
map registry = map("id", 1, 2, "dos");
// Fase 2: tipado interno fuerte
list<int> numbers = [1, 2, 3];
map<string, int> scores = map("ana", 10, "bob", 20);
object<int> counters = {ok: 1, fail: 0};
Colecciones tipadas con clases
class Item:
public string name = "n/a";
endclass
i1 = Item();
i1.name = "A";
i2 = Item();
i2.name = "B";
list<Item> items = [i1, i2];
for (Item it in items):
println(it.name);
endfor
Mutar tuple con [] genera error runtime.
El operador in no busca valores dentro de map u
object; busca claves o nombres de propiedad.
append(value) solo aplica a listas.
El encadenamiento de llamadas funciona sobre expresiones; en objetos, usa
[] cuando necesites seleccionar un miembro invocable por nombre dinamico.
Enum
Los enums se almacenan como objetos con miembros numericos secuenciales iniciando en 0.
Puedes recuperar nombre o valor mediante helpers.
enum Estado {
ACTIVO,
INACTIVO,
SUSPENDIDO
};
println(Estado.INACTIVO); // 1
println(enum_name(Estado, Estado.INACTIVO)); // "INACTIVO"
println(enum_value(Estado, "ACTIVO")); // 0
Validations and Limits
| Validation |
Condition |
Runtime behavior |
long range |
Valor fuera de [-2^63, 2^63-1] |
Error: Valor fuera de rango para long. |
byte range |
Valor fuera de [0, 255] |
Error de rango |
| List index |
No entero finito o fuera de rango |
Error de indice |
| Map/Object access |
Clave o propiedad ausente |
Error de clave/propiedad |
| Function arity |
Numero de argumentos distinto |
Error de ejecucion |
| Function type hints |
Argumento o retorno incompatible con hint declarado |
Error de ejecucion por mismatch de tipo |
| Interface contracts |
Clase no implementa metodo requerido, firma incompatible o metodo no publico
|
Error al declarar/registrar la clase |
| Override rules |
Sobrescritura sin override o con firma/retorno incompatible
|
Error al declarar/registrar la clase |
| Visibility |
Acceso externo a miembro private |
Error de ejecucion por visibilidad |
readonly field |
Asignacion fuera del constructor de la clase propietaria |
Error de ejecucion |
readonly static field |
Intento de mutacion despues de declaracion |
Error de ejecucion |
const binding |
Reasignacion, +=/-= o declaracion sobre
propiedad de objeto |
Error de parse o runtime segun el caso |
| Standalone declaration |
Uso de int x;, long y; o cualquier declaracion sin
inicializador |
Parse error |
| Derived constructor |
Falta super(...) como primera sentencia o se llama mas de una
vez |
Error de ejecucion |
| Function defaults (signature) |
Parametro obligatorio despues de uno con default o default en
& |
Parse error en declaracion de funcion |
for header |
Cabecera mal formada o uso de bloques/control de flujo en
init/update |
Parse error |
for-each |
Coleccion no iterable por el runtime o binding invalido |
Parse error o runtime error |
do-while grammar |
Falta cierre while(cond); |
Parse error |
switch grammar |
Falta endswitch, no hay labels o hay multiples
default |
Parse error |
break/continue |
Uso fuera de contexto valido |
Error de ejecucion |
defer |
Sentencia vacia, sentencia compuesta o uso fuera de bloque |
Parse error o runtime error |
in membership |
Lado derecho no es list, tuple,
set, map, object o
string |
Error de ejecucion |
| try/catch/finally grammar |
Falta catch/finally/endtry o formato
invalido de catch/finally |
Parse error |
null / none |
Uso de none esperando un literal nulo |
none no es keyword; usa null |
| LLVM AOT native coverage |
Uso de switch, for-each, do-while,
defer, finally o in fuera del subset
AOT nativo |
Fallback via runtime bridge o diagnostico de compile mode |
Aunque int evita overflow fijo, operaciones masivas pueden agotar memoria.
Valida
input externo y tamano de datos en aplicaciones de larga duracion.
Base Builtins - Method Summary
| Function |
Signature |
Returns |
Summary |
Validation |
print |
print(expr); |
void (statement) |
Imprime sin salto de linea |
Requiere expresion interna |
println |
println(); o println(expr); |
int (0) |
Imprime con salto final |
Max 1 argumento |
printf |
printf(format, ...args); |
int chars emitidos |
Formato estilo C para salida controlada |
Chequea aridad y tipo por especificador |
input |
input(); o input(prompt); |
string |
Lee una linea de stdin |
Max 1 argumento |
throw |
throw(value); |
No retorna (lanza excepcion) |
Interrumpe flujo y delega a try/catch |
Requiere exactamente 1 argumento |
Special field: endl es una constante resoluble en runtime con
valor
"\n". Uso tipico: print(endl);.
printf - Specifier Summary
| Specifier |
Expected Type |
Behavior |
Example |
%d, %i |
Integer |
Entero con signo |
printf("%d", -12); |
%u |
Integer >= 0 |
Entero sin signo |
printf("%u", 12); |
%f |
Numeric |
Flotante en formato fijo (6 decimales) |
printf("%f", 1.5); |
%c |
char, string len=1 o int ASCII 0..255 |
Caracter individual |
printf("%c", 'A'); |
%s |
Any |
Usa conversion ToString() |
printf("%s", [1,2]); |
%x, %X |
Integer >= 0 |
Hexadecimal lower/upper |
printf("%X", 255); |
%% |
N/A |
Emite literal % |
printf("100%%"); |
Si faltan o sobran argumentos, printf falla con error runtime.
Core Module - Method Summary
| Function |
Signature |
Returns |
Description |
type |
type(value) |
string |
Nombre de tipo runtime (int, double,
list, etc.) |
cast |
cast(value, type_name) |
Typed value |
Convierte a tipo destino si es valido |
isinstance |
isinstance(value, type_name) |
bool |
Chequeo de tipo runtime (builtin o clase) |
hash |
hash(value) |
int |
Fingerprint estructural estable para comparacion |
id |
id(value) |
int |
Identidad runtime estable por igualdad de valor |
assert |
assert(cond) o assert(cond, msg) |
true en exito |
Falla con runtime error si cond es falsy |
throw |
throw(value) |
N/A |
Lanza excepcion; usable con mensajes o instancias de clase |
println(type(10)); // int
println(type(cast(1.2, "float"))); // float
assert(2 + 2 == 4, "math broken");
try:
throw("boom");
catch(err):
println(err);
endtry
Collection Helpers and Enum Helpers
| Function |
Signature |
Returns |
Notes |
len |
len(value) |
int |
Longitud de string/list/tuple/set/map/object/char |
range |
range(stop), range(start, stop, step) |
list |
Secuencia de enteros; step no puede ser 0; max 1,000,000 elementos |
enumerate |
enumerate(iterable, start=0) |
list de tuple(index, value) |
Iteracion indexada en runtime |
zip |
zip(iter1, iter2, ...) |
list de tuple |
Combina iterables hasta el menor largo |
all / any |
all(iterable), any(iterable) |
bool |
Validaciones logicas masivas sobre elementos truthy/falsy |
tuple |
tuple(v1, v2, ...) |
tuple |
Construye secuencia inmutable |
set |
set(v1, v2, ...) o set(list_or_tuple_or_set) |
set |
Deduplica por igualdad profunda |
map |
map(key, value, ...) |
map |
Requiere cantidad par de argumentos |
enum_name |
enum_name(enum_obj, value) |
string |
Busca nombre de miembro por valor |
enum_value |
enum_value(enum_obj, name) |
int |
Busca valor por nombre de miembro |
chr / ord |
chr(code), ord(char) |
char / int |
Conversion ASCII (0..255) entre entero y caracter |
hex / bin |
hex(value), bin(value) |
string |
Representacion de enteros con prefijo 0x/0b |
println(range(1, 6, 2)); // [1, 3, 5]
println(enumerate(["a", "b"], 5)); // [(5, "a"), (6, "b")]
println(zip([1, 2, 3], "ab")); // [(1, 'a'), (2, 'b')]
println(all([1, true, "x"])); // true
println(isinstance(10, "number")); // true
println(hex(-26)); // -0x1a
System and Async Builtins
| Function |
Signature |
Returns |
Validation / Errors |
read_file |
read_file(path) |
string |
Archivo debe existir y abrirse correctamente |
write_file |
write_file(path, content) |
true |
Error si no puede abrir/escribir |
append_file |
append_file(path, content) |
true |
Escritura append |
file_exists |
file_exists(path) |
bool |
Consulta filesystem |
now_ms |
now_ms() |
long |
No acepta argumentos |
sleep_ms |
sleep_ms(ms) |
int (0) |
ms debe ser entero >= 0 |
async_read_file |
async_read_file(path) |
task_id (int) |
Crea tarea asincrona de lectura |
task_ready |
task_ready(task_id) |
bool |
Task id debe existir |
await |
await(task_id) |
resultado de tarea |
Consume y elimina task; error si task falla |
id = async_read_file("data.txt");
while !task_ready(id):
sleep_ms(10);
endwhile
content = await(id);
println(content);
Math Module - Method Summary
Para usar estas funciones debes hacer import math;.
| Function |
Signature |
Returns |
Validation |
sum |
sum(a, b) |
numeric |
2 args |
factorial |
factorial(n) |
int |
n entero no negativo, n <= 100000 |
sqrt |
sqrt(x) |
double |
x >= 0 |
pow |
pow(a, b) |
numeric |
exponente entero gigante puede fallar |
log |
log(x) / log(x, base) |
double |
x > 0, base > 0, base != 1 |
ln |
ln(x) |
double |
x > 0 |
exp |
exp(x) |
double |
1 arg |
abs |
abs(x) |
numeric |
1 arg |
sin, cos, tan |
fn(x) |
double |
1 arg |
asin, acos |
fn(x) |
double |
-1 <= x <=1 |
atan |
atan(x) |
double |
1 arg |
gcd |
gcd(a, b) |
int |
a y b enteros |
lcm |
lcm(a, b) |
int |
a y b enteros |
import math;
println(factorial(10));
println(gcd(84, 36));
println(pow(2, 100));
println(log(100, 10));
Math Constants - Field Summary
| Name |
Approx Value |
Availability |
Notes |
PI / pi |
3.141592653589793 |
import math; |
Circle ratio |
E / e |
2.718281828459045 |
import math; |
Euler constant |
TAU / tau |
6.283185307179586 |
import math; |
2 * PI |
PHI / phi |
1.618033988749895 |
import math; |
Golden ratio |
Package Layout
project/
app.clot
clot/
science/
utils/
utils.clot
core/
helpers/
helpers.clot
exceptions/
exceptions.clot
import clot.science.utils;
import clot.core.helpers;
import clot.core.exceptions;
// 1) Import de modulo completo
import scripts.math;
// 2) Import de modulo con alias
import scripts.math as math;
// 3) Import directo de simbolo
from scripts.math import add;
// 4) Import directo de simbolo con alias
from scripts.math import Box as Caja;
println(add(2, 3));
println(math.add(4, 5));
a = Caja(7);
b = math.Box(9);
println(a.value + b.value);
Si el modulo no tiene extension, el runtime busca .clot automaticamente.
Module Resolution Order
| Priority |
Root |
Purpose |
| 1 |
Ruta relativa al modulo actual |
Import directo por path logico |
| 2 |
Ancestros del modulo actual (hasta raiz) |
Lookup root-based para proyecto con carpetas profundas |
| 3 |
clot/ |
Root canonico recomendado para modulos del proyecto |
| 4 |
modules.* (legacy) |
Alias de compatibilidad hacia clot/science |
| 5 |
mods/ (legacy) |
Alias de compatibilidad hacia clot/core |
Imports legacy como modules.x o mods.x siguen funcionando, pero
la estructura recomendada para codigo nuevo es clot/ con subcarpetas por
dominio.
Package Contract
- Define una API publica clara via funciones con firmas estables.
- Evita side effects al importar, salvo inicializacion minima.
- Documenta precondiciones y errores esperados.
- Incluye pruebas smoke para rutas criticas.
Why does int not overflow but long does?
int usa BigInt dinamico (limitado por memoria), mientras long es
un entero signed fijo de 64 bits. Si excede su rango, el runtime falla por validacion.
How do I print with and without newline?
print(expr); no agrega salto.
println(expr); agrega salto.
print(endl); emite solo salto de linea.
printf(...) permite formato tipo C.
What happens if a function does not return?
Devuelve null implicitamente. Ejemplo: println(mi_func());
imprimira
null si no hubo return explicito. Excepcion: si la funcion declara
un
tipo de retorno (por ejemplo func int f(...):), entonces debe retornar un valor
compatible o se produce error runtime.
Tambien puedes escribir return en varias lineas siempre que cierres con
;.
Cantidad de tipos de retorno por funcion: uno cuando declaras hint
(func int ..., func string ..., etc.). Si quieres comportamiento
multi-tipo, usa retorno dinamico (func ... sin tipo, o
func any .../func dynamic ...).
any y dynamic son equivalentes.
Tipos declarables: int, double, float,
decimal,
long, byte, char, tuple,
set,
map, function, string, bool,
list,
object y null.
Does for-each require const?
No. const es opcional en el binding del for-each.
for (item in values):
println(item);
endfor
for item in values:
println(item);
endfor
for (const item in values):
println(item);
endfor
Usa const cuando quieras impedir reasignar la variable de iteracion dentro del
cuerpo. Si no lo necesitas, el binding simple item es valido.
Can I declare a variable first and assign later?
No con una declaracion vacia estilo C/Java. En Clot, toda binding debe nacer con un valor.
int x; es invalido.
// invalido
int x;
// valido
x = null;
x = 42;
// valido con tipo local explicito
string name = "Ada";
bool ready = false;
Usa null como placeholder cuando quieras "todavia no tengo valor". Eso no
significa "sin inicializar": significa "inicializado con ausencia de valor".
When does defer run?
defer programa una sentencia simple para el final del bloque actual. No corre en
el punto donde aparece, sino al salir del bloque. El orden es LIFO.
func sample():
defer println("third");
defer println("second");
println("body");
endfunc
sample();
// salida:
// body
// second
// third
Su uso practico tipico es cleanup por bloque: liberar recursos, restaurar estado, registrar
logs finales o ejecutar pasos que deben correr antes de abandonar el bloque.
What does in check?
valor in [1, 2, 3]: pertenencia por elemento.
clave in map(...): existencia de clave.
"prop" in obj: existencia de propiedad en object.
"na" in "banana": substring.
El lado derecho debe ser list, tuple, set,
map, object o string.
Is null like Python None? Does
none exist?
Conceptualmente, si: null es el valor de ausencia de Clot y es el equivalente
mas cercano al None de Python.
La forma oficial del lenguaje es null. none no es keyword, no es
alias y no debe usarse como literal nulo en ejemplos o codigo fuente.
Can LLVM AOT compile the new control-flow features natively?
No todas. En el estado actual, switch, for-each,
do-while, finally, defer y el operador
in no tienen lowering AOT nativo dedicado.
El modo compile puede seguir cubriendo esos casos via runtime bridge, pero no
debes asumir que se ejecutaran como IR LLVM puro sin soporte de runtime.
Why must super(...) be first in derived constructors?
Porque la instancia base debe quedar inicializada antes de ejecutar logica propia de la
clase
derivada. Esto garantiza estado consistente en herencia y evita usar miembros de base antes
de
tiempo. En Clot OOP MVP, el constructor derivado debe llamar super(...) como
primera
sentencia y solo una vez.
class Base:
constructor(x: int):
this.x = x;
endconstructor
endclass
class Child extends Base:
constructor(x: int):
super(x); // correcto: primera sentencia
this.y = x * 2;
endconstructor
endclass
Can I get enum member name instead of numeric value?
Si. Usa enum_name(EnumObj, EnumObj.MIEMBRO). Para el inverso, usa
enum_value(EnumObj, "MIEMBRO").
Issue Template
Title: [Runtime|Parser|LLVM] Short description
Version/Date: 2026-03-07 snapshot
Command: ./build/wsl-release/clot file.clot --mode ... --lang en
Input file:
<paste minimal reproducible clot code>
Expected behavior:
Actual behavior:
Stack/error output:
Environment: OS, compiler, LLVM availability
Severity Guide
| Severity |
Definition |
Example |
| Critical |
Crash o corrupcion de datos |
Segfault, resultado numerico incorrecto silencioso |
| High |
Feature principal inutilizable |
while no parsea, import roto |
| Medium |
Workaround posible |
Mensaje ambiguo, fallback inesperado |
| Low |
Impacto menor de UX/docs |
Error tipografico en diagnostico |
Workflow
- Crear rama por objetivo tecnico.
- Agregar o ajustar tests antes de merge.
- Ejecutar build + smoke tests.
- Actualizar documentacion afectada en esta pagina.
cmake --build --preset build-release -j4
bash tests/smoke.sh ./build/wsl-release/clot
bash tests/llvm_smoke.sh ./build/wsl-release/clot
Documentation Rules
- Todo builtin nuevo debe tener signature, retorno, validaciones y ejemplo.
- Todo tipo nuevo debe actualizar Type Summary y General Index.
- Todo cambio de semantica debe reflejarse en What is New y FAQ relevante.
- Los builtins del interprete deben implementarse en
src/interpreter/interpreter_builtins.cpp, no mezclados con ejecucion
general.
Recent Timeline
| Date |
Milestone |
Notes |
| 2026-03-07 |
Expanded control flow + const/in + finally/defer |
for, for-each, do-while,
switch, break, continue,
pass, const, in,
finally, defer, docs sync |
| 2026-03-06 |
Typed exception system + throw builtin |
throw(value), typed catch,
clot.core.exceptions module, docs/tests sync |
| 2026-03-03 |
Professional docs portal and full reference consolidation |
Section architecture, global search, indexes, glossary |
| 2026-03 |
Function/null semantics + enum enhancements |
Implicit null return, enum multiline, enum helpers |
| 2026-02 |
Analyzer mode + runtime bridge external + math expansion |
Mitigation of major architecture/perf concerns |
License
El proyecto se distribuye segun LICENSE.txt del repositorio.
Verifica terminos antes de redistribuir binarios o integrar codigo en proyectos cerrados.