Skip to content

Hello! 👋 My name is Nathan Weir. This is a fun personal project for using AI to build a bespoke, domain-specific programming language. It is not a serious, professional project. This site and the language itself are largely generated via Claude Code. If you find yourself programming with Weir, have fun - but use at your own risk!

I/O

Weir provides built-in functions for console output, file I/O, terminal control, and timing.

Prints a value followed by a newline. Accepts zero or one argument:

(println "Hello, World!") ;; prints: Hello, World!\n
(println 42) ;; prints: 42\n
(println) ;; prints a blank line

Prints a value without a trailing newline:

(print "Enter name: ") ;; prints: Enter name: (no newline)
(print 42) ;; prints: 42

Not strictly I/O, but commonly used with it — concatenates values into a string:

(println (str "Score: " score " / " total))

Reads the entire contents of a file as a string:

(defn load-config () : String
(read-file "config.txt"))
(let ((data (read-file "level.dat")))
(println (str "Loaded " (string-length data) " bytes")))
ParameterTypeDescription
pathStringFile path to read
ReturnsStringFile contents

Writes a string to a file (creates or overwrites):

(write-file "output.txt" "Hello, file!")
(write-file "scores.txt" (str "High score: " high-score))
ParameterTypeDescription
pathStringFile path to write
contentsStringString to write
ReturnsUnit

For building terminal-based applications (e.g., the terminal Tetris demo):

Puts the terminal into raw mode — keypresses are delivered immediately without waiting for Enter:

(term-init)

Restores the terminal to its normal (cooked) mode. Always call this before exiting to avoid leaving the terminal in a broken state:

(term-restore)

Reads a single keypress and returns the key code as an integer:

(let ((key (read-key)))
(cond
((= key 27) (quit)) ;; ESC
((= key 119) (move-up)) ;; 'w'
((= key 115) (move-down)) ;; 's'
(else (ignore))))

Requires term-init to have been called. Blocks until a key is pressed.

Returns the current time in milliseconds (monotonic clock):

(let ((start (time-ms)))
(do-expensive-work)
(println (str "Took " (- (time-ms) start) "ms")))

Pauses execution for the given number of milliseconds:

(sleep 16) ;; ~60 FPS frame delay
(sleep 1000) ;; 1 second
FunctionSignatureDescription
println(Fn ['a] Unit)Print value + newline
print(Fn ['a] Unit)Print value (no newline)
read-file(Fn [String] String)Read entire file
write-file(Fn [String String] Unit)Write string to file
term-init(Fn [] Unit)Enter raw terminal mode
term-restore(Fn [] Unit)Restore normal terminal mode
read-key(Fn [] i64)Read single keypress
time-ms(Fn [] i64)Current time in milliseconds
sleep(Fn [i64] Unit)Sleep for N milliseconds