Urlang is pretty nice! There's no format function but most other things work the way I expect them to, and the interface with JavaScript libraries is pretty easy to get along with. This is an implementation of a game loop from a JavaScript game tutorial page and it was pretty straightforward:
#lang at-exp racket ; Implementation of browser game loop from this tutorial: ; https://spicyyoghurt.com/tutorials/html5-javascript-game-development/create-a-pr... (require urlang urlang/for urlang/extra syntax/parse syntax/stx racket/syntax) (current-urlang-run? #f) ; run using Node? No: use browser (current-urlang-echo? #t) ; print generated JavaScript? Yes (current-urlang-console.log-module-level-expr? #t) ; print top-level expression? Yes (see console) (current-urlang-beautify? #t) ; invoke js-beautify (urlang (urmodule game-test (import alert console this Math isFinite Object window document Date) (define context #f) ; Needs to be "global". (define timestamp-old #f) (define (init) (let* ((canvas (document.getElementById "the-canvas"))) (:= context (canvas.getContext "2d"))) (window.requestAnimationFrame game-loop)) (define (game-loop timestamp) (let* ((seconds-passed (/ (- timestamp timestamp-old) 1000)) (fps (Math.round (/ 1.0 seconds-passed))) ) (:= timestamp-old timestamp) (:= context "fillStyle" "#fff") (context.fillRect 0 0 200 100) (:= context "font" "25px Arial") (:= context "fillStyle" "black") (context.fillText (+ "FPS: " fps) 10 50)) (draw) (window.requestAnimationFrame game-loop)) (define (draw) (:= context "fillStyle" (if (< 0.5 (Math.random)) "#ff8080" "#0099b0")) (context.fillRect 0 100 256 256)) (init) )) (define (generate-html) @~a{ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Game Test</title> </head> <body> <h1>Game Test</h1> <p>Instructions could go here...</p> <p><canvas id="the-canvas" width="640" height="480" tabindex="1"/></p> <script>@file->string{game-test.js}</script> </body> </html>}) (require net/sendurl) (send-url/contents (generate-html))
The "Invaders" example has a Big-Bang style game loop, but I had already started trying to implement this with Javathcript and figured I'd carry it on here.