100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Your First LISP Program

Write, save, and run a complete Common Lisp program: defining functions with defun, printing output, and loading a source file.

FoundationsBeginner9 min readJul 10, 2026
Analogies

Your First LISP Program

So far you have been typing expressions directly into the REPL, one at a time. Real programs are saved into files, usually with a .lisp extension, so they can be loaded, shared, and rerun without retyping everything. This lesson brings together defun for defining a named function, format for printing readable output, and the load process for running a complete file, so you can go from isolated REPL experiments to a finished, saved LISP program.

🏏

Cricket analogy: Moving from typing one-off expressions at the REPL to saving a complete .lisp file is like a batsman graduating from solo net practice to walking out and building a full innings in a real match: the same shots, now assembled into something complete and repeatable.

Defining a Function with DEFUN

The defun special form defines a named, reusable function: (defun name (parameters) body). Once defined, that name can be called anywhere else in your program the same way built-in functions like + or format are called. LISP functions do not need an explicit return statement; the value of the last expression evaluated in the body is automatically returned, so a function that ends with (* x x) returns whatever that multiplication produces.

🏏

Cricket analogy: Defining a named run-rate formula once is like a coach codifying a fixed formula for calculating strike rate: once written, every player and analyst can call the same named function instead of recalculating the formula from scratch each time.

lisp
(defun greet (name)
  (format t "Hello, ~a!~%" name))

(greet "Ada")     ; prints: Hello, Ada!

;; The last expression's value is returned automatically
(defun square (x)
  (* x x))         ; no explicit "return" keyword needed

(square 6)         ; => 36

Printing and Basic I/O

The format function is the standard way to produce output, driven by a control string containing directives: ~a prints any value in a general, human-readable form, ~d prints an integer in decimal, and ~% inserts a newline. A single format call can combine several directives and arguments in one line, which makes it far more flexible than print, a simpler function that writes a value in machine-readable form with a leading newline, mainly useful for quick debugging output.

🏏

Cricket analogy: The general-purpose directive in format printing any value in a readable form, like a player's name or their strike rate, is like a stadium's scoreboard display that can show either a name or a number in the same readable slot without needing separate display modes.

lisp
;; ~a prints any value in a human-readable ("aesthetic") form
(format t "Player: ~a~%" "Virat Kohli")   ; Player: Virat Kohli

;; ~d prints integers
(format t "Runs: ~d~%" 82)                ; Runs: 82

;; Multiple directives combine in one format string
(format t "~a scored ~d runs off ~d balls.~%" "Kohli" 82 53)
;; => Kohli scored 82 runs off 53 balls.

;; print, in contrast, writes a value with a leading newline
;; and re-readable (write) syntax, useful for debugging
(print "debug value")

Loading and Running Your File

Once your code is saved in a file, you have three common ways to run it: call the load function from an already-running REPL, giving it your filename as a string argument, to bring its definitions into that session; run sbcl --script followed by your filename from the terminal to execute the whole file non-interactively and exit; or run sbcl --load followed by your filename to execute the file and then drop you into an interactive REPL for further testing. This file-based workflow is the natural next step once you have proven out individual pieces at the REPL.

🏏

Cricket analogy: Running a saved script that executes a whole file at once is like a team chasing a set target with a pre-agreed batting order and powerplay plan already locked in, rather than deciding the approach shot by shot the way a solo net session allows.

lisp
;; From the REPL, load a saved file:
(load "hello.lisp")

;; From the terminal, run a file as a script:
;; sbcl --script hello.lisp

;; Or load a file and then drop into an interactive REPL:
;; sbcl --load hello.lisp

Quick format directive reference: ~a prints any value in human-readable form; ~s prints a value in machine-readable, re-readable form, quoting strings; ~d prints an integer in decimal; ~% inserts a newline, and using it multiple times inserts multiple newlines. These directives are the most common ones you'll use for everyday output.

  • defun defines a named, reusable function: (defun name (parameters) body).
  • A LISP function automatically returns the value of its last evaluated expression; no explicit return keyword is needed.
  • format t is the standard way to print output, using directives like ~a (any value), ~d (decimal integer), and ~% (newline).
  • print writes a value in a machine-readable form with a leading newline, useful for quick debugging.
  • Save your code in a file with a .lisp extension so it can be loaded or run repeatedly instead of retyped.
  • Use the load function from the REPL, or run sbcl --script followed by your file's name from the terminal, to run a complete program.
  • Moving from ad hoc REPL experiments to a saved, loadable file is the natural progression to writing real LISP programs.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#LISPStudyNotes#YourFirstLISPProgram#LISP#Program#Defining#Function#StudyNotes#SkillVeris#ExamPrep