Update README.md for brevity
This commit is contained in:
parent
0ce71beb62
commit
74094491f6
2 changed files with 28 additions and 79 deletions
97
README.md
97
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
|
||||
|
||||
|
|
10
example.vli
10
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))
|
||||
(println "12! =" (fact 12))
|
||||
|
|
Loading…
Reference in a new issue