Schmeep is an Android app that combines:
- R7RS Scheme: embedded Chibi Scheme interpreter
- Bluetooth SPP REPL: Remote Scheme REPL (Read-Eval-Print Loop) via Bluetooth Serial Port Profile. Uses a command-line program for I/O.
- WebView-Only UI: full-screen WebView for user interface
- JavaScript-to-Native Bridge: JavaScript-to-JNI communication for Scheme evaluation
demo.mp4
To install Schmeep on your Android phone:
- Set your keystore password as an environment variable:
export SCHMEEP_KEYSTORE_PASS=yourpasswordChoose a strong password, and don’t share it. You’ll need it for all builds.
- Create a keystore for signing the APK:
make keystoreThe keystore will be saved as
schmeep.keystorein the project directory. Keep this file safe, and don’t share it. You’ll need it to sign the app. - Attach your phone to your computer using a USB cable.
- Run:
cd schemep/ make distclean schmeep run logsThis will build the app, install it on your phone, and run it, showing you the Android logs. It will also build
schmeep, the command-line Bluetooth REPL client. - After this, you can disconnect the USB cable.
Press the app’s buttons. Each is labeled with a Scheme expression,
e.g. (* 6 7), which is evaluated when you press the button. The
result and any other output will be displayed above the buttons.
There is also a Clear Output button.
Note that some buttons won’t work until you press other ones first.
For example, factorial must be defined before it is called, and SRFI
27 must be loaded before random-integer is called.
On your computer, run schmeep while the app is still running on your
phone. It will find your phone and connect to it. At that point,
when you enter a Scheme expression at the REPL, it will be transmitted
to the phone, which will evaluate it and send you back the output and
result. The expression, output, and result will be displayed on the
app, too.
If your expression produces an infinite loop, you can enter C-c to
stop it.
Hit C-\ to exit the app.
- Try editing index.html, which defines the app’s one screen. Add
this:
<script type="application/x-scheme"> (define (fibonacci n) (let loop ((i 0) (a 0) (b 1)) (if (= i n) a (loop (+ i 1) b (+ a b))))) </script>
- Connect your phone using USB.
- Run
make runto rebuild the app and install the new version on your phone. This should only take a few seconds. - Connect using
schmeep. - Try evaluating
(fibonacci 10). - Of course, you could have entered the definition of
fibonaccidirectly fromschmeeprather than rebuilding the app. But rebuilding the app makes the change survive app restarts.
RAX is a simple framework for building web user interfaces in Schmeep. Let’s try an example.
- Add this to
index.htmljust before<div class="button-grid"></div>:<button class="scheme-button" data-rax='click (eg "Hello, world.")'>Hello, world.</button>
- Run
make run. - Click the “Hello, world.” button that appears above all the other buttons.
- You should see the input expression and the result.
- Here’s how that worked:
You added the
<button>. The class was just for CSS styling. Thedata-raxattribute had two parts:click, which specified that Scheme code would be executed on aclickevent; and(eg "Hello, world."), which specified that the string would be evaluated and returned. Theegmacro is just for examples, but it illustrates RAX. You can find its definition in eg.scm.Any expression used after the event name must return a procedure that accepts an event decoded from JSON. Instead of calling the macro
eg, we could have used any expression that returns such a procedure. That procedure can execute any Scheme code, and must return an alist mapping CSS selectors to HTML and a “verb.” RAX finds each returned selector, and uses the verb to decide what to do.For each selector that it found:
- If the verb missing or is
replace, RAX replaces the first element that matches the selector with that HTML. - If the verb is
append, RAX appends the HTML to the end of the matching element. - Other verb names are reserved for future extensions to RAX.
You can use
(chibi sxml)to produce HTML, and(chibi json)to produce JSON. Use eg.scm as an example. It handles exceptions as well.With these simple primitives, you should be able to build interesting apps.
Of course, we’ll need to add the ability to read and write output, e.g. in a database; and to connect to the network. I plan to add those.
- If the verb missing or is
I gave a lightning talk about Schmeep at the BALISP (Bay Area Lisp and Scheme) meeting on 3 Nov 2025:
https://www.youtube.com/watch?v=YlmrYAyJxdE
The demo video above was supposed to be included, but I ended up not being able to show it for technical reasons.
Thanks to Nawal Husnoo, author of chibi-droid, and cnlohr, author of rawdrawandroid, for inspiration. Thanks especially to Alex Shinn, author of Chibi Scheme and editor of the R7RS Small Scheme standard.
The command-line client can be tested with an expect script.
First, build the client:
make schmeepThen run the test script. You will need to have the expect program
installed.
tests/schmeep.expectThe script will connect to the Schmeep Android app, send some Scheme expressions, and test for correct evaluation. It also checks that interrupts (Ctrl-C) are handled correctly. It will then disconnect, connect again, and test for correct evaluation. It will display “ALL PASSED” at the end iff all tests pass.