Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tomjschuster/gleam_universal_server
A Gleam implementation of Joe Armstrong's Universal Server
https://github.com/tomjschuster/gleam_universal_server
beam erlang gleam
Last synced: about 1 month ago
JSON representation
A Gleam implementation of Joe Armstrong's Universal Server
- Host: GitHub
- URL: https://github.com/tomjschuster/gleam_universal_server
- Owner: tomjschuster
- Created: 2024-05-09T02:14:15.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2024-05-10T01:17:19.000Z (6 months ago)
- Last Synced: 2024-09-30T03:41:47.391Z (about 2 months ago)
- Topics: beam, erlang, gleam
- Language: Gleam
- Homepage: https://joearms.github.io/published/2013-11-21-My-favorite-erlang-program.html
- Size: 21.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# universal_server
![test workflow](https://github.com/tomjschuster/gleam_universal_server/actions/workflows/test.yml/badge.svg)
A [Gleam](https://gleam.run/) implementation of the "Universal Server" demonstrated by Joe Armstrong in his blog post [My favorite Erlang Program](https://joearms.github.io/published/2013-11-21-My-favorite-erlang-program.html).
```gleam
import gleam/erlang/process.{type Subject}
import gleam/result.{try}
import universal_serverpub fn main() {
use u_subject <- try(universal_server.start(True))
use f_subject <- try(universal_server.become(u_subject, factorial_server))let u_pid = process.subject_owner(u_subject)
let f_pid = process.subject_owner(f_subject)
let assert True = u_pid == f_pidlet assert Ok(120) = compute(f_subject, 5)
let assert Ok(3_628_800) = compute(f_subject, 10)Ok(Nil)
}fn factorial_server(subject: Subject(#(Subject(Int), Int))) {
let #(reply_to, n) =
process.new_selector()
|> process.selecting(subject, fn(m) { m })
|> process.select_forever()process.send(reply_to, factorial(n))
factorial_server(subject)
}fn factorial(n: Int) -> Int {
case n {
0 -> 1
n if n > 0 -> n * factorial(n - 1)
_ -> panic as "cannot calculate negative factorial"
}
}fn compute(subject: Subject(#(Subject(Int), Int)), n: Int) -> Result(Int, Nil) {
let reply_to = process.new_subject()
process.send(subject, #(reply_to, n))
process.receive(reply_to, 5000)
}
```## Development
```sh
gleam test # Run the tests
gleam shell # Run an Erlang shell
```