Back to flin
flin

Cinco principios de diseño que moldean cada línea de FLIN

Los cinco principios de diseño detrás de FLIN: simple, cero configuración, reactivo, nativo de intención y nativo de memoria.

Thales & Claude | March 30, 2026 11 min flin
EN/ FR/ ES
flinrust

Todo lenguaje de programación tiene opiniones. Python cree que la legibilidad cuenta. Rust cree que la seguridad es innegociable. Go cree que la simplicidad es una característica, no una limitación.

FLIN tiene cinco opiniones, y no son directrices. Son leyes. Cada decisión de sintaxis, cada palabra clave, cada elección arquitectónica se evalúa contra estos cinco principios. Si una funcionalidad viola cualquiera de ellos, no se lanza.

Estos principios no se descubrieron a través de la iteración. Se establecieron el primer día, antes de que se escribiera la primera línea de Rust para el compilador, antes de que se definiera el primer token en el analizador léxico. Son la constitución del lenguaje, y este artículo explica cada uno en detalle -- qué significa, por qué importa y cómo se manifiesta en el código.

Principio 1: SIMPLE

Si un niño de doce años que sabe HTML no puede entender tu código FLIN en treinta segundos, el código es demasiado complejo.

Esta es la Regla de Oro. Está impresa en la primera página de la especificación del lenguaje. Gobierna cada decisión de sintaxis que tomamos.

La simplicidad en FLIN no se trata de ser "fácil" o "amigable para principiantes" -- esos son efectos secundarios. Se trata de la sobrecarga cognitiva. Cada pieza de sintaxis que un desarrollador debe aprender, recordar y reconocer al leer código es un impuesto sobre su capacidad mental. FLIN minimiza ese impuesto despiadadamente.

Considera cómo otros lenguajes manejan un contador reactivo:

jsx// React: 10 lines, requires understanding imports, hooks, JSX, arrow functions
import React, { useState } from 'react';

export default function Counter() {
    const [count, setCount] = useState(0);
    return (
        <button onClick={() => setCount(c => c + 1)}>
            {count}
        </button>
    );
}
svelte<!-- Svelte 5: 5 lines, requires understanding runes, script blocks -->
<script>
    let count = $state(0);
</script>

<button onclick={() => count++}>{count}</button>
flin// FLIN: 3 lines, requires understanding variables and HTML
count = 0

<button click={count++}>{count}</button>

La versión de FLIN requiere exactamente tres piezas de conocimiento: cómo funcionan las variables, cómo funcionan los elementos HTML y cómo las llaves insertan expresiones. Un niño de doce años que haya escrito una página HTML puede leer esto y entenderlo.

El principio de simplicidad tiene consecuencias concretas para el diseño del lenguaje:

Sin importaciones. En FLIN, todo está disponible. No hay import React from 'react', no hay from fastapi import FastAPI, no hay use std::collections::HashMap. El archivo es el componente. Los componentes en otros archivos se referencian por su nombre de archivo. El compilador resuelve todo.

Sin export. El archivo es el componente. Lo que el archivo define es lo que el componente expone. No hay export default, no hay module.exports, no hay modificador pub.

Sin funciones envolventes. En React, cada componente es una función. En Vue, cada componente es un objeto con un método setup(). En FLIN, el archivo mismo es el componente. No hay sintaxis de envoltorio.

flin// This entire file IS a component called "Greeting"
// Filename: Greeting.flin

name = props.name || "World"

<h1>Hello, {name}!</h1>

Compara con el equivalente en React:

jsx// React: function wrapper, return statement, JSX
export default function Greeting({ name = "World" }) {
    return <h1>Hello, {name}!</h1>;
}

La versión FLIN tiene menos sintaxis, pero no es menos potente. Logra el mismo resultado eliminando la ceremonia que existe para satisfacer la arquitectura del framework, no para expresar la intención del desarrollador.

La prueba de simplicidad se aplica en el momento de la revisión de código. Cuando diseñamos una nueva funcionalidad para FLIN, escribimos tres programas de ejemplo usándola. Luego mostramos esos programas a alguien no familiarizado con FLIN y preguntamos: "¿Puedes decirme qué hace esto?" Si no pueden responder en treinta segundos, la sintaxis está mal. No la persona -- la sintaxis.

Principio 2: CERO CONFIGURACIÓN

Un archivo .flin es todo lo que necesitas.

Este principio elimina la explosión de archivos de configuración que afecta al desarrollo web moderno. En un proyecto típico de Next.js, tienes: package.json, tsconfig.json, next.config.js, tailwind.config.js, postcss.config.js, .eslintrc.js, .prettierrc, y más. Cada archivo existe porque una herramienta necesita que le digan cómo comportarse.

FLIN no necesita configuración porque FLIN es la única herramienta. No hay empaquetador que configurar, no hay compilador TypeScript que configurar, no hay linter que personalizar, no hay gestor de paquetes que inicializar.

El proyecto mínimo viable de FLIN es un archivo:

my-app/
  app.flin

Eso es todo. Ejecuta flin dev, y tienes un servidor de desarrollo con recarga en caliente, verificación de tipos y acceso a base de datos. Ejecuta flin build, y tienes un binario de producción.

Un proyecto más grande usa más archivos, pero cero archivos de configuración:

my-app/
  index.flin              # Home page
  about.flin              # About page
  products/
    index.flin            # Product list
    [id].flin             # Product detail
  api/
    users.flin            # User API
    users/[id].flin       # User detail API
  components/
    Header.flin
    Footer.flin
    ProductCard.flin
  styles.css              # Optional global styles

Cada archivo es un archivo fuente .flin o una hoja de estilos .css. No hay flin.config.js. No hay flin.toml. El comportamiento del lenguaje está definido por la especificación del lenguaje, no por configuración por proyecto.

El runtime de FLIN gestiona:

Funcionalidad              Cómo funciona
-------------------------  ----------------------------------
Recarga en caliente        Automática (vigila archivos .flin)
Verificación de tipos      Integrada en el compilador
Empaquetado                Automático (salida única)
Base de datos              Embebida (FlinDB, cero configuración)
Variables de entorno       Convención de nombres
Enrutamiento               Basado en archivos (estructura de directorios)
Formateo                   Integrado (un estilo, aplicado)

Siete funcionalidades que, en el ecosistema JavaScript, requieren siete herramientas separadas con siete archivos de configuración separados. En FLIN, requieren cero.

Principio 3: REACTIVO

Todas las variables son reactivas por defecto.

En React, debes optar por la reactividad llamando a useState. En Vue 3, debes envolver valores en ref() o reactive(). En Svelte 5, debes usar $state(). En Angular, debes usar signals u observables. Cada framework tiene su propia primitiva de reactividad, su propia API, su propio modelo mental.

La posición de FLIN es que la reactividad es demasiado fundamental para ser opcional. Toda variable en FLIN es reactiva. Cuando su valor cambia, toda expresión de vista que depende de ella se actualiza automáticamente.

flinfirstName = "Juste"
lastName = "GNIMAVO"
theme = "light"

// All three spans update independently when their dependency changes
<div class={theme}>
    <span>{firstName}</span>
    <span>{lastName}</span>
    <span>{firstName + " " + lastName}</span>
</div>

El compilador realiza análisis de dependencias en tiempo de compilación. Sabe que el primer <span> depende de firstName, el segundo de lastName y el tercero de ambos. Cuando firstName cambia, solo el primer y tercer span se actualizan. Cuando lastName cambia, solo el segundo y tercero. Esto es reactividad de grano fino -- el mismo enfoque usado por Solid.js y Svelte 5 -- pero sin ninguna API de reactividad explícita.

¿Por qué reactivo por defecto en lugar de opt-in? Porque la reactividad opt-in introduce una categoría de errores que no deberían existir. En React, el error más común es olvidarse de usar useState -- escribir let count = 0 en lugar de const [count, setCount] = useState(0) y preguntarse por qué la UI no se actualiza. En FLIN, este error no puede existir porque toda variable es reactiva. No hay variable no reactiva que puedas usar accidentalmente.

Principio 4: NATIVO DE INTENCIÓN

Expresa lo que quieres, no cómo hacerlo.

Este es el más visionario de los cinco principios de FLIN. Reconoce que en la era de la IA, el límite entre lo que un programador especifica y lo que un compilador infiere puede extenderse mucho más allá de lo que los lenguajes tradicionales permiten.

El diseño nativo de intención se manifiesta en dos palabras clave: ask y search.

La palabra clave ask traduce lenguaje natural a consultas de base de datos:

flin// Traditional approach: write the query yourself
recent_buyers = User
    .where(active == true)
    .where(created > last_week)
    .where(id in Purchase.where(amount > 5000).map(p => p.user_id))
    .order(created, "desc")
    .limit(20)

// Intent-native approach: describe what you want
recent_buyers = ask "active users who signed up last week and made a purchase over 5000"

Ambas producen el mismo resultado. La versión ask delega la construcción de la consulta a un modelo de IA, que traduce la descripción en lenguaje natural a las operaciones de entidad apropiadas.

La palabra clave search realiza búsqueda semántica contra campos marcados con el modificador semantic:

flinentity Article {
    title: text
    content: semantic text
    tags: [text]
    published: time = now
}

// Traditional keyword search: exact matches only
results = Article.where(title.contains("machine learning"))

// Semantic search: understands meaning, not just keywords
results = search "articles about AI trends in African agriculture"
          in Article
          by content
          limit 10

¿Por qué nativo de intención es un principio de diseño y no solo una funcionalidad? Porque cambia cómo los desarrolladores piensan sobre la programación. La programación tradicional es imperativa: le dices al ordenador cada paso. FLIN permite intención declarativa: le dices al ordenador el resultado que quieres, y él descifra los pasos.

Principio 5: NATIVO DE MEMORIA

Todo se persiste y tiene historial.

Este es el principio que da a FLIN su nombre. "E flin nu" -- recuerda las cosas.

En todo lenguaje de programación tradicional, la persistencia es una ocurrencia tardía. Construyes tu lógica de aplicación, luego descubres cómo guardar datos. Eliges una base de datos, instalas un driver, configuras una conexión, escribes un esquema, ejecutas migraciones, y entonces -- finalmente -- tu aplicación puede recordar cosas entre reinicios.

En FLIN, la persistencia es el comportamiento predeterminado. La palabra clave entity crea tanto un tipo como una tabla de base de datos. La palabra clave save escribe en la base de datos. El operador @ consulta el historial. Todo funciona de fábrica, sin configuración.

flinentity Metric {
    name: text
    value: number
    recorded: time = now
}

// Save today's metric
save Metric { name: "revenue", value: 42500 }

// Tomorrow, compare with yesterday
revenue = Metric.where(name == "revenue").first
yesterdayRevenue = revenue @ yesterday

change = ((revenue.value - yesterdayRevenue.value) / yesterdayRevenue.value) * 100

<div class="dashboard">
    <h2>Revenue</h2>
    <span class="current">{revenue.value}</span>
    <span class={if change > 0 then "up" else "down"}>
        {change.to_fixed(1)}%
    </span>

    <h3>History</h3>
    {for version in revenue.history.last(7)}
        <div>
            <span>{version.recorded.format("MMM D")}</span>
            <span>{version.value}</span>
        </div>
    {/for}
</div>

Cómo interactúan los cinco principios

Los cinco principios no son independientes. Se refuerzan mutuamente de formas que crean propiedades de diseño emergentes.

Simple + Cero configuración significa que toda la experiencia de "comenzar" es: crear un archivo, escribir código, ejecutar flin dev. No hay fase de configuración, no hay fase de "instala estas doce dependencias."

Reactivo + Nativo de memoria significa que cuando los datos persistentes cambian, la UI se actualiza automáticamente. Guarda una nueva entidad, y cualquier vista que consulte ese tipo de entidad se re-renderiza.

Nativo de intención + Nativo de memoria significa que las consultas potenciadas por IA operan sobre datos ricos en historial. Puedes ask "users whose spending decreased compared to last month" -- una consulta que requiere comparación temporal, lo cual solo es posible porque FLIN recuerda cada versión de cada entidad.

Juntos, los cinco principios crean un lenguaje donde el modelo mental del desarrollador es radicalmente más simple que en cualquier framework existente:

Modelo mental tradicional                  Modelo mental de FLIN
----------------------------------------   -------------------------
Aprender React + hooks + JSX               Aprender la sintaxis de FLIN
Configurar TypeScript                      (tipos integrados)
Elegir gestión de estado                   (todas las variables reactivas)
Configurar BD + ORM + migraciones          entity + save
Instalar motor de búsqueda                 palabra clave search
Configurar empaquetador + linter           (integrado, cero config)
Escribir rutas API con Express             palabra clave route
Desplegar con Docker                       flin build (binario único)

Ocho decisiones en el stack tradicional. Cero decisiones en FLIN.

Los principios como filtro

La función más importante de los cinco principios es como filtro para nuevas funcionalidades. Cuando alguien propone añadir algo a FLIN, lo sometemos a cinco preguntas:

  1. ¿Simple? ¿Puede un niño de doce años entender la sintaxis en treinta segundos?
  2. ¿Cero configuración? ¿Funciona sin ninguna configuración?
  3. ¿Reactivo? ¿Se integra con el sistema de reactividad automáticamente?
  4. ¿Nativo de intención? ¿Se puede expresar como intención en lugar de instrucciones?
  5. ¿Nativo de memoria? ¿Respeta la persistencia y el historial?

Si la respuesta a cualquier pregunta es "no," la funcionalidad necesita rediseño. Si la respuesta a todas las cinco es "sí," la funcionalidad pertenece a FLIN.

Este filtro ha rechazado muchas funcionalidades que otros lenguajes consideran esenciales. ¿Genéricos? Fallan la prueba de simplicidad. ¿Archivos de configuración? Violan cero configuración. ¿Gestión manual de estado? Contradice reactivo por defecto. ¿Consultas SQL crudas? Puentean nativo de intención. ¿Persistencia opt-in? Socava nativo de memoria.

Estos rechazos no son compromisos. Son los principios haciendo su trabajo.


Siguiente en la serie: The Golden Rule: One .flin File Is All You Need -- Sin package.json. Sin tsconfig. Sin webpack.config. Sin postcss.config. Un archivo.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles