Language Showcase: Lux
Lux is a purely-functional and statically-typed lisp that pushes the boundaries of what's possible in terms of meta-programming.
In this post of Compiler Spotlight, Eduardo Julian, Lux’s creator, walks us through the unique language he’s been building.
How would you describe Lux to the average programmer?
Lux is a purely-functional and statically-typed lisp that pushes the boundaries of what's possible in terms of meta-programming.
A secondary aspect of Lux is that it's meant to be (as closely as it can be) an omni-platform language that you can use to build software for very different projects with very different circumstances, by leveraging the multitude of available platforms (currently the JVM, JavaScript, Python, Ruby and Lua).
What problems is Lux trying to solve?
Honestly, mostly just problems that I've felt I've had. 😅
I wanted to make a typed lisp because I wanted Clojure to have types and core.typed just wasn't doing it for me.
I wanted to make Lux crazy extensible and customizable because I wanted to know that no matter what software development I wanted to do in the future, I could always bend the language to my will, and I wanted to give other people the same freedom.
And I wanted Lux to compile to anything because of a bad experience I had years ago working on a little game, and feeling frustrated that I couldn't compile Clojure to ActionScript in order to run my game on Flash.
What makes Lux unique?
There are so many answers to that question, but I'll try to focus on the most outstanding stuff.
Types are first-class values and they're just data-structures, so you can introspect then and compute with them at will (though most of the useful stuff you might want to do with them will likely happen at compile-time).
Macros have access to the state of the compiler, which gives you more power and flexibility than macros in other lisps.
And not only can you write macros to manipulate the syntax of Lux, but you can also write extensions for the compiler with regards to semantic analysis (and type-checking) of code, optimizations and even code-generation. These extensions are a bit more complex than macros, but not too much, and you can do with them stuff that even macros cannot accomplish.
There's even an (experimental) meta-compiler architecture that I introduced (and plan to use heavily in the future), that allows creating your own compiler sitting alongside the Lux compiler, and would even let you create polyglot programs from within Lux. It's still very early stage, and I haven't done anything useful with it yet, but I plan on building something important on top in an upcoming release (though I'm keeping what it is a secret for now 😉).
What's the coolest thing that's been built with Lux so far?
Publicly, the Lux compiler itself, and the Lux build tool.
Privately, I'm working on a project for doing financial analysis and it's being written in Lux. But it's closed-source and commercial, so I can't disclose more.
What are some of the toughest challenges with building Lux?
Prioritizing stuff.
I've had crazy cool ideas sitting on a TO-DO list for years because of higher priority stuff that I needed to do.
It kills me to pick winners and losers in terms of what gets scheduled for an upcoming release. There is just so much stuff that I want to do! 🤩
But most of the heavy-duty stuff that I had pending has now been done, and I feel like the next few iterations are going to grant me the peace of mind I have yearned for the last few years.
So, what’s next?
More platforms!
In particular, I'm hoping to compile to C/C++ in the future; and maybe Perl, PHP, Common Lisp and a few other platforms. WebAssembly is definitely on the hit-list.
A friend of mine also gave me an idea that might help me finally get a juicy niche for Lux to live in, but I'm keeping that a secret for now. 😁
Where can people learn more?
They should check out Lux's repo
There's also the book
And they can also check out the talk I gave at Strange Loop years ago (though it's a bit dated):
Which language would you say yours is closest to?
That's a tough question to answer. Can I split it half-way? 😅
Clojure would definitely be the mother, giving Lux syntax and a lispy orientation towards meta-programming.
Haskell would be the father, instilling a purely functional work ethic and proper mathematical values.
Program comparison: arithmetic
Prompt: Implement a program which takes in a single string from stdin containing a basic arithmetic expression, such as “1 + 2 - 5”, evaluate it, and print the result.
Showing off more code: extensions
Arithmetical operations are defined on a per-type basis. Here, we'll define a "universal" way of adding numbers that works on the default numerical types in Lux, so long as the types of all the parameters line up.