|
| 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