domingo, 11 de enero de 2026

Claude Code: un nuevo enfoque de la programación por pares

Claude Code es una herramienta de inteligencia artificial creada por Anthropic que funciona directamente en la terminal. Sirve para acelerar el desarrollo de software al generar, analizar, editar y corregir código, además de gestionar flujos de trabajo como pruebas y Git sin salir del entorno local.

En pocas palabras,  un asistente de codificación agéntico que vive en tu terminal.

Sirve para:

  • Generar fragmentos de código a partir de ideas. 
  • Leer y analizar proyectos completos. 
  • Editar y corregir errores automáticamente. 
  • Ejecutar pruebas y generar pull requests
  • Manejar flujos de trabajo de Git y búsqueda semántica en tu base de código.

En pocas palabras, Claude Code convierte tu terminal en un entorno de desarrollo inteligente, ayudando a programadores a trabajar más rápido y con menos fricción.

Claude Code y otras herramientas similares

Claude Code se diferencia de ChatGPT, DeepSeek y Microsoft Copilot principalmente en su enfoque: está diseñado para vivir en la terminal y actuar como un par programador que entiende, edita y gestiona proyectos completos de código, mientras que los otros asistentes tienen un alcance más general o están integrados en aplicaciones específicas

Diferencias principales:

  • Claude Code vs ChatGPT: Claude Code está especializado en desarrollo dentro de la terminal, mientras que ChatGPT es más generalista y se usa para múltiples tareas (escribir, aprender, programar, etc.). 
  • Claude Code vs DeepSeek: DeepSeek busca ofrecer potencia similar a GPT-4 a menor costo, pero no está diseñado específicamente para integrarse en flujos de desarrollo como Claude Code. 
  • Claude Code vs Microsoft Copilot: Copilot se integra en aplicaciones de Microsoft y GitHub, mientras que Claude Code vive en la terminal y gestiona proyectos completos con búsqueda semántica y edición directa. 
  • Claude Code vs Claude (IA general): Claude general es un modelo conversacional seguro y con gran capacidad de contexto; Claude Code es su versión enfocada en programación y terminal.

Tabla comparativa de asistentes de programación

Herramienta Enfoque Entorno principal Integración con código/proyectos Git y flujos CI/CD Búsqueda semántica en repos Testing desde el asistente Contexto largo Ecosistema y extensiones Casos ideales
Claude Code (Anthropic) Asistente dev en terminal CLI / Terminal Analiza, edita y corrige proyectos completos Opera comandos Git y genera PRs Sí (en el repositorio local) Sí (ejecuta y guía pruebas) Alto (modelos Claude) Integración con herramientas dev; menos enfoque en Office Desarrollo ágil en terminal, refactoring guiado
ChatGPT (OpenAI) Asistente generalista Web / API / Extensiones Genera y explica código; no gestiona repos locales por sí mismo Limitado (requiere herramientas externas) Parcial (via plugins/extensiones) Orientado a guía, no a ejecución directa Alto (dependiendo del plan/modelo) Amplio ecosistema de plugins y terceros Ideación, documentación, aprendizaje y prototipado
DeepSeek IA de alto rendimiento y costo eficiente Web / API Genera/analiza código; integración depende del usuario Limitado (vía scripts/SDK del usuario) No nativo No nativo Variable según modelo SDKs y comunidad creciente Precio/rendimiento para tareas de código y análisis
Microsoft Copilot (incl. GitHub Copilot) Compleción y asistencia en IDE + productividad Microsoft VS Code / IDEs / Office / Windows Completa y sugiere código en tiempo real Fuerte con GitHub (PRs, repos, acciones) Parcial (dependiendo de extensiones) Limitado (más enfoque en IDE que en ejecución) Medio–alto (según variante) Integración profunda en ecosistema Microsoft Trabajo en IDE, repos GitHub, Office y flujos empresariales
Claude (conversacional general) IA conversacional segura y con gran contexto Web / API Genera y revisa código; no gestiona terminal directamente Limitado (requiere herramientas externas) Parcial (vía integraciones) No nativo Muy alto (modelos más recientes) Integraciones via API y herramientas de terceros Análisis de documentos extensos, diseño y revisión técnica

Como mencionamos en entregas pasadas el Vibe Coding o "codificación por sensaciones" ha cambiado como el desarrollador trabajará en el futuro. No sabemos a ciencia cierta si seremos simples observadores o incluso reemplazados.

Enlaces:

https://claude.com/product/claude-code
https://claude.ai
https://alquimistadecodigo.blogspot.com/2015/04/pair-programming.html
https://www.elladodelmal.com/2025/03/que-es-el-vibe-coding.html
https://www.enriquedans.com/2025/12/el-espejismo-del-vibe-coding-cuando-la-relajacion-progresiva-convierte-al-programador-en-espectador.html
https://www.enriquedans.com/2025/11/cuando-el-software-se-escribe-a-ojo-por-que-el-vibe-coding-seduce-y-por-que-conviene-desconfiar.html

sábado, 10 de enero de 2026

Moonbit en un vistazo

MoonBit es una cadena de herramientas de lenguaje de programación nativo de IA para computación en la nube y edge. Se compila a WebAssembly, JavaScript y C.

Es muy similar a lenguajes como Python y sobre todo a Go

Ambos lenguajes (MoonBit y Go) son similares en:

  • Típicos estáticos con inferencia de tipos.
  • Lenguajes compilados con compilación rápida.
  • Seguridad en memoria, aunque con mecanismos ligeramente diferentes.
  • Orientado a la computación moderna con excelentes herramientas.

Aunque ya vimos algo sobre este lenguaje, hoy veremos cómo instarlo y algunos ejemplos de uso.

Instalando MoonBit

Instalando en Linux:

$ curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash

Instalando en Windows:

$ Set-ExecutionPolicy RemoteSigned -Scope CurrentUser; irm https://cli.moonbitlang.com/install/powershell.ps1 | iex

Verificamos la instalación:

$ moon version

Podemos ver la ayuda:

$ moon help

Para quienes usan Visual Studio Code, se puede descargar un plugin del lenguaje:

https://marketplace.visualstudio.com/items?itemName=moonbit.moonbit-lang

Programando en MoonBit

Ejemplo 1. El clásico "Hola, mundo".

holamundo.mbt

fn main {
  println("Hola, mundo.")
}

Ejecución:

$ moon run holamundo.mbt

Salida:

Hola, mundo.

Ejemplo 2. Tipos de datos en MoonBit. Aquí veremos los tipos de datos. 

tipos.mbt

fn main{
  let int : Int = 42
  let uint : UInt = 42
  let int64 : Int64 = 42
  let double : Double = 42
  let float : Float = 42
  let bigint : BigInt = 42
  let cadena : String = "FERROCARRIL"
  let c : Char = 'A'
  let verdadero : Bool = true
  println("\t Tipos de datos en MoonBit.")
  println(int)
  println(uint)
  println(int64)
  println(double)
  println(float)
  println(bigint)
  println(cadena)
  println(c)
  println(verdadero)
}

Ejecución:

$ moon run tipos.mbt

Salida:

         Tipos de datos en MoonBit.
42
42
42
42
42
42
FERROCARRIL
A
true

Ejemplo 3. Programa que nos muestre ejemplo de sentencias condicionales.

condicional.mbt

fn main{
  println("\t Condicionales en MoonBit.")
  let mut bandera: Bool = 23 > 22
  
  if bandera{
    println("Fue verdadero.")
    bandera = false
  }

  if bandera{
    println("Esto no se vera en pantalla.")
  }else{
    println("Esto si se vera en pantalla.")
  }

  let resultado = if "A" == "A"{
    "Esto fue verdadero."
  }else{
    "Esto fue falso."
  }
  println(resultado)
  println(fibonacci(5))
}
// Aqui usamos algo similar a switch
fn fibonacci(n : Int) -> Int {
  match n {
    0 => 0
    1 | 2 => 1
    _ => fibonacci(n - 1) + fibonacci(n - 2)
  }
}

Ejecución:

$ moon run condicional.mbt

Salida:

         Condicionales en MoonBit.
Fue verdadero.
Esto si se vera en pantalla.
Esto fue verdadero.
5

Ejemplo 4. Sumar los primeros 100 números pares. Con esto veremos un ejemplo de sentencias iterativas.

iterativas.mbt

fn main{

println("\t Sumar los primeros 100 números pares en MoonBit.")
let suma = for i = 1, acc = 0; i <= 100; i = i + 1 {
  if i % 2 == 0 {
    continue i + 1, acc + i
  }
} else {
  acc
}

   println(suma)

}

Ejecución:

$ moon run iterativas.mbt

Salida:

         Sumar los primeros 100 números pares en MoonBit.
2550

Ejemplo 5. Programa que tenga funciones para suma, resta, multiplicación y división de números enteros.

funciones.mbt

fn main{
  println("\t Funciones en MoonBit.")
  let a: Int = 3
  let b: Int = 2
  println(suma(a, b))
  println(resta(a, b))
  println(producto(a, b))
  println(division(a, b))
}

fn suma(x: Int, y: Int)-> Int {
  x + y
}

fn resta(x: Int, y: Int)-> Int {
  x - y
}

fn producto(x: Int, y: Int)-> Int {
  x * y
}

fn division(x: Int, y: Int)-> Int {
  x / y
}

Ejecución:

$ moon run tipos.mbt

Salida:

         Funciones en MoonBit.
5
1
6
1

Ejemplo 6. Un programa que use estructuras.

estructuras.mbt

struct Persona {
  nombre : String
  apellidos: String
  edad : Int
}

struct Punto{
  x:Int
  y:Int
}

fn main{
  println("\t Estructuras en MoonBit.")
  let thomas = Persona::{ nombre: "Thomas", apellidos: "Muller", edad: 30 }
  let p: Punto = {x: 23, y:43}

  println(thomas.nombre)
  println(thomas.apellidos)
  println(thomas.edad)

  println(" --------------- ")
  println(p.x)
  println(p.y)
}

Ejecución:

$ moon run estructuras.mbt

Salida:

        Estructuras en MoonBit.
Thomas
Muller
30
 ---------------
23
43

Conclusiones:

Hemos instalado MoonBit en nuestro sistema.

Hemos creado algunos programas para conocer lo básico del lenguaje.

En próximas entregas continuaremos con este tema.

Enlaces:

https://www.moonbitlang.com/
https://codemonkeyjunior.blogspot.com/2025/11/moonbit-un-lenguaje-orientado-la-ia.html

jueves, 1 de enero de 2026

Un vistazo a JakartaEE

Los que vienen programando en Java algún tiempo sabrán que trabajar con este lenguaje tiene sus pros y contras. No todo ha sido fácil, pero tampoco algo imposible.

Crear aplicaciones web con Servlets y JSP con sus configuraciones tediosas le complicaban la vida a más de uno. Ni se diga con los odiosos EJB y el uso de servidores como JBoss, Glassfish, etc.

Después vino Spring Framework con su Spring Boot que facilitó la vida a los desarrolladores web. Pues está herramienta se encargaba de lo complicado y dejaba al programador enfocarse en una sola cosa: su código.

Jakarta EE es la evolución directa de Java EE, el Java empresarial que muchos sufrían en antaño. La documentación oficial nos dice:

  • Es conjunto de especificaciones que se utiliza para crear productos y frameworks Java para aplicaciones empresariales a gran escala. 
  • Impulsa sistemas como bancos, sitios de comercio electrónico y plataformas empresariales. 
  • Se basa en Java SE con API adicionales para desarrollo web, acceso a bases de datos, mensajería y seguridad.

Características principales:

  • Tecnologías web: Servlets, JSP, JSF.
  • Lógica de negocio: EJB (Enterprise JavaBeans).
  • Persistencia de datos: JPA Mensajería: JMS Seguridad y transacciones.

Jakarta EE se ejecuta en servidores de aplicaciones como WildFly, GlassFish y Payara, que gestionan la configuración, la escalabilidad y el ciclo de vida.

Jakarta EE Get Started

Para los que vienen de Spring Boot este sitio se les hará familiar:

https://start.jakarta.ee/

Pues es similar al sitio https://start.spring.io/, el cual nos ayuda a crear un proyecto listo para usar y que nos evita las odiosas y tediosas configuraciones.

La documentación oficial nos dice:

"Jakarta EE Get Started crea rápidamente una aplicación Jakarta EE lista para usar, eliminando las complicaciones habituales de configuración. En lugar de empezar con una carpeta vacía, obtienes un proyecto completo y funcional, listo para construir, como si empezaras con un set de LEGO preconstruido que puedes personalizar al instante. Incluye la configuración correcta de Maven, estructuras de directorios estándar y código de ejemplo que demuestra los conceptos clave de Jakarta EE".

En pocas palabras, Jakarta EE aprendió lo que no hizo Java EE.

Al entrar al sitio podemos ver un formulario similar al de Spring Boot Initializer:

Comencemos con un proyecto sencillo.

Descargamos el archivo ZIP y lo descomprimimos en algún directorio:

$ cd jakartaee-hello-world

Veamos el contenido del proyecto:

src\main\java\org\eclipse\jakarta\hello\Hello.java
src\main\java\org\eclipse\jakarta\hello\HelloApplication.java
src\main\java\org\eclipse\jakarta\hello\HelloWorldResource.java

Hello.java

package org.eclipse.jakarta.hello;

public class Hello {

    private String name;

    public Hello(String name) {
        this.name = name;
    }

    public String getHello(){
        return name;
    }
}

La cual es una clase o un bean.

HelloApplication.java

package org.eclipse.jakarta.hello;

import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.ApplicationPath;

@ApplicationPath("rest")
public class HelloApplication extends Application {
    
}

Similar a la aplicación tipo Spring Boot.

HelloWorldResource.java

package org.eclipse.jakarta.hello;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

@Path("hello")
public class HelloWorldResource {

    @GET
    @Produces({ MediaType.APPLICATION_JSON })
    public Hello hello(@QueryParam("name") String name) {
        if ((name == null) || name.trim().isEmpty()) {
            name = "world";
        }

        return new Hello(name);
    }
}

La cual es una clase similar a un Controller en Spring Boot.

En teoría, es una aplicación funcional. Comprobemos esto.

Compilamos el proyecto:

$ mvn clean install

Si todo va bien, nuestra aplicación estará compilada y se habrá creado el WAR en la carpeta generada llamada target.

Ahora será necesario descargar e instalar Glassfish:

https://glassfish.org/download

Una vez descargado y descomprimido en algún directorio en específico, debemos crear la variable de entorno para poder ejecutarlo:

C:\glassfish7\bin

Ahora iniciaremos el servidor Glassfish:

$ asadmin start-domain

Abriremos el navegador en la ruta: http://localhost:4848

Entraremos al administrador de Glassfish. Vamos a Application/Deploy. Seleccionamos nuestro WAR y damos ok. Ya podemos ejecutar la aplicación.

Abrimos el navegador en la ruta: http://localhost:8080/jakartaee-hello-world/rest/hello?name=Thomas_Muller

Salida:

¡Hemos creado nuestra primera aplicación con Jakarta EE!

Detenemos el servidor Glassfish:

$ asadmin stop-domain

Actualización:

Si no quieres instalar Glassfish, puedes ejecutar este comando:

$ mvnw clean package wildfly:run

Deberás descargar la última versión de Wildfly:

https://www.wildfly.org/downloads/

Descomprimir el ZIP y colocarlo en algún directorio (C:\wildfly).

Además de editar el pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.eclipse</groupId>
    <artifactId>jakartaee-hello-world</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>jakartaee-hello-world</name>
    <description>
        Simple Jakarta EE 11 application running on WildFly.
    </description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
        <maven.compiler.release>21</maven.compiler.release>
        <jakartaee-api.version>11.0.0-RC1</jakartaee-api.version>
        <compiler-plugin.version>3.13.0</compiler-plugin.version>
        <war-plugin.version>3.4.0</war-plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-core-api</artifactId>
            <version>${jakartaee-api.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>jakartaee-hello-world</finalName>
        <plugins>
            
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>4.2.0.Final</version>
                <configuration>
                    <jbossHome>C:\wildfly</jbossHome>
                    <startupTimeout>180</startupTimeout>
                </configuration>
            </plugin>

            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
            </plugin>

           
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${war-plugin.version}</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project> 

Ya podrás desplegarlo sin la necesidad de iniciar Glassfish.

Feliz año 2026

Este es el post número 400 del blog.😉

Enlaces:

https://jakarta.ee/
https://www.linkedin.com/pulse/java-explained-servlets-jsp-jakarta-ee-rohit-bhosale-r2gzf/?trackingId=XgJjdE8PQombg7SZoMmx9Q%3D%3D
https://jakarta.ee/learn/starter-guides/a-comprehensive-beginners-guide-to-the-get-started/

sábado, 27 de diciembre de 2025

Ballerina: una comparativa con Rust

Como mencionamos en la entrega anterior, Ballerina es un lenguaje de programación en crecimiento. No posee una comunidad tan grande como otros lenguajes (Java, C#, C/C++, Python, etc.), pero así empiezan todos. Ballerina junto otros lenguajes como Go y Rust han cobrado cierto interés en el mundo de la programación, servicios Cloud, servicios REST y hasta la I.A.

En esta ocasión haremos una comparativa con Rust, un lenguaje de programación que tiene inspiración en lenguajes como C y C++, tomando lo mejor de ellos y descartando lo que no es necesario y Ballerina, un lenguaje que ha cobrado importancia en el desarrollo en la nube. Ambos lenguajes han aprendido de los mejores e incluso han ido superándolos incluso en velocidad y rendimiento.

Ballerina y Rust son lenguajes muy distintos: Ballerina está orientado a integración y microservicios, mientras que Rust se centra en sistemas de alto rendimiento y seguridad de memoria.

Veamos una tabla comparativa:

Comparativa: Ballerina vs Rust
Aspecto Ballerina Rust
Paradigmas Multiparadigma con foco en integración, concurrencia y servicios distribuidos; código con visualización de flujos y llamadas. Multiparadigma (imperativo y funcional) orientado a sistemas, control de bajo nivel y seguridad de memoria.
Casos de uso Integración de APIs, microservicios, orquestación de endpoints, aplicaciones cloud-native y seguridad en comunicaciones. Sistemas operativos, motores de juegos, programación embebida, CLI y servicios de alto rendimiento.
Compilación y ejecución Compila con bal build; ejecuta con bal run archivo.bal. Soporte integrado para Docker/Kubernetes. Compila con rustc archivo.rs; ejecuta con ./archivo. En proyectos se usa Cargo (cargo build, cargo run).
Tipos de variables Tipado estático: int, float, boolean, string; estructurados: record, map, array, table. Tipado estático con inferencia: primitivos (i32, f64, bool, char) y avanzados (struct, enum, tuple).
Estructuras de control if, while, foreach, match; concurrencia con workers y fork/join. if, loop, while, for, match con patrones; concurrencia segura con async/await y ownership.
Estructuras de datos record (tipo estructurado), map, array, table. struct, enum, tuple, array, Vec<T>, HashMap<K,V>.
Concurrencia Modelo de trabajadores, transacciones y flujos de integración; primitivas para servicios distribuidos. Seguridad de datos en concurrencia mediante ownership, borrowing y tipos como Arc/Mutex.
Ecosistema Enfocado en integración (HTTP, gRPC, GraphQL, Kafka) con librerías estándar orientadas a servicios. Amplio ecosistema de crates para sistemas, redes, WebAssembly, embebidos y desarrollo multiplataforma.
Curva de aprendizaje Suave para integraciones y microservicios; diseño opinado para flujos de red. Pronunciada por el ownership y el borrow checker; recompensa con rendimiento y seguridad.

Puntos clave entre Ballerina y Rust

Ambos lenguajes tienen similitudes y diferencias, aquí los puntos claves:

  • Enfoque distinto: Ballerina es un lenguaje de integración; Rust es un lenguaje de sistemas. 
  • Compilación: Rust ofrece control de bajo nivel y optimización; Ballerina simplifica despliegues en entornos distribuidos. 
  • Datos y control: Rust tiene estructuras más ricas y flexibles; Ballerina prioriza simplicidad y seguridad en datos de red. 
  • Concurrencia: Ambos soportan concurrencia, pero Rust lo hace con un modelo de ownership y Ballerina con workers y diagramas visuales.

Ejemplo 1. Crear un sencillo "Hola, mundo" en Ballerina y Rust. Esto nos servirá para ver cómo se compila y ejecuta un programa en cada lenguaje.

Empecemos con Ballerina. Compilaremos y ejecutaremos un archivo llamado holamundo.bal:

import ballerina/io;

public function main(string... args) {
    io:println("\t Hola, mundo en Ballerina");
}

Compilamos y ejecutamos:

$ bal run holamundo.bal

El código se compilará y se ejecutará en la terminal, la salida será:

Compiling source
        holamundo.bal

Running executable

         Hola, mundo en Ballerina

Ahora con Rust, compilaremos y ejecutaremos el archivo holamundo.rs:

fn main() {
    println!("\t Hola mundo en Rust");
}

Compilamos:

$ rustc holamundo.rs

Se creará un ejecutable:

$ holamundo.exe

Salida:

         Hola mundo en Rust

¿Qué podemos notar?

  • Ambos lenguajes son compilados. 
  • Ballerina es más similar Java, es dependiente de la JVM y genera bytecodes
  • Rust es más similar a C/C++, genera ejecutables nativos (*exe). 
  • La extensión de un programa Ballerina es *bal.
  • La extensión de un programa Rust es *rs.

Tipos de datos en Ballerina y Rust

Como mencioanmos, ambos lenguajes son compilados. También comparten la característica de ser de tipado estático. Eso quiere decir que debes especificar el tipo de datos a usar. No como lenguajes como Python o Ruby donde "una variable es una variable".

Tipos de datos en Ballerina vs Rust
Categoría Ballerina Rust
Primitivos numéricos int, float, decimal i8, i16, i32, i64, u8, u16, u32, u64, f32, f64
Booleanos boolean bool
Texto y caracteres string char, String (tipo de colección)
Compuestos record, map, array, table struct, enum, tuple, array, Vec<T>, HashMap<K,V>
Especiales nil (valor nulo), error, any Option<T>, Result<T,E>, unit (())
Concurrencia Workers y canales integrados para paso de mensajes Tipos seguros para concurrencia: Arc, Mutex, RwLock

Ejemplo 2. Crear un programa en ambos lenguajes con el objetivo de ver los tipos de datos en cada lenguaje.

En Ballerina:

tipos.bal

import ballerina/io;

type Persona record {|
    string nombre;
    int edad;
|};

enum Estado {
    ACTIVO,
    INACTIVO
}

public function main() {
    int edad = 30;
    float altura = 1.75;
    boolean activo = true;
    string inicial = "C"; // no existe 'char'
    string nombre = "Thomas Muller.";

    int[] numeros = [1, 2, 3, 4];
    [int, float, string] tupla = [25, 1.80, "Ana"];

    Persona p = { nombre: "Luis", edad: 40 };
    Estado estado = ACTIVO;

    map<string> capitales = { "MX": "Ciudad de México", "US": "Washington" };

    int|error resultado = 10; // Result
    float? opcion = 3.14;     // Option

    
    int contador = 0;
    fork {
        worker w1 {
            int local = contador;
            local += 1;
            io:println("Worker 1 contador: " , local.toString());
        }
        worker w2 {
            int local = contador;
            local += 1;
            io:println("Worker 2 contador: " , local.toString());
        }
    }

	io:println("Nombre: " + nombre + ", Edad: " + edad.toString());
    string capitalMX = capitales["MX"] ?: "Desconocido";
    io:println("Capital de MX: " + capitalMX);
    io:println("Persona: " + p.toString());
    io:println("Contador final (simulado): " + contador.toString());
}

Compilamos y ejecutamos:

$ bal run tipos.bal

Salida:

Nombre: Thomas Muller., Edad: 30
Capital de MX: Ciudad de México
Persona: {"nombre":"Luis","edad":40}
Contador final (simulado): 0
Worker 2 contador: 1
Worker 1 contador: 1

En Rust:

tipos.rs

fn main() {
    
    let edad: i32 = 30;
    let altura: f64 = 1.75;
    let activo: bool = true;
    let inicial: char = 'C';
    let nombre: String = String::from("Thomas Muller.");

    
    let numeros: [i32; 4] = [1, 2, 3, 4];
    let tupla: (i32, f64, &str) = (25, 1.80, "Ana");

    struct Persona {
        nombre: String,
        edad: i32,
    }
    let p = Persona { nombre: String::from("Luis"), edad: 40 };

    enum Estado {
        Activo,
        Inactivo,
    }
    let estado = Estado::Activo;

    use std::collections::HashMap;
    let mut capitales = HashMap::new();
    capitales.insert("MX", "Ciudad de México");
    capitales.insert("US", "Washington");

    let resultado: Result<i32, &str> = Ok(10);
    let opcion: Option<f64> = Some(3.14);

   
    use std::sync::{Arc, Mutex};
    use std::thread;

    let contador = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..2 {
        let contador = Arc::clone(&contador);
        let handle = thread::spawn(move || {
            let mut num = contador.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for h in handles {
        h.join().unwrap();
    }

    println!("Nombre: {}, Edad: {}", nombre, edad);
    println!("Capital de MX: {}", capitales["MX"]);
    println!("Persona: {} ({})", p.nombre, p.edad);
    println!("Contador final: {}", *contador.lock().unwrap());
}

Compilamos:

$ rustc tipos.rs

Se creará un ejecutable:

$ tipos.exe

Salida:

Nombre: Thomas Muller., Edad: 30
Capital de MX: Ciudad de México
Persona: Luis (40)
Contador final: 2

Podríamos continuar con las comparaciones con estructuras de datos, acceso a archivos, acceso a base de datos y hasta servicios REST. Sin embargo, lo haremos en otra ocasión.

Conclusiones

Es importante hacer notar que:

  • Rust: curva de aprendizaje más pronunciada por su sistema de ownership y borrow checker
  • Ballerina: menos comunidad y ecosistema que Rust; puede ser limitante fuera del ámbito de integración.

Ambos lenguajes tienen un propósito, resuelven problemas distintos. No son competidores.

Enlaces:

https://rust-lang.org/
https://ballerina.io/
https://www.infoq.com/articles/ballerina-integration-tutorial-part-2/
https://www.infoq.com/articles/ballerina-microservices-language-part-1/



jueves, 25 de diciembre de 2025

Ballerina: un lenguaje en crecimiento

En una entrega anterior vimos un breve vistazo a Ballerina, un lenguaje de programación dependiente de la JVM. Diseñado por WSO2 para programadores de aplicaciones de la era de la nube.

Lanzado en 2017, con versión estable en 2022, Ballerina aún es joven y no tiene la misma comunidad que Java o Go.

Empresas como WSO2, MOSIP y RAAPID.AI usan Ballerina principalmente para integración de sistemas, microservicios y manejo de datos sensibles en entornos distribuidos. Su enfoque está en la orquestación de APIs, seguridad en comunicaciones y procesamiento de datos en la nube.

Empresas que usan Ballerina y casos de uso
Empresa / Proyecto Uso principal de Ballerina Beneficio clave
WSO2 Integración de sistemas empresariales y orquestación de APIs Resuelve el “integration gap” entre microservicios y productos de integración
MOSIP Integración dirigida por eventos con WebSubHub Manejo eficiente de eventos y flujos de datos en sistemas de identidad nacional
RAAPID.AI Integración de datos clínicos Interoperabilidad y unificación de datos médicos dispersos
Localazy Hub Aplicaciones en red y microservicios Seguridad integrada (TLS/SSL) y soporte nativo para Docker/Kubernetes

¿Por qué Ballerina?

  • Diseñado para integración: A diferencia de lenguajes genéricos, Ballerina entiende protocolos, formatos y conectores desde el núcleo. 
  • Microservicios y APIs: Ideal para arquitecturas distribuidas, con soporte nativo para REST, gRPC y mensajería. 
  • Seguridad embebida: TLS/SSL y políticas de seguridad por diseño. 
  • Cloud-native: Integración directa con Docker y Kubernetes, lo que lo hace atractivo para DevOps y despliegues modernos.

Consideraciones y retos

  • Adopción limitada: Aunque potente, Ballerina aún es joven (lanzado en 2017, con versión estable en 2022) y no tiene la misma comunidad que Java o Go. 
  • Nicho de integración: Su mayor valor está en proyectos donde la orquestación de servicios y APIs es crítica; fuera de ese ámbito, otros lenguajes pueden ser más prácticos. 
  • Curva de aprendizaje: Su enfoque visual (diagramas de secuencia y flujos) puede ser novedoso pero requiere adaptación.

Creando un proyecto sencillo con Ballerina

Para esto requerimos instalar Ballerina:

https://ballerina.io/downloads/

1. Una vez instalado comprobamos la versión instalada:

$ bal version

2. Creamos el proyecto:

$ bal new hello_world
$ cd hello_world

3. Editamos el archivo main.bal:

import ballerina/io;

public function main() {
    io:println("Hola, mundo");
}

4. Ejecutamos el código:

$ bal run

Salida:

Hola, mundo

Revisemos la estructura del proyecto:

  • Ballerina.toml: Metadatos del paquete (nombre, versión). 
  •  hello_world/main.bal: Punto de entrada (main) del programa. 
  •  target/ (se crea al compilar): Artefactos y compilados. 
  •  Module.md: Documentación del módulo.

También tenemos la opción de crear un ejecutable (como los JARS):

$ bal build

Y ejecutarlo:

$ bal run target/bin/hello_world.jar

Y si preguntan ¿Por qué se crea un JAR? Es porque Ballerina es un lenguaje dependiente de la JVM.

Ahora veamos algo más interesante: crear un servicio HTTP.

Editemos el archivo main.bal:

import ballerina/http;

service / on new http:Listener(8080) {
    resource function get hello() returns string {
        return "Hola, mundo";
    }
}

Ejecutemos:

$ bal run

Abrimos el navegador en la ruta: http://localhost:8080/hello

Salida:

Hola, mundo

Como se puede observar, Ballerina tiene mucho que ofrecer para los desarrolladores. Desde los que vienen de C, C++, PHP, Python, Java, C#, Go y Rust.

Enlaces:

https://alquimistadecodigo.blogspot.com/2022/09/ballerina-en-un-vistazo.html


Claude Code: un nuevo enfoque de la programación por pares

Claude Code es una herramienta de inteligencia artificial creada por Anthropic que funciona directamente en la terminal. Sirve para acele...

Etiquetas

Archivo del blog