Otium

Otium

Welcome to Otium! Otium is a little Lisp with a focus on pragmatism, live reloading and being reasonably performant.

These docs

These docs (and Otium) are partly generated by LLMs. Parts that are written partly or wholly by an LLM are marked with ✨ in the title, the rest are written by me. Have fun and be safe!

About the language & runtime

  • Most directly descended from Scheme, but takes some ideas from Clojure, Janet, Common Lisp in terms of practicality.
  • Runtime is intended to be suitable for multi-MB memory embedded systems e.g. ESP32, RP2350 devices.
  • “Good, not great” performance. It has a modest optimizing native-code compiler backed by sljit.
  • Aims to be solid on memory usage. It uses an Immix-inspired non-generational garbage collector which has a separate and tuned profile for low memory systems.
  • Live development is a first class citizen with a dev server that allows querying and modifying running programs.
  • Has a CLOS-lite style object system primarily to support rich user interfaces.
  • Built-in actor-style concurrency. This runs on a single native thread; the goal is more about making it easy to express rich UIs and programs that don’t get blocked by IO vs. highly parallel performance.

A little taste

The main goal of Otium is being able to modify running applications, so let’s make a little UI application and then change something about it. This guy just renders a solid colored rectangle, and we’ll make it so that clicking changes the rectangle’s color.

(require
  (otium.ui :as ui)
  (otium.gfx :as gfx))

;; Create a running window
(def window
  (ui/open {:width 640 :height 480 :title "My cool application"}))

;; Make a Rectangle widget which renders a colored box
(defclass Rectangle
  :is ui/Widget
  (color :init 0xff0000ff :state #t))

;; Define necessary UI methods
(defmethod (ui/measure (r Rectangle) limits) (ui/size 640 480))
(defmethod (ui/paint (r Rectangle) g bounds) (gfx/rect g bounds (r :color)))

;; Put the rectangle onto the screen
(ui/set-view! window (fn () (ui/new Rectangle {})))

;; Run the graphical application and close when user exits
(unwind-protect
  (ui/run)
  (ui/close! window))

You can follow along at home by putting this into a file (or using the one in the repository) and running it with the development server enabled:

./otium –dev examples/hand/intro-ui.ot

Once that’s done, we can make a snippet that adds our background-changing functionality:

;; Table mapping current color to next color
(def next-color
  {0xff0000ff 0x00ff00ff
   0x00ff00ff 0x0000ffff
   0x0000ffff 0xff0000ff})

;; When user clicks, cycle through colors
(defmethod (ui/handle-event (r Rectangle) event)
  (case (get event :kind)
    ((:pointer-down :pointer-up) :handled)
    ((:press)
     (set! (r :color) (get next-color (r :color) 0xff0000ff))
     :handled)
    (else nil)))

And load it into the running application to make the rectangle clickable:

tools/otium-dev eval –file examples/hand/intro-ui-mod.ot

What’s next

Type to search docs and reference.