First program

spork-lang 0.6.0

Run a single Spork file using persistent collections, Python interop, matching, annotations, and a macro.

Save this complete program as first.spork:

(ns examples.readme
  (:require [std.json :as j])
  (:import [os]))

;; Vectors
(def v [1 2 3])
(def v2 (conj v 4))
(print v)  ; [1 2 3] - original is unchanged
(print v2) ; [1 2 3 4] - new structure sharing memory with old

;; Maps
(def m {:name "Spork" :version 1})
(def m2 (assoc m :version 2))
(print m)  ; {:name "Spork", :version 1}
(print m2) ; {:name "Spork", :version 2}

;; Sets
(def s #{1 2 3})
(contains? s 2) ; true

; create new subset of s without 2
(def s2 (disj s 2))
(print s)  ; #{1 2 3}
(print s2) ; #{1 3}

;; Method calls (dot syntax)
(def text "hello world")
(text.upper) ; "HELLO WORLD"

;; Attribute access
(print os.name)

;; Mixing Python types (escape hatch)
(def py-list (list [1 2 3])) ; Convert Spork Vector to Python list
(print (fmt "py-list before: {}" py-list))
(py-list.append 4)          ; Mutate it in place

(print (fmt "py-list after: {}" py-list))

;; Make a map to print as JSON
(def data {:name "Spork" :version 1.0}) ; persistent Spork map
(print (fmt "Json: {}" (j.dumps data))) ; '{"name": "Spork", "version": 1.0}'

(defn describe [x]
  (match x
    0 "zero"
    (^int n) (+ "integer: " (str n))
    [a b] (+ "vector pair: " (str a) ", " (str b))
    {:keys [name]} (+ "Hello " name)
    _ "something else"))

(defn ^int add [^int x ^int y]
  (+ x y))

(defmacro unless [test & body]
  `(if ~test
     nil
     (do ~@body)))

(unless (= (add 1 1) 3)
  (print "Math still works"))

Run it directly without creating a manifest:

spork first.spork

The file requires std.json, manipulates persistent vectors, maps, and sets, creates a mutable Python list at an explicit boundary, and defines both a function using pattern matching and a macro. Continue with the language tour for each form and the project guide when the program grows beyond one file.