X-Date: 2024-09-01T23:26:26Z X-Note-Id: b5ba6437-5fe2-4d01-8dc5-3efe8587e728 Subject: Valeri REPL became actually useful (and keeps state) X-Slug: valeri_repl_became_useful [Valeri](https://git.knazarov.com/knazarov/valeri) REPL has progressed to a state where it can run multiple sequential statements that can refer to each other's variable and function bindings. A few examples: ``` valeri> (fn square (x) (* x x)) # valeri> (square 5) 25 valeri> (def four 4) 4 valeri> (fn add-four (x) (+ x four)) # valeri> (add-four 5) 9 ``` And in addition to supporting primitive arithmetics, it also got support for arrays and dicts: ``` valeri> (def a [1 2 (+ 3 4)]) [1 2 7] valeri> (get a 2) 7 (def d {"foo" 123 "bar" 456}) {"bar" 456 "foo" 123} valeri> (get d "bar") 456 ``` Of course all of this is available when you run scripts from a file as well, like `./valeri example.vli`. Compared to what I had just a week ago, this is a lot of progress. Previous version of the REPL could only compile one-shot operations that didn't share any state with each other, and as such the usefulness was very limited. The standard library is very tiny at the moment, and this means that you can't write bigger programs. For example, there is no `map`, `fold`, pipelining (or "threading"), reductions and other higher-order constructs. Because Valeri is "pure" as opposed to Scheme, Common Lisp and Clojure which all offer mutation, writing more complex programs will be tedious. But before jumping into adding functionality to the standard library, I'd like to tackle two more things: - Macros, as in other regular Lisps - Effects, for proper I/O and interactions between processes The lack of macros in particular stands in the way of the standard library, because many useful constructs have to be either implemented through them or be supported directly by the compiler. And I don't want to bloat the compiler too much. Effects are needed to build gradually more and more complex applications (like text filtering or a web server). At this moment, the only available effect is `println` which is implemented as a hack. The real implementation will utilize ideas similar to [Roc language](https://www.roc-lang.org/), where any I/O yields a continuation. But for now, I'm quite pleased with the results.