3 ms·
If you want to see this principle in action, I’ve been updating Arc for the last five years. If you clone https://github.com/shawwn/sparc https://github.com/sha
by sillysaurusx 3y ago
If you want to see this principle in action, I’ve been updating Arc for the last five years. If you clone https://github.com/shawwn/sparc https://github.com/shawwn/sparc, you should be able to run bin/arc news.arc and see a clone of hacker news running on http://localhost:8080 http://localhost:8080. No need to install anything if you’re on Linux or Mac; it downloads a minimal racket locally. Windows users just need to install racket normally.
I use it as a bookmark aggregator, since I can submit things and leave myself notes. The first account you create will become an admin, and any future accounts are regular users. Passwords are bcrypted rather than sha1’d. Windows works too, but for some reason the repl seems to block all other threads from making progress, so Microsoft users will have to run it with DEV=0 to disable the news.arc repl on startup.
It’s not ready to show yet in general, but there are a lot of advances. My design goal is that if pg ever sees it, he’d want to use it himself.
It incorporates some ideas from Bel, too. I’ll be doing a big write up of all the changes.
The biggest advance from a language standpoint is probably keyword arguments. If there’s any interest, I’ll go into more detail.
The biggest advance from a usability standpoint is that arc is now a thin wrapper over racket. There’s no FFI and no need to translate anything. Arc lists are racket lists. Ditto for hash tables and everything else. You can write racket code in arc by prefixing code #'(like this), which the arc compiler turns into a racket expression (like this). So #'(require (rename-in racket/system [system racket-system])) will do what you’d expect it to do in racket. You can mix racket code and arc in two ways: (#'foo bar baz) will compile bar and baz as arc expressions, but will call foo in functional position. So (#'begin0 (+ "x" 'y) 'z) will give "xy", because begin0 is a racket special form that returns its leftmost expression.
The other way is an equivalent of quasiquoting: #`(let ((x #,(obj a: 1))) x) will return a hash table with ‘a set to 1.
The unit tests in test.arc are probably the best way to see all the language features, but it’s hard to read at times. (The writeup will introduce each concept in a bel-like fashion, but it’s not ready yet.)
news.arc is where most of the power is on display. Making a new endpoint is extremely easy. And prompt.arc shows how you can write a dynamic application without using databases or needing to store any state. The state is in the closures.
- sillysaurusx 3y agoSpeaking of closures, remember how HN used to run out of RAM because each page refresh would create new ones? That doesn't happen here, because no new closure is created if both the lexical environment and the compiled code are identical. The number of fns are displayed at the bottom when you're logged in as an admin, so you can verify nothing new is created when you refresh. Dan has a good writeup about why HN got rid of them, but unfortunately I can't seem to find it. There are still reasons to avoid them (e.g. if you need a stable url), but I'm happy that performance is no longer one of them.