Start working on lunarbox article
This commit is contained in:
parent
d2510af6db
commit
7f55203625
2 changed files with 106 additions and 0 deletions
content/echoes/updating-lunarbox
BIN
content/echoes/updating-lunarbox/factorial.png
Normal file
BIN
content/echoes/updating-lunarbox/factorial.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 97 KiB |
106
content/echoes/updating-lunarbox/index.dj
Normal file
106
content/echoes/updating-lunarbox/index.dj
Normal file
|
@ -0,0 +1,106 @@
|
|||
{ role=config }
|
||||
``` =toml
|
||||
created_at = "2025-06-10 02:10:42+02:00"
|
||||
draft = true
|
||||
```
|
||||
|
||||
::: description
|
||||
My journey updating a half a decade old project of mine to use modern tooling, and some reflection on the evolution of the PureScript ecosystem. The final section is a sort of love letter to PureScript, and everything the language has meant to me.
|
||||
:::
|
||||
|
||||
# Refactoring my moon in a box
|
||||
|
||||
[Lunarbox]: https://github.com/lunarcast/lunarbox
|
||||
[Lunarbox API]: https://github.com/lunarcast/lunarbox-api
|
||||
|
||||
[Lunarbox][] is a functional programming language I build in my spare time around 2020. Waow, it's been half a decade already, I'm getting old, huh? Most of the project was written in [PureScript][], although the [canvas renderer][Lunarbox canvas renderer] has at some point been rewritten to [TypeScript][] for performance reasons. The [API][Lunarbox API] has been built by my friend [BlueGhost][], who also chose to use TypeScript.
|
||||
|
||||
[Lunarbox canvas renderer]: https://github.com/lunarcast/lunarbox/blob/develop/src/typescript/render.ts
|
||||
[PureScript]: https://www.purescript.org/
|
||||
[TypeScript]: https://www.typescriptlang.org/
|
||||
[BlueGhost]: https://github.com/BlueGhostGH/
|
||||
|
||||
{ src="factorial.png" alt="Implementation of the factorial function in Lunarbox" width="75%" }
|
||||
::: image-figure
|
||||
A recursive [factorial][Factorial] implementation in Lunarbox. Try it out [here][Lunarbox factorial].
|
||||
:::
|
||||
|
||||
On [2022-10-28]{ role=date } [Heroku][], a server hosting service commonly recommended to beginners, [removed their free tier][Heroku removed their free tier]. As you might've guessed, Heroku is precisely where Lunarbox (in particular, the aforementioned API) was being hosted. I was just starting university when said date rolled around, so I did very little about it. I asked my friend to back-up the [Postgres][PostgreSQL] database, before swiftly forgetting about the topic.
|
||||
|
||||
Lunarbox' deployment was quite a mess. The front-end required a fair bit of tooling to build, and an (by that time) outdated version of PureScript. Moreover, due to a lack of proper base URL handling (i.e. the project would always assume it lived at the base of an URL' path), Lunarbox' front-end was being hosted on [Netlify][] instead of something like [GitHub pages][] (which I'm a bit more familiar with). To make things worse, the back-end required a full on Postgres database, which made running it locally a bit annoying (I hate having to spin up Postgres databases locally aaaaaaaaaaa).
|
||||
|
||||
The "sane" thing to do might've been to try and set up a [Docker][] container and jump ship to some new hosting service offering a free tier, although that felt (to me) like asking for the cycle to repeat itself once a few years had passed by (ok, having a Docker container would've definitely helped make the process easier, but I don't particularly like Docker, alright?). I had already been planning to start self hosting things for a good while, and a low-risk project like Lunarbox would've surely been the perfect opportunity to do so, rigghttttt?
|
||||
|
||||
Three years have since passed, I'm almost done with my bachelor studies, my personal server's up and running, hosting dozens of services, yet Lunarbox is still dead.
|
||||
|
||||
[Factorial]: https://en.wikipedia.org/wiki/Factorial
|
||||
[Lunarbox factorial]: about:blank
|
||||
[Heroku]: https://www.heroku.com/
|
||||
[Heroku removed their free tier]: https://help.heroku.com/RSBRUH58/removal-of-heroku-free-product-plans-faq
|
||||
[PostgreSQL]: https://www.postgresql.org/
|
||||
[Netlify]: https://www.netlify.com/
|
||||
[GitHub pages]: https://pages.github.com/
|
||||
[Docker]: https://www.docker.com/
|
||||
|
||||
Since I don't have that much professional experience, the people I've previously interviewed for have asked me to show them a personal project of mine. Twice now, Lunarbox is the project I've chosen to show, and something that's impressed both of them. Since I'm (yet again) looking for a summer job, I felt like now was the perfect time to try and get Lunarbox up and running again. In the years since Lunarbox' inception, I've become a super big fan of [Nixos][], so the path forwards was clear. I had to:
|
||||
|
||||
1. Update Lunarbox to modern versions of the tooling involved (the tedious part)
|
||||
2. Get rid of the Postgres dependency, switching to something leaner like [SQLite][] (the annoying part)
|
||||
3. Package up every component using Nix, and write a Nixos module for easy deployment (the fun part)
|
||||
4. Reap the rewards, by deploying Lunarbox to my personal server! (the easy part)
|
||||
|
||||
[Nixos]: https://nixos.org/
|
||||
[SQLite]: https://sqlite.org/
|
||||
|
||||
::: toc
|
||||
:::
|
||||
|
||||
## Running the server
|
||||
|
||||
## Running the front-end
|
||||
|
||||
### Language changes
|
||||
|
||||
### Formless
|
||||
|
||||
### Reflection on the evolution of PureScript
|
||||
|
||||
## Nix packaging
|
||||
|
||||
## Writing a Nixos module
|
||||
|
||||
## Deploying
|
||||
|
||||
## Reflection on Lunarbox
|
||||
|
||||
Before going further, I wanted to take a step back and reflect on Lunarbox as a whole. For one, it introduced me to Functional Programming as a whole, and indirectly helped me land my first two jobs. Lunarbox started as a [fp-ts][] project. At first, I tried implementing type inference off the top of my head. Not only did I try that, I tried doing it directly on the node graph, which made it very strange for me to work on (at the time, at least). Defeated, I looked up some tutorials.
|
||||
|
||||
At first, I came across [a TypeScript implementation][Type inference for beginners] of [Hindley-Milner type inference][]. I haven't read the series since, but I remember it leaving quite a few gaps in my understanding at the time. Looking for more, I then came across another post, this time written in [Haskell][]. I sadly can't seem to find the exact post, but I think it was pretty similar to [this one][Implementing HM in Haskell]. One interesting thing here is the use of the [RWST monad transformer][The RWST monad transformer]. At the time, I (for some reason) thought it would be a good idea to try to do the same in Typescript via the monad transformer support offered by fp-ts ([example][StateT in fp-ts]). Unlike Haskell, TypeScript does not support any sort of typeclasses/traits/etc, which makes working with monad transformers quite painful — the programmer needs to pass around the typeclass dictionaries manually. Moreover, the lack of general do-notation made using monads painful even once they've been constructed. Nevertheless, not knowing what I was doing, I gave up for the time being, and decided to learn a proper functional programming language.
|
||||
|
||||
[fp-ts]: https://gcanti.github.io/fp-ts/
|
||||
[Type inference for beginners]: https://medium.com/@dhruvrajvanshi/type-inference-for-beginners-part-1-3e0a5be98a4b
|
||||
[Hindley-Milner type inference]: https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system
|
||||
[Haskell]: https://www.haskell.org/
|
||||
[Implementing HM in Haskell]: https://blog.stimsina.com/post/implementing-a-hindley-milner-type-system-part-1
|
||||
[The RWST monad transformer]: https://hackage.haskell.org/package/mtl-2.3.1/docs/Control-Monad-RWS-CPS.html#t:RWST
|
||||
[StateT in fp-ts]: https://gcanti.github.io/fp-ts/modules/StateT.ts.html
|
||||
|
||||
My journey started with [Elm][]. To this day, I believe the official Elm tutorial is a great first step into functional programming. I remember building some very basic things (like a basic [TODO app][Elm TODO app]), which made me quickly realise that Elm's architecture was quite limiting. Having since worked with Elm professionally, I can't fathom how true my first impressions were. God, I hate Elm for non-trivial codebases. Performing every single effect via message-passing gets old very quickly, trust me. The values are not the only immutable things when using Elm — so is the codebase given complicated enough interactions between the underlying effects.
|
||||
|
||||
[Elm]: https://elm-lang.org/
|
||||
[Elm TODO app]: https://git.moonythm.dev/prescientmoon/solar-conflux/src/branch/master/elm/todolist
|
||||
|
||||
Nonetheless, I then set my eyes on [F#][]. I remember doing [a few days][Advent of Code 2019 (day 3) in F#] of [Advent of Code][], and even spending a bit of time trying to write a [Yu-Gi-Oh! engine][Unfinished F# Yu-Gi-Oh! engine] (which I of course gave up on pretty quickly, given how gargantuan an undertaking that is). I actually liked F# quite a bit. I think this is the first time I learnt what monads actually were (I think I read about them in some F# library's documentation). I eventually gave up the language after facing some issues with whatever tool I was using for running F# in the browser (I honestly can't remember what said issues were, but oh well).
|
||||
|
||||
[F#]: https://fsharp.org/
|
||||
[Advent of Code]: https://adventofcode.com/
|
||||
[Advent of Code 2019 (day 3) in F#]: https://github.com/prescientmoon/aoc/blob/main/2019/days/3/Program.fs
|
||||
[Unfinished F# Yu-Gi-Oh! engine]: https://git.moonythm.dev/prescientmoon/solar-conflux/src/branch/master/fsharp/ygosim
|
||||
|
||||
Finally, I landed on PureScript. The very same friend who would later end up writing Lunarbox' API told me about Lunarbox' existence a while before, but I think I had ignored it the instant I'd seen the language using [Bower][] as its package manager. Nonetheless, the new and shiny [Spago][] pulled me in. Having taken the slow steps to get there, the language itself felt quite easy to learn (although the ecosystem took me considerably longer to get used to).
|
||||
|
||||
[Bower]: https://bower.io/
|
||||
[Spago]: https://github.com/purescript/spago
|
||||
|
||||
was my first foray into the world of type system programming and type theory as a whole. The
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue