La renaissance de Golo

Par Philippe Charrière, Principal Solutions Architect chez Docker. J’ai la manie de créer de nombreux side projects (certains survivent).

Pendant les vacances de Noël, je voulais valider quelques hypothèses concernant le vibe coding. J'ai donc décidé de faire le portage de Golo, un langage de programmation développé à l'origine en Java et à base de InvokeDynamic, vers GoloScript. Donc un interpréteur Golo, mais cette fois écrit en Go.

Donc Golo, c'était par ici: https://golo-lang.github.io "a lightweight dynamic language for the JVM". Ce langage a été développé par Julien Ponge au laboratoire CITI (INSA Lyon) dans le cadre des activités du groupe de recherche DynaMid. Golo est un effort pionnier pour concevoir un langage spécifiquement autour de l'instruction de bytecode invokedynamic introduite dans Java 7 (JSR 292). Contrairement à d'autres langages dynamiques de la JVM comme Groovy, JRuby ou Nashorn qui ont adapté le support d'invokedynamic, Golo a été conçu dès le départ pour tirer parti de ces capacités, ce qui en faisait un runtime de langage léger, rapide et remarquablement hackable.

Et je tiens à préciser que Golo est devenu un projet Eclipse en 2015: https://projects.eclipse.org/projects/technology.golo

Je suis devenu contributeur du projet, et c'est comme cela que j'ai appris tout ce que je connais de Java (et de la JVM) aujourd'hui.

Le choix de ce projet n'était pas anodin: le projet est relativement "gros" et on parle d'implémentation de langage, donc rien à voir avec un simple CRUD pour déployer un service SaaS non sécurisé sur le Cloud. J'ai longtemps contribué dessus, donc je connais plutôt bien le code, ainsi que les spécificités du langages.

Ce qui fait que je suis à même de:

  • vérifier que les fonctionnalités sont bien implémentées correctement

  • guider l'agent de codage dans les bonnes directions

  • faire des exemples tordus pour valider les implémentations

J'ai utilisé Claude Code pour faire ce portage (et valider mes hypothèses).

À ma grande surprise, j'avais un PoC fonctionnel au bout d'un après-midi !!!. Au bout d'une semaine, une version complète avec des nouveautés par rapport à l'ancienne version (notamment liées à WebAssembly et forcément l'IA générative). Et quand je dis une semaine, c'est en pointillé (tôt le matin avant d'aller bosser, le soir la nuit lorsque je ne dors pas).

A l'issue de cette première semaine, j'avais un interpréteur GoloScript fonctionnel qui était facile à faire évoluer sans IA! En effet, une des spécificités du projet initial Golo, c'était que sans être un spécialiste de l'implémentation de langage, on pouvait facilement comprendre le code et lui ajouter des fonctionnalités en Java et en Golo. Donc l'interpréteur GoloScript est maintenant "augmentable" en Go et en Golo, et une fois recompilé vous disposez de la nouvelles fonctionnalités (souvenez vous du "remarquablement hackable").

La deuxième semaine, (en cours au moment où j'écris ces lignes), consiste plus à faire de la documentation, des tests, des exemples, du fix de bugs, et à commencer à ajouter des fonctionnalités au langage mais sans IA, uniquement en utilisant les possibilités d'augmentations offertes par GoloScript... Et faire aussi un site web pour présenter tout ça (https://gololang.org/ ).

Quelques exemples qui illustrent l'usage de GoloScript :

  1. Si vous souhaitez reproduire et exécuter les exemples, vous pouvez bien entendu télécharger la dernière release de GoloScript ici https://codeberg.org/TypeUnsafe/golo-script/releases. C'est un simple binaire sans dépendances externes. J'ai pu tester les versions pour Linux arm et amd, ainsi que Darwin arm. N'hésitez pas à me faire un retour si vous rencontrez des problèmes sur d'autres plateformes.

  2. Autre solution: j'ai créé une sorte de playground que vous pouvez lancer avec Docker Compose: https://codeberg.org/TypeUnsafe/golo-playground et vous disposerez de tout le nécessaire pour commencer à utiliser GoloScript.

Le langage Golo a toujours eu un style bien a lui, qui vous permet de développer d'une manière relativement classique, mais aussi avec une touche de programmation fonctionnelle (sans que cela soit obligatoire). GoloScript hérite de cette philosophie.

L'incontournable Hello World

module hello

function main = |args| {

    println("Hello, World! ")

}


GoloScript supporte les Closures

module closures

function main = |args| {

    let divide = |a, b| -> a/b

    try {

        println(divide(84, 0))

    } catch (err) {

        println("Erreur : " + err :message())

    }

}

La même chose mais avec une touche plus fonctionnelle

module closures

import gololang.Errors

function main = |args| {

    let divide = |a, b| -> a/b

    trying(-> divide(84, 0))

      : either( 

        |value| -> println("Valeur", value),

        |error| -> println("Erreur", error)

      )

}

Ce qui est nouveau dans GoloScript ?

Dans les nouveautés il y a WebAssembly (via Wazero), mais aussi et surtout l'intégration de l'IA générative et le support du protocol MCP comme client et serveur. Pour aujourd'hui ce sera un aperçu rapide de l'IA générative. Vous pouvez maintenant utiliser GoloScript pour créer des agents IA basés sur des modèles de langage avec tout "moteur" de LLM compatible avec l'API OpenAI (Docker Model Runne, Ollama, llama.cpp, ...):

module ai.gololang

import gololang.Errors

import gololang.Ai

function main = |args| {

  # Create an OpenAI client using the builtin function

  let openAIClient = openAINewClient(

    "http://localhost:12434/engines/llama.cpp/v1",

    "I love DockerModelRunner",

    "ai/qwen2.5:1.5B-F16"

  )

  let littleAgent = 

    ChatAgent()

    : name("LittleAgent")

    : client(openAIClient)

    : messages(list[])

    : options(

        DynamicObject()

          : temperature(0.7)

          : topP(0.9)

      )

    : systemMessage(

      "You are a creative storyteller, expert in Star Trek lore."

      )

  littleAgent: streamCompletion("[Brief] Who is James T Kirk.",

    |chunk| {

      if chunk: error() != null {

        println("Error:", chunk: error())

        return false

      }

      print(chunk: content())

      return true  # Continue streaming

    }

  ): either(

    |value| -> println("\n\nStream completed with", value: chunkCount(), "chunks."),

    |error| -> println("\n\nStream failed with error:", error)

  )

}

À noter: que l'intégration de l'IA dans GoloScript comme ci-dessus (le module gololang.Ai) est 100% écrite en GoloScript et "à la main", encore une fois le côté "remarquablement hackable" du langage. Et ce module utilise l'intégration du SDK Go OpenAI dans GoloScript. Le ChatAgent est une structure GoloScript augmentée avec des méthodes pour gérer les conversations avec les modèles de langage. D'autres Agent IA sont en cours de développement.

Voilà pour ce rapide aperçu de GoloScript. J'espère que cela vous a plu et que vous aurez envie d'essayer ce langage dynamique et "hackable".

Catégorie actualité: 
Image actualité AMP: 
Espace publicitaire · 300×250