Skip to content

Commit 62a3cd9

Browse files
committed
blog: Add 2025-07-24.md
1 parent 28344ed commit 62a3cd9

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

blog/2025-07-24.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
---
2+
title: Why YS Chose Clojure
3+
date: 2025-07-24
4+
draft: false
5+
authors: [ingydotnet]
6+
categories: [Summer-of-YS]
7+
edit: blog/2025-07-24.md
8+
comments: true
9+
---
10+
11+
12+
So YS compiles to Clojure.
13+
14+
It also has a Clojure runtime and access to the Clojure ecosystem.
15+
16+
It's also written in Clojure. (It didn't have to be. The compiler could have
17+
been written in any language.)
18+
19+
Why Clojure?
20+
21+
I'll explore that topic today.
22+
23+
<!-- more -->
24+
25+
26+
## Do I have a Lisp?
27+
28+
I thought of YS as a concept in mid 2022, but didn't go far with it.
29+
One thing that I decided (possibly years earlier) was it should be a Lisp.
30+
A Lisp in the sense that Lisp is code as data.
31+
Since YAML is a data language, it felt like code in YAML was code as data, which
32+
pretty much is the definition of Lisp.
33+
34+
But...
35+
36+
I didn't really know what a Lisp was or how to make one.
37+
I knew that a Lisp expression was parens around a function and arguments.
38+
That's about it.
39+
40+
```lisp
41+
(print (join "2 + 2 = " (+ 2 2)))
42+
```
43+
44+
Something like that.
45+
46+
47+
## How to Make A Lisp
48+
49+
I said "I didn't know how to _make_ a Lisp" on purpose.
50+
51+
In early 2023 I googled "how to make a Lisp" and found this amazing project
52+
called [mal](https://github.com/kanaka/mal) (Make A Lisp).
53+
It's a complete 11 step tutorial on how to implement a rudimentary Lisp in any
54+
language you want to.
55+
Each of the 11 steps has a test suite that you need to get to pass before moving
56+
on to the next step.
57+
Last I counted, there were over 100 implementations in over 75 languages!
58+
59+
It took me 2 weeks to implement a Lisp in Perl.
60+
The "mal" Lisp is Clojure inspired.
61+
The final step is to use your mal to run (self-host) a mal implementation
62+
written in mal and have it pass all the tests!
63+
It still blows my mind a bit to think about it.
64+
65+
When I was done, I decided to see what the mal Lisp would look like in YAML.
66+
It looked awful!
67+
But I kept playing with it and it kept getting better.
68+
Soon I was pretty sure that YS could be a language that I would actually like
69+
programming in.
70+
71+
That said, it would still be a lot of work.
72+
73+
74+
## The Holy Graal(VM)
75+
76+
I decided not to stop working on my Perl mal/Clojure Lisp, and to see how far I
77+
could get with making a Clojure hosted on Perl.
78+
I called the project Lingy.
79+
80+
I was attending a Perl conference in Toronto in July 2023 and decided to give
81+
a talk called "Lingy and YAMLScript".
82+
83+
Somehow this talk got noticed by the Clojure community and I was invited to join
84+
their Slack.
85+
I met the right people and soon learned about [GraalVM](
86+
https://www.graalvm.org/) and [SCI](https://github.com/babashka/sci).
87+
88+
SCI is a Clojure runtime and GraalVM's `native-image` tool can be used to
89+
compile jar files (what Clojure compiles to) to native executables.
90+
With these 2 things I realized that I could make YS be a real language in a
91+
matter of months, rather than years.
92+
To a large degree, I was right.
93+
I had a usable language by the end of 2023.
94+
95+
When I realized that I could make YS a real language, I was fully committed from
96+
that point on.
97+
I've been working on YS ever since.
98+
99+
Of course, programming languages are never finished, and there's more to do than
100+
ever to have all the YS tooling and ecosystem in place for the best possible YS
101+
user experience.
102+
103+
104+
## Shared Libraries
105+
106+
Maybe more important than GraalVM compiling YS to a native executable is its
107+
ability to also compile YS to a shared library: `libys.so`.
108+
109+
With that, I knew I could make a YS capable YAML loader for almost every common
110+
programming language.
111+
In fact, without the shared library realization, I probably wouldn't have
112+
started working on YS in earnest.
113+
114+
I think we had 5 or 6 YAML loaders by the end of 2023.
115+
Today we have 15.
116+
The goal has always been (at least) 42!
117+
118+
!!! note
119+
120+
I literally have a list of 45 FFI capable programming languages that also
121+
have library registries.
122+
So I know we can do this.
123+
124+
The amount of code for a typical libys binding is about 100-200 lines of code.
125+
It involves FFI stuff, but with the help of LLMs these days, it only takes me a
126+
day or two to release a new language binding.
127+
128+
More often than not, learning how to use a new publishing registry is the hard
129+
part.
130+
131+
132+
## What's Good About Clojure?
133+
134+
Probably the best things about Clojure is that it has a great core library and
135+
a great ecosystem.
136+
137+
If you want to make a new programming language these days, you really need to be
138+
building on the ecosystems of giants.
139+
140+
Clojure itself was built on top of Java; one of the biggest giants of the
141+
programming language world.
142+
From all I've read, that was very much on purpose.
143+
144+
Building YS on top of Clojure started with the promise that it would have a
145+
giant, Rich and robust ecosystem from the start.
146+
147+
One other awesome thing about Clojure is its commitment to not breaking code.
148+
It's ridiculously backwards compatible.
149+
I've yet to encounter a single bug introduced by a new version of Clojure (or
150+
Java for that matter).
151+
152+
153+
## What's the Problem with Clojure?
154+
155+
From a YS perspective, the biggest problem with Clojure is that people assume
156+
it needs a JVM or Java knowledge to use it well.
157+
That's just not true.
158+
159+
The `ys` command line interpreter is just a single standard binary executable.
160+
161+
You don't even need to know Clojure to be able to get value from YS.
162+
On the other hand, to be a great YS programmer, you do need to know quite a bit
163+
about it.
164+
165+
I'll say personally that I think Clojure is a great language to learn.
166+
Especially if you don't already know a Lisp.
167+
Learning Lisp should be a requirement for anyone who wants to be a well rounded
168+
programmer, and Clojure is a great modern Lisp.
169+
170+
171+
## What's the Problem with GraalVM?
172+
173+
Maybe my biggest current misgivings around YS and Clojure is that the GraalVM
174+
compiler:
175+
176+
* Is very slow to compile things (over a minute)
177+
* Only supports Windows, Linux and macOS
178+
* Creates large binaries
179+
180+
These aren't deal breakers, but they keep me thinking about other options.
181+
182+
One option that I haven't done much with yet is simply using the JVM.
183+
Once a JVM is started, it's very fast.
184+
Faster than the native compilations.
185+
The native compilations just _start_ very fast.
186+
Alas, the JVM solution doesn't really fit the shared library binding model.
187+
188+
Another option is to explore Clojure hosted by other languages.
189+
ClojureScript is a great example of this.
190+
It runs on the web and NodeJS.
191+
192+
I'm even more interested in exploring Clojure hosted on Go or Rust.
193+
There are a few projects out there already playing with this.
194+
195+
There's also the promise of being able to compile Clojure to WebAssembly.
196+
It's gonna be ready any day now.
197+
Or so I've been told.
198+
(More than once. ;)
199+
200+
I hope so, because I think it would be a very big deal for YS.
201+
202+
203+
## Conclusion
204+
205+
I'm quite happy with the choice of Clojure for YS.
206+
I think it's a sound foundation.
207+
It's like a Lego set that you can use out of the box and also build new domain
208+
specific Lego sets with.
209+
210+
It also has the potential to reach beyond the JVM and NodeJS to new exciting
211+
platforms.
212+
213+
YS effectively lets you use Clojure in YAML with a more YAML appropriate syntax,
214+
taking it places it may never have gotten to otherwise.

0 commit comments

Comments
 (0)