Translate

domingo, 19 de abril de 2026

¿Por qué Java usa Streams?


Cuando Java introdujo Streams en Java 8, no fue solo para “hacer código más lindo”, sino para cambiar la forma en que procesamos colecciones.


Pero otros lenguajes de la JVM ya resolvían esto de forma distinta.

Entonces, la pregunta es: ¿por qué Java eligió Streams y no otro modelo?


Antes de Java 8:

List<String> result = new ArrayList<>();

for (String s : lista) {

    if (s.length() > 3) {

        result.add(s.toUpperCase());

    }

}


Mucho boilerplate

  • No es declarativo
  • Difícil de paralelizar
  • Mezcla lógica con control de flujo


La solución: Streams en Java


Con Streams:


List<String> result = lista.stream()

    .filter(s -> s.length() > 3)

    .map(String::toUpperCase)

    .toList();


Claves del diseño:

  • Evaluación lazy
  • Pipeline de operaciones
  • Separación entre datos y procesamiento
  • Fácil paralelización (parallelStream())


Java construyó un modelo nuevo, no solo métodos en Collection ¿y por qué? Otros lenguajes los hacían bien. 

Scala

lista.filter(_.length > 3).map(_.toUpperCase)


Características

  • Colecciones inmutables por defecto
  • Operaciones directamente sobre la colección
  • Lazy solo si usás View o LazyList

Scala no necesita Streams porque su API de colecciones ya es funcional


Kotlin

lista.filter { it.length > 3 }

     .map { it.uppercase() }


Características:

  • API funcional sobre colecciones
  • Operaciones eager por defecto


Para lazy:

lista.asSequence()

    .filter { it.length > 3 }

    .map { it.uppercase() }


Diferencia clave

Kotlin separa:

  • List (eager)
  • Sequence (lazy)


Java unificó esto en Streams.


Groovy

lista.findAll { it.length() > 3 }

     .collect { it.toUpperCase() }


Características

  • Muy expresivo
  • Dinámico
  • API funcional desde hace años


Diferencia clave

Más simple, pero:

  • menos eficiente
  • no lazy por defecto
  • sin optimización tipo pipeline


Entonces ¿Por qué Java eligió Streams?


Java tenía restricciones fuertes:

1. Compatibilidad hacia atrás, no podía romper Collection

2. Necesidad de lazy evaluation para evitar:

  • listas intermedias
  • consumo extra de memoria


3. Paralelismo

Streams permiten: lista.parallelStream() sin cambiar el código lógico


4. Pipeline optimizable


La JVM puede optimizar: filter → map → reduce, como una sola operación


Java no eligió Streams por casualidad.

Fue una decisión para:

  • mantener compatibilidad
  • introducir programación funcional
  • mejorar performance
  • habilitar paralelismo


Mientras otros lenguajes:

  • ya eran funcionales (Scala)
  • o tomaron caminos más simples (Kotlin, Groovy)



sábado, 18 de abril de 2026

Java 26: Hacia dónde evoluciona la plataforma


Java 26 representa una versión en evolución dentro del ciclo de releases de Java, donde se profundizan cambios importantes en concurrencia, rendimiento y modelo de datos.

Tipo de release: No LTS

Estado: 🧪 En desarrollo / Early Access

Enfoque: innovación + maduración de features clave


Concurrencia (Project Loom)

Java continúa consolidando un nuevo modelo de concurrencia.


Structured Concurrency (posible estabilización)

Permite agrupar tareas relacionadas como una unidad lógica

Simplifica:

  • manejo de errores
  • cancelación
  • sincronización


Hace que el código concurrente sea más legible y seguro


Virtual Threads (optimización continua)

  • Mejor integración con APIs existentes
  • Ajustes de rendimiento
  • Mayor adopción en frameworks


Lenguaje: menos boilerplate


Pattern Matching (más evolución)

  • Código más declarativo
  • Reducción de casts explícitos
  • Mejor integración con `switch`


Java sigue acercándose a un estilo más expresivo sin perder claridad.

Interoperabilidad nativa

Foreign Function & Memory API (FFM)

  • Más cerca de ser estándar definitivo
  • Alternativa real a JNI


Permite:

  • acceso eficiente a memoria off-heap
  • llamadas a librerías nativas


Clave para aplicaciones de alto rendimiento


Proyecto Valhalla (avance gradual)

Uno de los cambios más importantes a largo plazo.


Value Objects (en progreso)

  • Objetos sin identidad
  • Mejor uso de memoria
  • Mayor eficiencia en estructuras de datos


Impacto esperado:

  • colecciones más rápidas
  • menos overhead de objetos


JVM y rendimiento


  • Mejoras continuas en:
    • G1
    • ZGC
  • Optimización del JIT
  • Mejor uso de CPU moderna


Java 26 no es una versión de adopción masiva, sino una versión que:

  • empuja nuevas ideas
  • estabiliza features incubadas
  • prepara cambios grandes a futuro


miércoles, 15 de abril de 2026

¿Qué es LLVM? Introducción a la infraestructura detrás de los compiladores modernos


Si alguna vez te preguntaste cómo lenguajes como Rust o Swift generan código tan eficiente…

La respuesta probablemente sea: LLVM. LLVM no es un compilador tradicional es una infraestructura para construir compiladores.


Durante años, herramientas como GCC siguieron este modelo:

  • Todo en uno (frontend + optimización + backend)
  • Difícil de extender
  • Costoso crear nuevos lenguajes


Resultado: crear un lenguaje era MUY complejo


LLVM cambia el enfoque: Separar el compilador en piezas reutilizables


¿Cómo funciona LLVM?

El proceso se divide en 3 partes:

Frontend

  • Convierte tu lenguaje a LLVM IR
  • Cada lenguaje define su frontend


LLVM IR (Intermediate Representation)

Es el corazón del sistema:

  • Representación intermedia
  • Independiente del hardware
  • Optimizable


Ejemplo:

llvm id="u7j1k0"

define i32 @main() {

  %1 = add i32 10, 20

  ret i32 %1

}


Un “lenguaje común” entre todos los compiladores


Backend

Convierte el IR en código máquina:

  • x86
  • ARM
  • RISC-V

LLVM se encarga de esto


¿Por qué es tan importante? Porque reduce drásticamente la complejidad:

Antes: Lenguaje = compilador completo

Ahora: Lenguaje = frontend + LLVM


LLVM es muy usado, entre los lenguajes que lo usan podemos encontrar:

  • Rust
  • Swift
  • C/C++ con Clang
  • Kotlin Native


LLVM separa responsabilidades:

  • Lenguaje → Frontend
  • Optimización → LLVM
  • Hardware → Backend


Esto permite innovación más rápida y reutilización masiva

LLVM es el motivo por el cual hoy crear un lenguaje es mucho más accesible que antes.

martes, 14 de abril de 2026

Alias en imports en Java: lo que no existe (y cómo resolverlo)


Cuando venís de otros lenguajes, es común esperar algo como esto:

import com.ejemplo.A as A1; // ❌


Pero en Java esto simplemente no existe.


 ¿Qué son los alias en imports?


Un alias permite:

  • Importar dos clases con el mismo nombre
  • Y diferenciarlas con nombres alternativos


Ejemplo típico en otros lenguajes:


Kotlin

import com.ejemplo.a.Clase as ClaseA

import com.ejemplo.b.Clase as ClaseB


Scala

import com.ejemplo.a.{Clase => ClaseA}

import com.ejemplo.b.{Clase => ClaseB}


C#

using ClaseA = Ejemplo.A.Clase;

using ClaseB = Ejemplo.B.Clase;


¿Qué pasa en Java?


Si tenés dos clases con el mismo nombre:


import com.ejemplo.a.Clase;

import com.ejemplo.b.Clase; // ❌ conflicto


Java no sabe cuál usar.

La solución es tenés que usar el nombre completo en al menos uno:


import com.ejemplo.a.Clase;


public class Main {

    public static void main(String[] args) {

        Clase a = new Clase();

        com.ejemplo.b.Clase b = new com.ejemplo.b.Clase();

    }

}


¿Por qué Java no tiene alias?


El lenguaje prioriza:

  • Simplicidad
  • Legibilidad explícita
  • Evitar ambigüedades en compilación

No hay transformación de nombres en imports


Problemas reales que genera:

  • Código más verboso
  • Menor ergonomía
  • Conflictos frecuentes en proyectos grandes
  • Difícil integración entre librerías con naming similar

Java no soporta alias en imports y la solución es usar nombres completos. Pero otros lenguajes modernos sí lo resuelven mejor


viernes, 10 de abril de 2026

Java 25: Evolución y consolidación de la plataforma


Java SE 25 continúa el camino de modernización de Java, con foco en concurrencia, rendimiento y maduración de features introducidas en versiones anteriores.

Ojo es No LTS


Concurrencia (Project Loom)


Java sigue apostando fuerte por la concurrencia moderna.

Virtual Threads (madurez)

  • Totalmente integrados en el ecosistema
  • Mejoras en estabilidad y rendimiento
  • Transparencia casi total respecto a threads tradicionales


Beneficio clave: Escalar a miles de tareas concurrentes sin complejidad extra


Scoped Values (evolución)

Alternativa moderna a ThreadLocal:


ScopedValue<String> user = ScopedValue.newInstance();


ScopedValue.where(user, "Emanuel").run(() -> {

    System.out.println(user.get());

});


  • Inmutables
  • Seguros en entornos concurrentes
  • Ideales para usar con Virtual Threads


Structured Concurrency (avance)

  • Mejor organización de tareas relacionadas
  • Manejo más claro de errores y cancelaciones
  • Código más predecible


Lenguaje: más simple y expresivo


Pattern Matching (refinamientos)

  • Mejoras en switch
  • Menos casting manual
  • Código más limpio


switch (obj) {

    case String s -> System.out.println(s);

    case null -> System.out.println("null");

    default -> {}

}


Interoperabilidad


Foreign Function & Memory API

  • Más estable y usable
  • Reemplazo progresivo de JNI


Permite:

  • llamar a código nativo
  • manejar memoria off-heap de forma segura


JVM y rendimiento

Garbage Collectors


Mejoras continuas en:

  • G1
  • ZGC


Optimizaciones generales

  • Menor latencia
  • Mejor throughput
  • Ajustes en el JIT


Ecosistema

  • Mejor integración con frameworks modernos
  • Tooling más alineado con Virtual Threads
  • Preparación para proyectos futuros como Valhalla


Java 25 no busca revolucionar, sino consolidar lo que ya empezó a cambiar Java profundamente:

  • Concurrencia moderna ya usable en producción
  • Lenguaje más expresivo
  • Mejor performance


Acelera la innovación de la IA con contenedores

 Me llegó este mail de google y lo quería compartir : 

martes, 7 de abril de 2026

Java 24: Novedades y características principales


Java SE 24 continúa la evolución de la plataforma con foco en rendimiento, concurrencia y simplificación del lenguaje.

Ojo es no LTS!


Concurrencia moderna (Project Loom)

Uno de los ejes más importantes sigue siendo la evolución de la concurrencia.


Virtual Threads (mejoras)

  • Threads livianos gestionados por la JVM
  • Permiten manejar miles o millones de tareas concurrentes
  • Menor costo que los threads tradicionales


Structured Concurrency (incubating)

  • Permite tratar múltiples tareas como una sola unidad lógica
  • Mejora el manejo de errores y cancelaciones


Ejemplo conceptual:


try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {

    scope.fork(() -> servicioA());

    scope.fork(() -> servicioB());

    scope.join();

    scope.throwIfFailed();

}


Lenguaje: más expresividad


Pattern Matching (evolución)

  • Mejora continua en switch
  • Código más declarativo y menos verboso


switch (obj) {

    case String s -> System.out.println(s.length());

    case Integer i -> System.out.println(i * 2);

    default -> {}

}


Interoperabilidad nativa

Foreign Function & Memory API (evolución)

  • Reemplazo moderno de JNI
  • Acceso seguro a memoria fuera del heap
  • Llamadas a código nativo (C/C++)


Beneficios:

  • más performance
  •  menos complejidad que JNI


Rendimiento y JVM

Garbage Collectors

Mejoras en:

  • G1
  • ZGC


Optimizaciones generales

  • Mejor uso de CPU y memoria
  • Reducción de pausas


Otras mejoras

  • Refinamientos en APIs estándar
  • Mejoras internas en la JVM
  • Preparación para futuros proyectos como Valhalla


Java 24 no introduce cambios “revolucionarios”, pero sí consolida tendencias clave:

  • Concurrencia moderna (Loom)
  • Código más expresivo (Pattern Matching)
  • Mejor interoperabilidad (FFM API)
  • Performance constante


Es una versión que prepara el terreno para cambios más grandes en futuras releases.

sábado, 4 de abril de 2026

¿Cual es el estado de los lenguajes que corren sobre la plataforma Java?



La plataforma Java no es solo el lenguaje Java. Gracias a la JVM (Java Virtual Machine), es posible ejecutar múltiples lenguajes con distintos paradigmas y objetivos.

A continuación, un resumen breve de los más relevantes:


Java

Objetivo: Lenguaje generalista, orientado a objetos.

Uso típico: Backend, enterprise, Android (históricamente).

Estado: Activo y en constante evolución (LTS recientes, mejoras funcionales).


Kotlin

Objetivo: Alternativa moderna a Java, más concisa y segura.

Uso típico: Android, backend, multiplataforma.

Estado:  Muy activo, impulsado por JetBrains y adoptado oficialmente por Google.


Scala

Objetivo: Mezclar programación funcional y orientada a objetos.

Uso típico: Big Data, sistemas distribuidos.

Estado: Activo, pero con menor adopción reciente frente a Kotlin.


Groovy

Objetivo: Lenguaje dinámico para simplificar Java.

Uso típico: Scripts, testing, herramientas como Gradle.

Estado:  Estable, pero en segundo plano.


Clojure

Objetivo: Programación funcional pura (Lisp en la JVM).

Uso típico: Sistemas concurrentes, data processing.

Estado: Activo en nichos específicos.


Jython

Objetivo: Implementación de Python sobre la JVM.

Uso típico: Integración con ecosistema Java.

Estado: Limitado (sin soporte moderno de Python 3 completo).


JRuby

Objetivo: Ejecutar Ruby en la JVM.

Uso típico: Integración con sistemas Java.

Estado: Activo, pero nicho.


Frege

Objetivo: Lenguaje funcional inspirado en Haskell.

Uso típico: Académico / experimental.

Estado: Poco activo.


Eta

Objetivo: Llevar Haskell a la JVM.

Uso típico: Funcional puro sobre JVM.

Estado: Proyecto prácticamente detenido.


 JavaScript (GraalVM)

Objetivo: Ejecutar JavaScript en la JVM mediante GraalVM.

Uso típico: Polyglot, microservicios, scripting.

Estado:  Activo y en crecimiento.


Python (GraalVM)

Objetivo: Ejecutar Python sobre la JVM con GraalVM.

Uso típico: Integración polyglot.

Estado:  Experimental.


La JVM es en una plataforma polyglot, donde distintos lenguajes conviven según la necesidad.

Cursos Gugler: Inscripciones para el primer cuatrimestre del año 2026

Se encuentran abiertas las inscripciones para el primer cuatrimestre del año 2026, para todas las capacitaciones dictadas por el Laboratorio de Investigación Gugler. Podés asegurar tu lugar en el curso y comisión que desees !!!.

Las clases inician:

  • Lunes 06/04 , Jueves 09/04 o Sábado 11/04, según el curso que elegiste.

Podés inscribirte utilizando el siguiente enlace: INSCRIBIRME

Cursos, horarios y comisiones disponiblesINFO CURSOS






jueves, 2 de abril de 2026

DORA 2025: mejora el rendimiento de tu equipo con la IA

 

Estado actual de Roslyn (.NET Compiler Platform)


Roslyn es la plataforma de compilación de .NET que provee compiladores para C# y VB.NET, junto con APIs para análisis de código, generación y tooling.


Roslyn no es solo un compilador, sino una plataforma como servicio:

  • Compilación de código (C#, VB.NET)
  • Análisis estático (analyzers)
  • Refactorizaciones
  • Generación de código (source generators)
  • Base de herramientas como Visual Studio y OmniSharp


Antes de Roslyn, los compiladores eran “cajas negras”, pero con Roslyn:

  • El código se representa como árboles de sintaxis (Syntax Trees)
  • Podés inspeccionar y modificar código en tiempo de compilación
  • Todo está expuesto como API


Esto habilita cosas como:

  • linters avanzados
  • refactorizaciones automáticas
  • generación de código en compile-time


Estado actual (2026)

  • Totalmente activo y mantenido por Microsoft
  • Evoluciona junto con C# (últimas versiones como C# 12/13)
  • Fuerte adopción en tooling moderno (.NET CLI, IDEs, analyzers)
  • Ecosistema maduro de analyzers y source generators


Tendencias actuales

Source Generators cada vez más usados

  → reemplazando reflexión en muchos casos


Incremental Generators

  → mejor performance y menos recompilaciones


Mayor uso en:

  • validaciones en compile-time
  • frameworks
  • librerías de alto rendimiento


Roslyn hoy es:

  • el corazón del ecosistema .NET moderno
  • una plataforma estable y madura
  • clave para tooling avanzado y metaprogramación



GraalVM vs GraalOS vs Containers vs Unikernels


En los últimos años aparecieron múltiples formas de ejecutar aplicaciones:

  • GraalVM
  • GraalOS
  • Containers como Docker
  • Y el concepto de Unikernel


Todas apuntan a lo mismo: Ejecutar software de forma más eficiente, portable y segura

Pero no compiten exactamente en el mismo nivel


Antes de comparar, entendamos esto:


| Tecnología | Nivel                          |

| ---------- | ------------------------------ |

| GraalVM    | Runtime / compilación          |

| GraalOS    | Sistema operativo experimental |

| Containers | Empaquetado y ejecución        |

| Unikernels | Arquitectura de sistema        |


Un error común es compararlas como si fueran alternativas directas. En realidad, muchas se pueden combinar.


GraalVM es un runtime avanzado que permite:

  • Ejecutar múltiples lenguajes
  • Compilar a binarios nativos (Native Image)


Ventajas

  • Arranque ultrarrápido
  • Menor consumo de memoria
  • Ideal para microservicios


Limitaciones

  • Problemas con reflection Complejidad operativa



GraalOS intenta combinar:

GraalVM + filosofía unikernel


Es decir:

  • Apps compiladas como native image
  • Ejecutándose sobre un OS mínimo


Estado actual:

  • Experimental
  • Sin adopción masiva
  • Poco foco en los últimos años


Hoy el mundo real es claro:

  • Docker domina el deploy
  • GraalVM optimiza ejecución
  • Unikernel es prometedor pero nicho
  • GraalOS es más idea que realidad :(


miércoles, 1 de abril de 2026

Rendimiento de Consola: Linux vs Windows (¿realmente uno es más rápido?)


Hace poco me encontré con un comportamiento curioso ejecutando el siguiente código en Java:


var lista = new LinkedList<Long>();

for (var i = 0L; i < Long.MAX_VALUE; i++) {

    System.out.println(i);

    lista.add(i);

}


En Linux corría muchísimo más rápido que en Windows.


La primera reacción fue: ¿La JVM es más rápida en Linux?

Pero la respuesta es: no necesariamente.


El problema no está en Java ni en la lógica del programa. Está en: System.out.println(i);


Cada println implica:

  • Sincronización interna (thread-safe)
  • Conversión a string
  • Llamada al sistema operativo (I/O)
  • Escritura en la consola


Windows (cmd / PowerShell)

  • Consola históricamente más lenta
  • Mayor overhead en escritura
  • Menor eficiencia en buffering
  • Renderizado de texto menos optimizado


🐧 Linux (terminal)

  • Mejor manejo de buffers
  • I/O más eficiente
  • Consolas más livianas (bash, zsh, tty)
  • Mejor throughput de escritura


Si sacamos el println anda muy rápido :


var lista = new LinkedList<Long>();

for (var i = 0L; i < 10_000_000; i++) {

    lista.add(i);

}


El cuello de botella era la consola, no el sistema operativo.


Como lecciones importantes tengo :

  1. Nunca midas performance con println
  2. El I/O domina el rendimiento
  3. No culpes al lenguaje o al OS sin aislar variables
  4. Linux suele tener mejor rendimiento de consola



sábado, 28 de marzo de 2026

GraalOS ¿qué es y en qué estado está?


Si venís siguiendo GraalVM, probablemente escuchaste hablar de GraalOS.


La idea suena ambiciosa. Un sistema operativo optimizado para correr aplicaciones compiladas con GraalVM.

Pero… ¿es algo real hoy? ¿o sigue siendo experimental?


GraalOS es un concepto/proyecto que busca ejecutar aplicaciones native image directamente sobre un sistema mínimo.


Sin necesidad de:

  • JVM tradicional
  • Sistema operativo generalista


En esencia:

  • Llevar la idea de GraalVM al extremo:
  • una app = un runtime + un OS mínimo

GraalOS está muy relacionado con el concepto de Unikernel


Un unikernel:

  • Incluye solo lo necesario para una app
  • Corre directamente sobre el hypervisor
  • Reduce overhead y superficie de ataque


Pero, pero, GraalOS no es un producto maduro ni ampliamente disponible


En los últimos años:

  • No tuvo adopción masiva
  • No hay releases estables mainstream
  • No forma parte del flujo típico de GraalVM


En la práctica es más un concepto exploratorio / investigación que una herramienta de uso diario.

Mientras GraalVM avanzó mucho, GraalOS perdió protagonismo :(


En lugar de GraalOS, crecieron:

  • Containers (Docker)
  • Orquestación (Kubernetes)
  • Serverless

La industria resolvió el problema con otra abstracción


Hoy usarías antes:

  • Un container liviano
  • Un binary con GraalVM Native Image
  • Kubernetes o serverless


Antes que meterte en algo como GraalOS. GraalOS es más una idea interesante que una herramienta práctica.

¿En que anda GraalVM?


GraalVM es uno de los proyectos más interesantes del ecosistema Java. Permite ejecutar múltiples lenguajes (Java, JavaScript, Python, etc.) y, sobre todo, compilar aplicaciones a binarios nativos mediante Native Image.

En los últimos años, el proyecto evolucionó bastante — no tanto en hype, sino en madurez real. Además, hubo cambios importantes en cómo se distribuye y licencia.


Uno de los cambios más importantes: Gran parte de GraalVM se integró más profundamente con OpenJDK

  • El compilador Graal JIT ya no es algo “externo raro”
  • Se volvió más estándar dentro del ecosistema Java
  • Mejor compatibilidad con versiones recientes del JDK (17, 21, 23)


En otras palabras:

  • Antes GraalVM era “algo aparte”.
  • Hoy está mucho más alineado con el stack oficial de Java.


La feature estrella sigue siendo:

  • Ahead-of-Time compilation (AOT)
  • Genera binarios nativos sin JVM
  • Arranque ultra rápido
  • Bajo consumo de memoria


En estos años mejoró muchísimo:

  • Mejor soporte para frameworks (Spring, Micronaut, Quarkus)
  • Menos configuración manual
  • Mejor manejo de reflection
  • Debugging menos doloroso


Especialmente con:

  • Spring Boot + AOT
  • Quarkus (que sigue siendo el más “native-first”)


Cambio clave: licencias y distribución. Acá está el punto más importante del post 

Antes existían dos ediciones:

  •   Community Edition (open source)
  •   Enterprise Edition (mejoras pagas)


Ahora (últimos años) oracle reorganizó todo:

GraalVM Community

  • Basado en OpenJDK
  • Licencia: GPL (con classpath exception)
  • Sigue siendo gratis y open source


GraalVM Oracle (antes Enterprise)

  • Parte del ecosistema comercial de Oracle
  • Incluye optimizaciones avanzadas
  • Integrado con Oracle JDK


Y esto está más alineado con el modelo de licencias de Oracle Java.


Bueno pero, ¿GraalVM ahora es pago?”

La respuesta corta:

  • No, la versión Community sigue siendo gratis
  • Pero algunas features avanzadas están en el ecosistema comercial


Y algo que no me gusta es que Polyglot tiene menos hype y es más de nicho. 

GraalVM nació con la idea de: “Un runtime para múltiples lenguajes”


Soporta:

  • Java
  • JavaScript
  • Python
  • Ruby
  • WebAssembly


Pero, no se usa mucho, creo que es una tendencia general en la industria. 


En estos años se vio algo interesante que hubo menos marketing, más uso concreto


Casos típicos:

  • Microservicios con arranque rápido
  • Serverless
  • Apps en contenedores (menos RAM)


La pregunta del millon ¿Vale la pena hoy? Sí, si:

  • Querés arranque rápido
  • Buscás bajo consumo de memoria
  • Usás frameworks compatibles
  • Estás en cloud / Kubernetes


No tanto si:

  • Usás mucha reflexión dinámica
  • Dependés de librerías complejas
  • Querés “zero config”

Mi opinión es que GraalVM es un producto real, que todos tendríamos que conocer y usar. Si tenés una aplicación en Java y en el cloud, no cuesta nada probar migrar a GraalVM y medir su performance, ya sea usando Graal Jit o binarios nativos. 

martes, 24 de marzo de 2026

Consumir una API en Google Sheets


Con Google Sheets y Google Apps Script podés crear funciones personalizadas que consuman APIs externas.

En este ejemplo vamos a obtener el valor del dólar oficial desde: https://dolarapi.com/v1/dolares/oficial

Crear la función:

1. Ir a Extensiones → Apps Script

2. Crear la siguiente función:


function DOLAR_OFICIAL() {

  var url = "https://dolarapi.com/v1/dolares/oficial";

  

  var response = UrlFetchApp.fetch(url);

  var data = JSON.parse(response.getContentText());

  

  return data.venta;

}


Cómo usarla en la hoja:


En cualquier celda:

=DOLAR_OFICIAL()


¿Qué está pasando?

UrlFetchApp.fetch(url) → hace la llamada HTTP

JSON.parse(...) → convierte la respuesta a objeto

data.venta → accede al valor de venta del dólar


Podemos devolver más datos (compra y venta):


function DOLAR_OFICIAL_COMPLETO() {

  var url = "https://dolarapi.com/v1/dolares/oficial";

  

  var response = UrlFetchApp.fetch(url);

  var data = JSON.parse(response.getContentText());

  

  return [

    ["Compra", "Venta"],

    [data.compra, data.venta]

  ];

}


Uso:

=DOLAR_OFICIAL_COMPLETO()


Esto va a llenar dos columnas automáticamente.


Funciones personalizadas en Google Sheets con Apps Script



Google Sheets permite crear funciones personalizadas usando Google Apps Script, que luego podés usar como si fueran fórmulas nativas (tipo `SUM` o `VLOOKUP`).


Una función personalizada es una función en JavaScript que:

  • Recibe parámetros desde una celda
  • Procesa datos
  • Devuelve un resultado que se muestra en la hoja


Cómo crear una función:

1. Abrí tu hoja en Google Sheets

2. Ir a Extensiones → Apps Script

3. Escribí tu función

4. Guardá el proyecto


Veamos un ejemplo: 

Creamos una función que reciba un nombre y devuelva `"Hola " + nombre`:


function SALUDAR(nombre) {

  return "Hola " + nombre;

}


Cómo usarla?


En cualquier celda escribís:


=SALUDAR("Emanuel")


Resultado:

Hola Emanuel


También podés usar una celda como parámetro:

=SALUDAR(A1)


Nota que: 

  • El nombre de la función suele escribirse en mayúsculas (convención)
  • Debe devolver un valor (string, número, array, etc.)
  • No puede modificar otras celdas directamente (solo retornar valores)
  • Se recalcula cuando cambian los datos


Veamos otro ejemplo: 

Una función que saluda a múltiples nombres:


function SALUDAR_VARIOS(nombres) {

  return nombres.map(n => "Hola " + n);

}



Uso:

=SALUDAR_VARIOS(A1:A3)



Resultado:

Hola Juan

Hola Ana

Hola Pedro


Ideas para usar funciones personalizadas

  • Validaciones complejas
  • Transformación de datos
  • Integración con APIs (clima, cotizaciones, etc.)
  • Automatización de reportes

lunes, 23 de marzo de 2026

Elementos personalizados en Elm




Los navegadores parecen estar admitiendo cada vez más elementos personalizados, lo cual resulta muy útil para integrar JavaScript en programas Elm.

Veamos un ejemplo mínimo de cómo usar elementos personalizados para la localización e internacionalización.

Supongamos que queremos localizar fechas, pero esta funcionalidad aún no está disponible en los paquetes principales de Elm. Quizás quieran escribir una función que localice las fechas:


//

//   localizeDate('sr-RS', 12, 5) === "петак, 1. јун 2012."

//   localizeDate('en-GB', 12, 5) === "Friday, 1 June 2012"

//   localizeDate('en-US', 12, 5) === "Friday, June 1, 2012"

//

function localizeDate(lang, year, month)

{

    const dateTimeFormat = new Intl.DateTimeFormat(lang, {

        weekday: 'long',

        year: 'numeric',

        month: 'long',

        day: 'numeric'

    });


    return dateTimeFormat.format(new Date(year, month));

}


Pero, ¿cómo usamos eso en Elm? Los navegadores más recientes permiten crear nuevos tipos de nodos DOM como este:


//

//   <intl-date lang="sr-RS" year="2012" month="5">

//   <intl-date lang="en-GB" year="2012" month="5">

//   <intl-date lang="en-US" year="2012" month="5">

//

customElements.define('intl-date',

    class extends HTMLElement {

        // things required by Custom Elements

        constructor() { super(); }

        connectedCallback() { this.setTextContent(); }

        attributeChangedCallback() { this.setTextContent(); }

        static get observedAttributes() { return ['lang','year','month']; }


        // Our function to set the textContent based on attributes.

        setTextContent()

        {

            const lang = this.getAttribute('lang');

            const year = this.getAttribute('year');

            const month = this.getAttribute('month');

            this.textContent = localizeDate(lang, year, month);

        }

    }

);


Las partes más importantes aquí son attributeChangedCallback y observedAttributes. Necesitas una lógica similar para detectar los cambios en los atributos que te interesan.

Cárgala antes de inicializar tu código Elm y podrás escribir código como este:


import Html exposing (Html, node)

import Html.Attributes (attribute)


viewDate : String -> Int -> Int -> Html msg

viewDate lang year month =

  node "intl-date"

    [ attribute "lang" lang

    , attribute "year" (String.fromInt year)

    , attribute "month" (String.fromInt month)

    ]

    []


Ahora puedes llamar a viewDate cuando necesites acceder a ese tipo de información localizada en tu vista.


domingo, 22 de marzo de 2026

Apps Script en Google Docs


Este post es nada que ver con este blog, pero Apps Script me ha salvado tanto que sería malísimo no compartirlo. 

Google Docs no solo sirve para escribir documentos: también permite automatizar tareas mediante scripts usando Google Apps Script.

Esto te permite agregar lógica personalizada, generar contenido dinámico o incluso integrar servicios externos.

Apps Script es una plataforma basada en JavaScript que corre en la nube y permite extender herramientas como:

  • Google Docs
  • Google Sheets
  • Google Drive
  • Gmail


En el caso de Google Docs, podemos crear funciones que modifiquen el documento o generen contenido automáticamente.


1. Abrí un documento en Google Docs

2. Ir a Extensiones → Apps Script

3. Se abrirá el editor de scripts

4. Escribí tu función y guardá


Vamos a crear una función que reciba un nombre y retorne "Hola " + nombre.


function saludar(nombre) {

  return "Hola " + nombre;

}


A diferencia de Google Sheets, en Docs no podés invocar funciones directamente en el texto como fórmulas. Pero podés:

  • Ejecutarla desde el editor
  • O usarla para insertar contenido en el documento


Por ejemplo, una versión que escribe directamente en el documento:


function insertarSaludo() {

  var doc = DocumentApp.getActiveDocument();

  var body = doc.getBody();

  

  var nombre = "Emanuel";

  var saludo = "Hola " + nombre;

  

  body.appendParagraph(saludo);

}


Podés combinar esto con menús personalizados para ejecutar funciones desde la UI del documento.


function onOpen() {

  DocumentApp.getUi()

    .createMenu('Mis Scripts')

    .addItem('Insertar saludo', 'insertarSaludo')

    .addToUi();

}


Es ideal para: 

  • Generar reportes automáticamente
  • Insertar firmas o textos repetitivos
  • Crear plantillas dinámicas
  • Integrar con APIs externas