From 7898e4d4f955d36e7bfda5849da5f12161ee1b17 Mon Sep 17 00:00:00 2001 From: Ohad Rau Date: Wed, 4 Apr 2018 22:37:24 -0400 Subject: [PATCH] Start listing out ideas for different parts of the Quartz system --- IDEAS.md | 3 ++ vm/IDEAS.md | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 IDEAS.md create mode 100644 vm/IDEAS.md diff --git a/IDEAS.md b/IDEAS.md new file mode 100644 index 0000000..975ad6f --- /dev/null +++ b/IDEAS.md @@ -0,0 +1,3 @@ +* ML-style module system +* Sum, product types +* `&` operator to run in parallel diff --git a/vm/IDEAS.md b/vm/IDEAS.md new file mode 100644 index 0000000..7b2a542 --- /dev/null +++ b/vm/IDEAS.md @@ -0,0 +1,117 @@ +The Quartz VM: +------------- + +* Probably needs some fancy rock-related name (SiO2, Silicon/Silica, Oxygen, Mineral, Amethyst) +* Exceptions are first-class +* Concurrency/parallelism are first-class +* Message passing is first-class +* Built-in GC +* Stack-based probably +* Doesn't need to be extremely low-level +* Maybe sessions should mimic classes in JVM bytecode + + Top-level export with type signatures +* Somewhat dynamically typed + + When code hops between computers, we need some checks to make sure everything is okay + + E.g. if one server goes AWOL, we need dynamic chceks in place to respond + +## Ideas: + +* OCaml bytecode +* JVM bytecode +* BEAM bytecode + +## Examples: + +``` +session Timer(s) + on Start from s + let now = std::get_time_ms() + on Stop from s + let new = std::get_time_ms() + s!Took(new - now) + end + end +end + +session P(q) + t = spawn Timer(self) + t!Start + q!Ping + on Pong from q + t!Stop + on Took(ms) + std::print(ms) + end + end +end + +session Q(p) + on Ping from p + std::wait(10) + p!Pong + end +end + +fun main() + let p = spawn P(q) + and q = spawn Q(p) +end +``` + +``` +session Timer < exists S. [s : S] -> ?s{Start ~> ?s{Stop ~> !s{Took(int) ~> End}}} >: + # push s + await_msg [0] + cmp $Start _nomatch0 + call_function @std::get_time_ms + await_msg [-1] + cmp $Stop _nomatch0 + pop + call_function @std::get_time_ms + sub + send_msg(1) [-1] $Took + close + + _nomatch0: + close_err "Session Timer received unmatched message from ?S" # Better example would use exceptions + +session P < exists Q. (q : Q) -> [t : Timer] -> !t{Start ~> !q{Ping ~> ?q{Pong ~> !t{Stop ~> ?t{Took(int) ~> End}}}}} >: + # push q + push @self + call_constructor_spawn @Timer # Call and push spawn Timer(self) + send_msg [0] $Start + send_msg [-1] $Ping + await_msg [-1] + cmp $Pong _nomatch0 + send_msg [-1] $Stop + await_msg(1) [-1] # Takes an additional arg (goes argN, ..., arg0, msg) + cmp $Took _nomatch1 + pop + call_function @std::print + close + + _nomatch0: + close_err "Session P received unmatched message from Q" # Better example would use exceptions + + _nomatch1: + close_err "Session P received unmatched message from Timer" # Better example would use exceptions + +session Q < exists P. (p : P) -> ?p{Ping ~> !p{Pong ~> End}} >: + # push p + await_msg [0] # Await a message from p + cmp $Ping _nomatch0 # Compare last item on stack (the message) to $Ping + push 10 + call_function @std::wait + send_msg [-1] $Pong # Send $Pong to p + close + + _nomatch0: + close_err "Session Q received unmatched message from P" # Better example would use exceptions + +function main < () -> void >: + spawn_empty # Push thread p onto stack + spawn_empty # Push thread q onto stack + call_constructor_async @P [-1] # Takes 1 off the stack (q) and runs on thread p + swap + call_constructor_async @Q [-1] # Takes 1 off the stack (p) and runs on thread q +```