diff --git a/README.md b/README.md index 4652288..52720c8 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,37 @@ -# Experimental Lisp compiler +# Valeri: a pure Lisp with algebraic effects -This is a Lisp compiler, that I'm writing to test a few ideas and try to make a language -that I would want to use for personal projects. +This language is created for people to have fun with functional programming, +while not requiring to learn difficult concepts. Because of its dynamism and purity, +this is what you can do: -Note: project is in very early stage. +- Send any object over the network (including function closures) +- Suspend and resume execution at any point in time (and even travel back in time) +- Use any object as a dictionary key -Features that I would like to see (in no particular order): -- small and simple core with focus on correctness/security -- Erlang-style concurrency and message-passing instead of threading/async-await -- per-actor garbage collectors -- native support for immutable data structures -- fast startup -- 64-bit only -- ability to produce small redistributable binaries -- persistence primitives out-of-the-box +Valeri doesn't have classes, and instead relies on passing primitive data structures +around, like dictionaries, arrays, sets, etc. +All IO in the language is implemented by using delimited continuations. -## Rationale +## Getting started -I find that writing something simple in popular programming languages takes an ungodly amount of time. -Mostly because those languages try to cater to a very wide audience. If I have a need to glue a couple -systems together, I need to pull at least a dozen dependencies, and keep them up to date all the time. +There are no packages yet, so you'd need to compile from source. +You'd need `cmake` and either `gcc` or `clang`. To build: -Case in point: one day I needed a simple script that would crawl a github organization, collect -information from there about open pull requests, create a dashboard that presents the information -in the way I want, and occasionally pings people on open issues and pull requests. - -Sounds simple, right? Well, not so fast. You cannot crawl GitHub all the time, because it has request -limits. So you need to run a daemon in background, and update the currently synchronized state. Oh, -so there is state now? How about you store it in a database? And then add migrations to initialize the -schema? - -Don't want to mess with databases? Then you can go the route of just-put-everything-into-a-big-json-file. -Except then you have to turn dates into strings, because JSON doesn't allow custom types. And also, -no integer keys in dictionaries for you. And tuples now turn into arrays, so when you read them back, -the code will treat them differently (because surprise-surprise, arrays cannot be dictionary keys, -while tuples can). - -Frankly, not everything needs a scalable persistence system capable of handling hundreds of thousands -of users. But I would prefer the language to provide something decent that I can just put my data structures -to, and get them back exactly the way I put them. - -Then, the second problem with this particular case is that there are multiple parallel things happening. -At least, one of them is polling the API, and the other sends notifications once a day, and the third -updates the dashboard every now and then. Doing this in Python requires either threads, or async, or -a hand-rolled event loop with a timer. - -For a lot of small apps, I don't care about copying data multiple times. But what I do care about is -never having to deal with data races or inconsistencies. So, in my opinion the Erlang model where -actors are isolated and exchange messages wins hands down. No "function coloring", no shared state, -relative ease of debugging, etc. - -I would even go as far as to say that many of the production apps I worked on in my career could have -_easily_ been done without any shared state. - -So, a language that can take care of such basics and get out of your way would be very nice. Even if -it would be as slow as TCL, it would still be fine for many practical things. - - -## Compiling and running - -You'd need `gcc` and `cmake`. - -At this moment, only a bare minimum of functionality is implemented. - -To run: - -```sh +``` cmake . make +``` + +And then either run the REPL: + +``` +./valeri +``` + +Or run the example: + +``` ./valeri example.vli ``` @@ -78,16 +41,10 @@ To run tests: ctest ``` -## Influences - -- TCL -- Clojure -- Erlang - ## Get in touch -I'm working on this alone at the moment, and don't expect it to turn into anything. But if you like the idea, you can reach out -to me on Matrix: [@knazarov:knazarov.com](https://matrix.to/#/@knazarov:knazarov.com). +- Matrix: [@knazarov:knazarov.com](https://matrix.to/#/@knazarov:knazarov.com). +- Email: mail@knazarov.com ## Acknowledgements diff --git a/example.vli b/example.vli index 99175a4..748cb5f 100644 --- a/example.vli +++ b/example.vli @@ -1,15 +1,7 @@ -;;((fn (f y) (f y)) - ;;(fn (x) (* x x)) - ;;2) - -;;(((fn (x) - ;;(fn () (* x x 2))) - ;;2)) - (fn fact (n) (if (<= n 0) 1 (* n (fact (- n 1))))) -(println "12! =" (fact 12)) \ No newline at end of file +(println "12! =" (fact 12))