vers.h
Here is a small truth hidden in a tiny file: in PicoLisp, the version number is a date. In the old C sources the whole of it was vers.h, one line telling you the day the interpreter was cut. Today it is src/vers.l, and the idea hasn’t changed.
What it is, in plain words
In pil32 (the C implementation, studied here in 2017) vers.h declared one array:
static byte Version[4] = {17,6,13};
That is three numbers: year, month, day. {17,6,13} means 13 June 2017; the fourth slot is spare. byte is defined in pico.h as typedef unsigned char byte;. The file was generated by the mkVers script.
In pil21, the current PicoLisp, the same idea lives in src/vers.l. This is the whole file in 26.9:
# 25sep26 Software Lab. Alexander Burger
(symbols '(llvm))
(local) *Version
(pico~de *Version 26 9 25)
It is the same date format, now as Lisp, and it uses the namespace syntax: pico~de means “the de from the pico namespace”, because the file is read inside the llvm compiler namespace.
Release numbers are the year and month: PicoLisp releases come out quarterly as YY.3, YY.6, YY.9 and YY.12, so 26.9 is September 2026. The rolling pil21.tgz on software-lab.de carries the exact day, like 26.9.25, while distribution packages carry the release (picolisp 26.9 in Debian unstable, for example, or older ones like 25.3 in Debian 13).
Why it matters
- Debugging. When you ask on the mailing list or IRC why something behaves oddly, the first answer is “which version?” A date tells you exactly which source tree you have, and which ChangeLog entries apply to it.
- Compatibility. Code written for pil32 and pil21 differs in places, for example the
nativecall interface, namespaces, and removed functions. Knowing your version tells you which manual to read. - Simplicity as a design value. Most projects need a build system plugin to generate a version string. PicoLisp needs one line. That is the PicoLisp attitude in miniature.
An everyday analogy: a “baked on” stamp
A loaf of bread from a good bakery has a date on it, not a marketing number. You know immediately how fresh it is and which batch it came from. The version is that stamp. “Version 3.1.7” tells you little; “26.9.25” tells you it was baked on 25 September 2026.
A hands-on example
Ask the running interpreter, from the shell or the REPL (tested on 26.9):
$ pil -version -bye
26.9.25
: (version) # prints and returns the list
26.9.25
-> (26 9 25)
: (version T) # just return it, no printing
-> (26 9 25)
Because it returns a list, you can test it in code, for example to refuse to run on an interpreter that is too old:
(unless (>= (version T) (24 6 1))
(quit "Need PicoLisp 24.6 or newer") )
PicoLisp compares lists element by element, so (26 9 25) is greater than (24 6 1). Dates sort naturally, which is another quiet benefit of the format.
I used to keep a tiny shell script that prints the versions of the tools I depend on, so I can paste them into notes or bug reports:
#!/bin/sh
uname -sr
pil -version -bye
clang --version | head -1
emacs --version | head -1
To see what changed between versions, read doc/ChangeLog in the tarball, or the online copy. It is ordered by these same dates.
Common misconceptions
- “The date is the day I installed it.” It is the day the source was released, not your install or build date.
- “A new number means a rewrite.” No. The format just tracks dates; most releases are small fixes and additions.
- "
vers.h/vers.lconfigures the build." It configures nothing. It is purely informational.
Connections
- PicoLisp, The PicoLisp Machine, PicoLisp Sources, mkVers.
- C Programming, Identifiers and Literals, for reading the C line above with confidence.
- new and box: more built-ins worth reading in the source.
