viernes, 22 de mayo de 2026

Lenguajes que han muerto y que no estabas enterado: el caso de Ceylon

Ceylon fue un lenguaje de programación que prometía algo que otros han intentado sin éxito: ser el verdadero sucesor de Java.

Tampoco lo logró.

Fue creado por Gavin King, el mismo creador de Hibernate, y "lanzado" el año 2011.

Digo lanzado, porque las versiones "lanzadas" nunca llegaban a ser estables. Pues cada versión lanzada (valga la redundancia) afectaban al lenguaje y que confundían al pobre ingenuo que se acercaba al lenguaje con el objetivo de aprendera a usarlo.

Lo que aprendías en una versión lo debías desaprender en la nueva... y así sucesivamente.

Actualmente el lenguaje se encuentra archivado por la Fundación Eclipse: https://projects.eclipse.org/projects/technology.ceylon

Ceylon posee (¿debería hablar en presente?) una sintaxis similar a la de Java y C#. Quienes venían de esos lenguajes podían adentrase al lenguaje sin tanto problema.

Características principales:

  • Orientado a objetos. 
  • Soporte a la meta programación. 
  • Imperativo. 
  • De tipado estático. 
  • Soporte la construcción modular. 
  • Multiplataforma.
  • Además de tener su propio IDE (plugin para Eclipse).

Un vistazo a Ceylon

El clásico "Hola, mundo" en Ceylon.

holamundo.ceylon

shared void run(){
    print("Hola, mundo en Ceylon");
}

No mencionaremos cómo compilarlo y ejecutarlo ya que, como mencionamos, cada versión del lenguaje cambiaba todo. Desde cómo comentar código hasta como construir el ejecutable.

Entrevista sobre Ceylon a Gavin King

El tema central de la entrevista fue sobre el nacimiento y propósito del lenguaje Ceylon.

Gavin King comentó que, tras años trabajando con Java, detectó limitaciones en su sistema de módulos y en la coherencia del lenguaje. Ceylon surge para ofrecer una sintaxis más moderna y un modelo de tipos más seguro.

Observemos esta tabla comparativa entre Ceylon y Java.

Comparativa Ceylon y Java

Aspecto Java Ceylon
Origen y creador Desarrollado por Sun Microsystems (1995), liderado por James Gosling. Creado por Gavin King en Red Hat (2011).
Objetivo principal Lenguaje de propósito general para aplicaciones empresariales, móviles y web. Modernizar el ecosistema Java con un lenguaje más coherente, modular y expresivo.
Paradigma Orientado a objetos con soporte funcional desde Java 8. Mixto: orientado a objetos y funcional, con fuerte énfasis en modularidad y claridad semántica.
Tipado Estático y fuerte, pero con inferencia limitada. Estático y fuerte, con inferencia de tipos avanzada y tipos unión/intersección.
Sistema de módulos Introducido en Java 9 (Jigsaw), pero complejo y poco intuitivo. Sistema de módulos nativo desde el inicio, simple y coherente.
Interoperabilidad Corre sobre la JVM y puede interactuar con otros lenguajes del ecosistema. Compila para JVM y JavaScript, permitiendo ejecución en servidor y navegador.
Sintaxis Verbosa y orientada a clases. Más concisa, con sintaxis moderna y expresiva.
Herramientas Ecosistema maduro (IDE, frameworks, librerías). IDE propio con compilador, gestor de módulos y documentación integrada.
Enfoque de diseño Prioriza compatibilidad y estabilidad. Prioriza legibilidad, coherencia y seguridad de tipos.
Casos de uso Aplicaciones empresariales, Android, sistemas financieros. Aplicaciones modulares, APIs, servicios distribuidos y código multiplataforma.

Ceylon representó su intento de modernizar el paradigma Java, ofreciendo una alternativa más elegante y coherente para proyectos grandes y distribuidos. Fue una lástima que no lo haya logrado.

Enlaces:

https://en.wikipedia.org/wiki/Ceylon_(programming_language)
https://swizec.com/blog/cool-thing-thursday-ceylon/
https://codemonkeyjunior.blogspot.com/2012/04/ceylon-funcionando-correctamente.html
https://projects.eclipse.org/projects/technology.ceylon
https://web.mit.edu/ceylon_v1.3.3/ceylon-1.3.3/doc/en/spec/html_single/#:~:text=Ceylon%20is%20a%20general%2Dpurpose,oriented%2C%20and%20higher%2Dorder.


lunes, 18 de mayo de 2026

Comparativa entre MoonBit y Python

MoonBit es un lenguaje de programación relativamente nuevo; un lenguaje orientado a la I.A. Ideal para la computación en la nube y en el borde, que abarca WebAssembly, WebAssembly-GC, JavaScript y backends nativos.

Python es un lenguaje surgido en los 90's; un lenguaje multiparadigma. Cuya filosofía sugiere lo ágil y hace hincapié en la legibilidad del código.

Miremos la siguiente tabla comparativa:

Comparativa MoonBit y Python

Característica Python MoonBit
Creador Guido van Rossum Zhang Hongbo
Paradigma Multiparadigma Programación asíncrona basado en corrutinas, similar a Kotlin
Tipado Dinámico Estático
Extensión .py .mbt
Tipo ejecución Interpretado Compilado
Ideal para REST API, web, etc. Orientado a aplicaciones I.A. y aplicaciones en tiempo real

Ambos lenguajes comparten ciertas características y poseen su propias peculiaridades. No obstante, la mejor forma de comparar estos lenguajes es realizando algunos ejemplos.

Comparando lenguajes de programación

Declaración de variables:

Comparativa MoonBit y Python

Aspecto Python MoonBit
Declaración
x = 10 # todo es asignación dinámica
let x = 10 (inmutable por defecto)
var y = 20 (mutable)
Tipado
# Dinámico, no requiere anotación.
# Ejemplo: 
s = "hola"
# Estático, inferido por el compilador.
# Ejemplo: 
let s: String = "hola"
Tipos básicos
int, float, bool, str, list, dict, tuple, None
Int, Float, Bool, String, Array, Option, Result
Mutabilidad Todas las variables son referencias mutables por defecto Control explícito con let (inmutable) y var (mutable)

Escribamos el clásico programa de "Hola, mundo" en ambos lenguajes.

holamundo.mbt

fn main() {
    print("Hola, mundo")
}

Ejecución:

$ moon run holamundo.mbt

En Python:

holamundo.py

def main():
    print("Hola, mundo")

if __name__ == "__main__":
    main()

Ejecución:

$ python holamundo.py

Miremos otro ejemplo. El clásico programa de "FizzBuzz".

En MoonBit:

fizzbuzz.mbt

fn fizzbuzz(n: Int) {
    for i in 1..n {
        if i % 15 == 0 {
            print("FizzBuzz")
        } else if i % 3 == 0 {
            print("Fizz")
        } else if i % 5 == 0 {
            print("Buzz")
        } else {
            print(i)
        }
    }
}

fn main() {
    fizzbuzz(20)
}

Ejecución:

$ moon run fizzbuzz.mbt

Salida:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

En Python:

fizzbuzz.py

def fizzbuzz(n: int):
    for i in range(1, n + 1):
        if i % 15 == 0:
            print("FizzBuzz")
        elif i % 3 == 0:
            print("Fizz")
        elif i % 5 == 0:
            print("Buzz")
        else:
            print(i)

if __name__ == "__main__":
    fizzbuzz(20)

Ejecución:

$ python fizzbuzz.py

Salida:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

Creación de proyectos en MoonBit y Python.

Aspecto MoonBit Python
Herramienta oficial moon new <project> crea estructura básica con src/, tests/, moon.mod No hay comando oficial, pero se recomienda estructura estándar con setup.py, requirements.txt, src/, tests/
Estructura típica
├── src/
├── tests/
└── moon.mod
        
├── src/
├── tests/
├── requirements.txt
├── setup.py
└── README.md
        
Gestión de dependencias moon add <package> (usa repositorio oficial) pip install <package> y se registra en requirements.txt
Ejecución moon run python main.py o pytest para pruebas

MoonBit apuesta por tipado estático, mutabilidad controlada y proyectos con estructura mínima pero clara.

Python es dinámico, flexible y tiene una comunidad enorme con convenciones más que reglas estrictas.

Ambos lenguajes tienen similitudes, pero obviamente MoonBit comparte mayor similitud con Go y no tanto con Python.

Python a su vez comparte mayor similitud a lenguajes como Mojo. Un lenguaje que comparte mucha de su sintexis.

Continuaremos más adelante comparando más lenguajes.

Enlaces:

https://codemonkeyjunior.blogspot.com/2026/05/comparativa-entre-go-y-moonbit.html
https://docs.moonbitlang.com/en/latest/tutorial/for-go-programmers/index.html

sábado, 16 de mayo de 2026

Comparativa entre Go y MoonBit

En está ocasión haremos una comparativa entre el lenguaje de programación Go y Moonbit, el lenguaje orientado a I.A.

Go es un lenguaje de programación diseñado para ser rápido, eficiente, concurrente y fácil de aprender. Compilado y con tipado estático, destaca en el desarrollo backend, sistemas en la nube y redes gracias a su gestión automática de memoria y alto rendimiento.

Por el otro lado, MoonBit es una cadena de herramientas de lenguaje de programación nativo de IA para computación en la nube y edge. Además se compila a WebAssembly, JavaScript y C.

Observemos la siguiente tabla comparativa.

Comparativa Go y MoonBit

Característica Go MoonBit
Creador Ken Thompson, Robert Pike y Robert Griesemer Zhang Hongbo
Paradigma Multiparadigma Programación asíncrona basado en corrutinas, similar a Kotlin
Tipado Estático Estático
Extensión .go .mbt
Nivel de abstracción Alto Alto
Tipo de ejecución Compilado Compilado
Ideal para Microservicios, aplicaciones concurrentes, etc. Orientado a la I.A. y aplicaciones en tiempo real

Ambos lenguajes comparten ciertas características y poseen su propias peculiaridades. No obstante, la mejor forma de comparar estos lenguajes es realizando algunos ejemplos.

Para más detalles puedes ver esto: https://docs.moonbitlang.com/en/latest/tutorial/for-go-programmers/index.html


Creando proyectos con Go y MoonBit

Empezaremos creando un sencillo proyecto con Go.

1. Creamos un directorio y nos ubicamos en el:

$ mkdir holamundo
$ cd holamundo

2. Inicializamos el módulo:

$ go mod init example.com\holamundo

3. Creamos un programa ``main.go`` con el siguiente contenido:

package main

import "fmt"

func main() {
  fmt.Println("¡Hola, mundo en Go!")
}

La estructura del proyecto lucirá así:

holamundo/
   go.mod
   main.go

Construimos:

$ go build

Esto creará un ejecutable.

Salida:

¡Hola, mundo en Go!

Ahora con MoonBit.

1. Creamos el proyecto:

$ moon new holamundo
$ cd holamundo

El directorio principal y archivos quedarán de esta forma:

holamundo/
├── cmd
   └── main
       ├── main.mbt
       └── moon.pkg
├── holamundo_test.mbt
├── config.mbt
├── holamundo.mbt
├── moon.mod.json
└── moon.pkg

El contenido del archivo ``main.mbt`` es el siguiente:

fn main {
  println("¡Hola, mundo en MoonBit!")
}

Ahora ejecutamos:

$ moon run cmd\main\main.mbt

Salida:

¡Hola, mundo en MoonBit!

Tomemos un ejercicio de Project Euler: calcular la suma de todos los múltiplos de 3 o 5 menores que 1000.

En Go sería de este modo:

main.go

package main

import  "fmt"

func main() {
    vect := make([]int, 1000)
    for i := 0; i < 1000; i++ {
        vect[i] = i + 1
    }

    sum := 0
    for _, v := range vect {
        if v%3 == 0 && v%5 == 0 {
            sum += v
        }
    }

    fmt.Println("Suma:", sum)
}

Construimos y ejecutamos:

$ go build
$./main.exe

Salida:

Suma: 33165

En MoonBit sería así:

main.mbt

fn main {
    let vect = Array::new()

    for i = 0; i < 1000; i = i + 1 {
        vect.push(i + 1)
    }
    let sum = for i = 0, acc = 0; i < vect.length(); i = i + 1 {
        let v = vect[i]
        if v % 3 == 0 && v % 5 == 0 {
            continue i + 1, acc + v
        }
    } else { acc }

    println("Suma: ")
    println(sum)
}

Por el momento es todo. Continuaremos con la comparativa en próximas entregas.

Enlaces:

https://tour.moonbitlang.com/
https://projecteuler.net/
https://docs.moonbitlang.com/en/latest/tutorial/for-go-programmers/index.html
https://alquimistadecodigo.blogspot.com/search?q=go
https://go.dev/
https://emanuelpeg.blogspot.com/search?q=go

sábado, 9 de mayo de 2026

GCP: optimizando consultas y sentencias en BigQuery


BigQuery nos permite realizar las siguientes operaciones:

  1. Consulta de datos: Puedes ejecutar consultas SQL complejas para extraer datos de tus conjuntos de datos y realizar análisis avanzados.
  2. Análisis de datos en tiempo real: BigQuery admite consultas en tiempo real sobre datos de streaming, lo que te permite analizar y visualizar datos en tiempo real a medida que llegan.
  3. Análisis geoespacial: BigQuery incluye funciones y operaciones para realizar análisis geoespaciales, como cálculos de distancia, intersecciones espaciales y agrupaciones geográficas.
  4. Operaciones de agregación: Puedes realizar operaciones de agregación como SUM, AVG, COUNT, MAX y MIN en tus datos para resumir la información y obtener insights.
  5. Procesamiento de texto: BigQuery proporciona funciones y operadores para procesar datos de texto, como búsquedas de patrones, análisis de sentimientos y extracción de entidades.
  6. Integración con herramientas de análisis y visualización: Puedes integrar BigQuery con herramientas de análisis y visualización de datos populares como Google Data Studio, Tableau y Power BI para crear paneles interactivos y visualizaciones de datos.
  7. Machine Learning: BigQuery ML te permite construir y entrenar modelos de aprendizaje automático directamente en tus datos almacenados en BigQuery, sin necesidad de moverlos a otro lugar.
  8. Carga y exportación de datos: Puedes cargar datos en BigQuery desde archivos locales, Google Cloud Storage, servicios de streaming como Pub/Sub y otras fuentes de datos. También puedes exportar datos desde BigQuery a diferentes formatos de archivo y servicios de almacenamiento.
  9. Seguridad y control de acceso: BigQuery ofrece controles de acceso granulares y opciones de cifrado para proteger tus datos y garantizar la conformidad con las normativas de privacidad.
  10. Administración y monitoreo: BigQuery proporciona herramientas para administrar y monitorear tus recursos, consultas y cargas de trabajo, como el tablero de control de BigQuery y Cloud Monitoring.

Sin embargo, también tiene ciertos limitantes como lo pueden ser:

  • Debes ser cuidadoso por el uso, ya que las cuotas pueden restringir ciertas operaciones iterativas. 
  • Si operas sobre una misma tabla, puede haber bloqueos (lo que evitará un buen almacenamiento de tu información). 
  • No permite subconsultas como en Informix o herramientas similares. 
  • El tamaño de una fila no puede superar los 10MB.
  • Etc.

Y es ahí donde entran las optimizaciones con CTEs (Common Table Expressions) o WITH en las consultas. Imaginemos el siguiente bloque de código:

/*
   Este bloque es para actualizar la información de
 la tabla2 desde la tabla1.
*/

begin
declare fecha_origen date default '2026-04-13';
declare fecha_actual date default '2026-05-09';

for record 
in(select user, info_process from
 `mydataset.tabla1` 
where date_process = fecha_origen) 
do
  update `mydataset.tabla2` 
set user = record.user, 
info_process = record.info_process, 
date_process= fecha_actual 
where date_process = fecha_origen ;
end for;

end;

El bloque realiza la operación de actualización correctamente, pero no es lo más óptimo. Pues debemos cuidar los recursos.

Rehacemos el bloque pero usando la cláusula de WITH. Esto nos permitirá la optimización del bloque y ahorraremos tiempo y recursos valiosos.

Tenemos entonces lo siguiente:

/*
   Este bloque es para actualizar la información de
 la tabla2 desde la tabla1.
*/

begin
declare fecha_origen date default '2026-04-13';
declare fecha_actual date default '2026-05-09';

update `mydataset.tabla2` as tab_up 
set user = src.user, 
info_process = src.info_process, 
date_process= fecha_actual 
from(
   select id, user, info_process 
   FROM `mydataset.tabla1` where date_process = fecha_origen 
) as src where  tab_up.id = src.id 
 and  tab_up.date_process = fecha_origen ;

end;

Aunque no empleamos la cláusula, seguimos su misma lógica: optimizar la consulta.

¿Qué pasaría si quisieramos hacer una inserción?

Tomando en cuenta el siguiente bloque:

/*
   Este bloque es para actualizar la información de
 la tabla2 desde la tabla1.
*/

begin
declare fecha_actual date default '2026-05-09';

for record 
in(select valor_mensual from
 `mydataset.tabla1` 
where date_process = fecha_actual and importe < 99.9) 
do
  
insert into `mydataset.tabla2`(valor_mensual) value (record.valor_mensual); 

end for;

end;

El bloque trabaja casi perfectamente, pero no es óptimo el uso de recursos.

Rehacemos el bloque con la lógica de WITH:

/*
   Este bloque es para actualizar la información de
 la tabla2 desde la tabla1.
*/

begin
declare fecha_actual date default '2026-05-09';


insert into `mydataset.tabla2`(valor_mensual) 
with source as(
  select t.valor_mensual from `mydataset.tabla1` t
  where t.date_process = fecha_actual and t.importe < 99.9
) select * from source;



end;

Como se puede observar si usamos la cláusula WITH y no solo su lógica como en el ejemplo del bloque UPDATE.

Y cómo es lógico, también lo podemos aplicar a las consultas con SELECT. Miremos una consulta no optimizada y comparémosla con una que sí lo está:

declare fecha_actual date default '2026-05-09';
declare importe_max float64;
set importe_max = 99.9;

select user, date_process, importe, valor_mensual
 `mydataset.tabla2`
where date_process = (
   select date_process
 `mydataset.tabla1`where date_process = fecha_actual 
) and importe = (
  select importe
 `mydataset.tabla1`where importe < importe_max 
);

Optimizada:

DECLARE fecha_actual DATE DEFAULT DATE '2026-05-09';
DECLARE importe_max FLOAT64 DEFAULT 99.9;

WITH filtro_fecha AS (
  SELECT date_process
  FROM `mydataset.tabla1`
  WHERE date_process = fecha_actual
),
filtro_importe AS (
  SELECT importe
  FROM `mydataset.tabla1`
  WHERE importe < importe_max
)
SELECT user, date_process, importe, valor_mensual
FROM `mydataset.tabla2`
WHERE date_process IN (SELECT date_process FROM filtro_fecha)
  AND importe IN (SELECT importe FROM filtro_importe);

¿Y qué de las operaciones de borrado?

Sin optimizar:

begin
declare fecha_actual date default '2026-05-09';

for record 
in(select valor_mensual from
 `mydataset.tabla1` 
where date_process = fecha_actual and importe < 99.9) 
do
  
delete from `mydataset.tabla2`where valor_mensual = record.valor_mensual
 and date_process = fecha_actual;

end for;

end;

Optimizada:

DECLARE fecha_actual DATE DEFAULT DATE '2026-05-09';

WITH valores_a_borrar AS (
  SELECT valor_mensual
  FROM `mydataset.tabla1`
  WHERE date_process = fecha_actual
    AND importe < 99.9
)
DELETE FROM `mydataset.tabla2`
WHERE date_process = fecha_actual
  AND valor_mensual IN (SELECT valor_mensual FROM valores_a_borrar);

Como hemos visto, el uso de la cláusula WITH nos permite evitar subconsultas repetitivas y hace el código más legible y eficiente.

Seguiremos hablando de este tema en próximas entregas.

Enlaces:

https://codemonkeyjunior.blogspot.com/2024/04/gcp-google-cloud-bigquery.html
WITH statements in BigQuery SQL (Youtube)

Lenguajes que han muerto y que no estabas enterado: el caso de Ceylon

Ceylon fue un lenguaje de programación que prometía algo que otros han intentado sin éxito: ser el verdadero sucesor de Java . Tam...

Etiquetas

Archivo del blog