General line of investigation: find ways to compile Scheme or Elixir to RISC Zero programs with reasonable performance
Investigation 1 (inactive)
Compile Chicken Scheme to C for execution in RISC Zero
- Steps:
- Modify the Chicken Scheme compiler source code and compile it with RISC Zero toolchain to obtain static libraries for riscv32m architecture
- Write functions in Scheme and use Chicken Scheme compiler to compile them into C
- Create RISC Zero project that links in the above static library and has a Rust entry point that calls the C code (produced by calling Chicken Scheme compiler)
- Outcomes:
- The approach works and resource logics could theoretically be written in Chicken Scheme
- Challenges:
- Performance: 5! written in Scheme takes 80 minutes to prove on RISC Zero, cause is likely the size of the Chicken Scheme runtime (which supports garbage collection, continuations, ā¦)
- The Chicken Scheme runtime has to be slightly patched because the RISC Zero toolchain does not support things like TCP or file access - users donāt have to deal with this though
- The Chicken Scheme API for C code to be able to call Chicken Scheme functions has to be learned - users donāt have to deal with this though
- The Chicken Scheme runtime calls some undefined functions like
sbrk- these have to be identified and defined inside the RISC Zero project
- Possible future steps (none were taken because a different approach was chosen at the end of ideation):
- Try to optimize the process so that 5! takes less time
- Try to simplify each step in the compilation process - maybe certain commands donāt need certain flags?
- Produce highly detailed instructions on how to reproduce this Chicken Scheme compilation process
- Links:
- Minor modifications to Chicken Scheme for RISC Zero: GitHub - anoma/chicken-core
Investigation 2 (inactive)
Make an interpreter for a Scheme-like DSL in Rust, and run the interpreter in RISC Zero
- Steps:
- Define a small Scheme-like DSL (i.e. has macros, limited continuations, first class functions) that would compile nicely to C
- Write an interpreter in Rust for this DSL and run this interpreter inside RISC Zero
- Outcomes:
- Programs written in the Scheme-like DSL work and are much faster than those from invegation 1 (computing 5! takes 3 minutes)
- Challenges:
- Performance: 5! written in Scheme takes 3 minutes to prove on RISC Zero compared to the same code written in C taking 5 seconds
- Links:
- Interpreter of DSL in Rust: GitHub - anoma/l2c: A compiler from a Scheme-like language to C
Investigation 3 (inactive)
Make compiler in Rust to compile from Scheme-like DSL to C for execution on RISC Zero
- Steps:
- Define a small Scheme-like DSL (i.e. has macros, limited continuations, first class functions) that would compile nicely to C
- Write a compiler in Rust from this DSL to C
- Create RISC Zero project that has a Rust entry point that simply calls the above C code (produced by running the above compiler on DSL code)
- Outcomes:
- Programs written in the Scheme-like DSL work and are much faster than those from invegation 2 (computing 5! takes 5 seconds)
- Challenges:
- This approach only works if the DSL remains similar enough to C to allow a direct translation to C (without additional runtimes)
- Unfamiliarity: the language is neither Scheme nor is it C, so people would have to learn the limitations/features that are unique to the language
- Notes:
- This was the chosen approach, hence investigation 1 ceased
- Links:
- Compiler from DSL to C: GitHub - anoma/l2c: A compiler from a Scheme-like language to C
Investigation 4 (the formally chosen approach, active):
Embed Scheme-like DSL inside Elixir and use compiler written in Elixir to compile to C
- Steps:
- Make the minimum necessary number of modifications to @Jamās Scheme-DSL to enable it to compile nicely to C (move from dynamic to lexical scoping, ā¦)
- The DSL is essentially S@Jamheme code represented as nested lists of atoms in Elixir
- Write compiler in Elixir that takes the DSL (i.e. nested lists of atoms) and converts it to C
- Outcomes:
- Programs written in this Scheme-DSL successfully compile to C code that can be used inside RISC Zero (with speeds exactly the same as investigation 3)
- Challenges:
- Many layers: Elixir code compiles to Scheme-like DSL which compiles to C which then compiles to RISC Zero
- This approach only works if the DSL remains similar enough to C to allow a direct translation to C (without additional runtimes)
- Unfamiliarity: the language is neither Scheme nor is it C, so people would have to learn the limitations/features that are unique to the language
- Future steps:
- Fully read the demos using Common Lisp to write resource logics to fully understand the current vision for this work
- Provide functions that might be useful in writing resource logics
- Links:
- RISC Zero project using compiler outputs: GitHub - anoma/risc0-scheme: Scheme-like DSL inside RISC Zero
- Compiler implementation: Jam+murisi/feature/elixir resource machine by murisi Ā· Pull Request #35 Ā· anoma/anoma-local-domain Ā· GitHub
- Compiler implementation: Jam+murisi/feature/elixir resource machine+further experiments2 by murisi Ā· Pull Request #38 Ā· anoma/anoma-local-domain Ā· GitHub
Investigation 5 (requested experimental approach, active)
Compile one of the Elixir compilerās intermediate representations to something that runs on RISC Zero
- Steps:
- Figure out which of the Elixir compilerās intermediate representations translate most nicely to C, C++, Rust, or RV32M assembly
- For expediency, I chose to compile BEAM bytecode to C because this pair looked the most similar
- Only the single-threaded subset of BEAM bytecode would be supported - no message passing, actors, spawning, ā¦
- Hand translated some BEAM bytecode to C to increase confidence that this approach could work
- Currently writing a compiler to automate this translation, almost covered enough BEAM bytecode instructions to test some simple Elixir functions (like factorial)
- Outcomes: none yet
- Benefits:
- No new language would need to be invented, since we are kind of giving Elixir an alternative backend
- Challenges:
- BEAM bytecode doesnāt seem to be well documented - but thereās usually some resource on the internet or the BEAM source code itself to understand semantics
- BEAM bytecode is slightly lower level than C and can explicitly create/destroy stack frames and refer to return addresses, this does not convert nicely to C - but this challenge can sometimes be sidestepped
- Exactly specifying the exact subset of Elixir that would be supported by the subset of BEAM bytecode that we would support
- Future steps:
- Hopefully produce a demo in a few days so that stakeholders can determine whether this is a direction they would prefer
- Links:
- None yet, should have something in a few days