1 What is Moby?
2 Quick Start
3 Running and packaging Android programs
4 Phone API
4.1 Location (GPS)
4.2 Motion sensors and tilt
4.3 Internet access
Version: 5.0.1

Moby: Racket for Mobile Phones

1 What is Moby?

Moby is a project from the PLT team. The Moby compiler consumes Advanced Student Language (ASL) programs that use World primitives, and produces applications for mobile platforms. The current prototype supports desktop browsers and smartphones. Our long-term goal is to make Racket the premiere reactive scripting language for mobile phones.

Shriram Krishnamurthi presented the ideas behind Moby at ILC 2009 in his talk The Moby Scheme Compiler for Smartphones.

Moby requires Racket 5.0.1.

2 Quick Start

Let’s create a simple application that shows a rapidly incrementing counter. Create a file "counter.rkt" in the Module language with the following content:

  #lang planet dyoo/moby:3:3
  (define initial-world 0)
  (big-bang initial-world (on-tick add1))

Note that this program is in a separate language that provides extra functions like big-bang. This program can be executed in Racket, although evaluation will halt on the big-bang because it’s a function that requires a Javascript context.

For testing, the function run-in-browser can be used to provide a mock environment in your web browser:
  #lang racket
  (require (planet dyoo/moby:3:3))
  (run-in-browser "counter.rkt")
This will bring up a web server and a browser window with the running program.

To create an Android apk package, you can use create-android-phone-package. Create a file called "build-counter.rkt" with the following content:
  #lang racket
  (require (planet dyoo/moby:3:3))
  (create-android-phone-package "counter.rkt" "counter.apk")
Running this will take "counter.rkt" and compile it to an Android package "counter.apk".

Because Moby programs use the web, they can dynamically generate DOM trees and style them with CSS, as in the examples below.

The next example renders the world as a paragraph of text, styled with a font-size of 30. It uses draw-page and draw-css to draw the web page.

  #lang planet dyoo/moby:3:3
  (define initial-world 0)
  (define (draw-html w)
  (list (js-p '(("id" "myPara")))
        (list (js-text "hello world"))))
  (define (draw-css w)
  '(("myPara" ("font-size" "30"))))
  (big-bang initial-world
            (to-draw-page draw-html draw-css))

The next example shows an image and an input text field. As with the previous example, it uses draw-html and draw-css to construct the web page, and every time the world changes, the runtime environment reacts by re-drawing the web page.

  #lang planet dyoo/moby:3:3
  (define (form-value w)
  (format "~a" w))
  (define (update-form-value w v)
  (string->number v))
  (define elt
  (js-input "text" update-form-value '()))
  (define (draw-html w)
  (list (js-div)
        (list (js-img "http://racket-lang.org/logo.png"))
        (list elt)
        (list (js-p '(("id" "aPara")))
              (list (js-text (format "~a" w))))))
  (define (draw-css w)
  '(("aPara" ("font-size" "50px"))))
  (big-bang 0
    (to-draw-page draw-html draw-css))

We can also use phone-specific features, such as geolocation. The following program shows the current location.
  #lang planet dyoo/moby:3:3
  (require (planet dyoo/moby:3:3/phone/location))
  (define (make-message w lat lng)
  (format "I think I am at: ~s ~s" lat lng))
  (big-bang "initial state"
            (on-location-change make-message))
Note that it requires phone/location, one of the modules provided by this package.

The last example is a phone mood ring called "mood-ring.rkt": it shows a single DIV whose background color is controlled by the phone’s orientation; it uses phone/tilt to get at the orientation of the phone, and arbitrarily maps it to a color.

  #lang planet dyoo/moby:3:3
  (require (planet dyoo/moby:3:3/phone/tilt))
  ; The world is a color.
  (define initial-world (make-color 0 0 0))
  ; tilt: world number number number -> world
  ; Tilting the phone adjusts the color.
  (define (tilt w azimuth pitch roll)
  (make-color (scale azimuth 360)
              (scale (+ pitch 90) 180)
              (scale (+ roll 90) 180)))
  ; scale-azimuth: number -> number
  ; Take a number going from 0-360 and scale it to a number between 0-255
  (define (scale n domain-bound)
  (inexact->exact (floor (* (/ n domain-bound) 255))))
  ; User interface.
  (define view (list (js-div '((id "background")))))
  (define (draw-html w) view)
  (define (draw-css w)
  (list (list "background"
              (list "background-color"
                    (format "rgb(~a, ~a, ~a)"
                            (color-red w)
                            (color-green w)
                            (color-blue w)))
     (list "width" "300")
     (list "height" "300"))))
  (big-bang initial-world
            (on-tilt tilt)
            (to-draw-page draw-html draw-css))
Again, to package the program, we use create-android-phone-package.
  #lang racket
  (require (planet dyoo/moby:3:3))
  (create-android-phone-package "mood-ring.rkt" "mood.apk")

3 Running and packaging Android programs

 (require (planet dyoo/moby:3:3))

(run-in-browser input-file)  void
  input-file : path-string?
Runs the given input-file in a context that provides mocks for phone-specific behavior.

(create-android-phone-package input-file    
  output-apk)  void
  input-file : path-string?
  output-apk : path-string?
Creates an Android phone package.

4 Phone API

The language bindings of Moby language come from the js-vm PLaneT package; please refer to the documentation of js-vm.

4.1 Location (GPS)

 (require (planet dyoo/moby:3:3/phone/location))

(on-location-change world-updater)  handler
  world-updater : (world [latitude number] [longitude number] -> world)
Constructs a world handler that watches for changes in the phone’s geographic location.

4.2 Motion sensors and tilt

 (require (planet dyoo/moby:3:3/phone/tilt))

(on-acceleration world-updater)  handler
  world-updater : (world [x number] [y number] [z number] -> world)
Constructs a world handler that watches acceleration updates.

(on-shake world-updater)  handler
  world-updater : (world -> world)
Constructs a world handler that watches shake events; if the phone is shaken, the world-updater will fire off.

(on-tilt world-updater)  handler
  world-updater : (world [azimuth number] [pitch number] [roll number] -> world)
Constructs a world handler that watches changes in orientation.

4.3 Internet access

 (require (planet dyoo/moby:3:3/phone/internet))

This module does not provide any bindings, but is meant to notify create-android-phone-package if a program needs permission to access the internet. If your program is using image-url or js-img, add a require to this module.