Writing iPhone apps in Scheme
              λ
What is Scheme?
• Scheme is a dialect of Lisp, around since the
  70s
• Functional, although not “pure”
• Extremely minimal, concise, and expressive
 • Fully defined in R5RS   [1]


 • Build bigger parts from smaller parts
                                                  λ
Implementations
• Scheme by itself is the language specification
• There are many implementations of
  Scheme, each with different strengths:
  • Gambit-C: speed, portability
  • PLT: ease-of-use, libraries
  • Scheme48: modules, formal semantics
  • etc.
                                                  λ
Syntax
• Uses S-expressions and prefix notation
• (function arg1 arg2 ...)
• (+ 5 5)
 • 10
• (- (foo 3 2) 1)
 •?
• (+ 1 2 3 4 5)
 • 15                                     λ
Syntax




         λ
Functions
• `define` declares functions
 • (define (multiply x y)
      (other-function x)
      (* x y))
• The last value is returned, so unless
  `other-function` has a side effect, that call
  is essentially ignored
• `define` also create variables
 • (define foo 5)
                                                  λ
Functions
• `lambda` creates an anonymous function
• (lambda () (+ 1 2))
• (lambda (x y) (* x y))
• lambdas are ubiquitous in Scheme, too
  powerful to fully explain here, but it’s
  another dimension of Scheme’s
  expressiveness
• Our “multiply” function could be defined as:
 • (define multiply (lambda (x y) (* x y)))      λ
Functions
• Functions are full closures with tail-
  recursion where possible
• (define (foo x y)
     (define z (get-z-axis))
     (lambda () (+ x y z)))
• (define (bar)
     (read-network-blocking-and-act)
     (bar))

                                           λ
Identifiers
• The name of an identifier is very flexible; can
  contain almost any character
• Very expressive
 • (define the-number 5)
 • (define !@#$%^&* 10)
 • (define (is-alive?) ...)
                                                  λ
Lists
• The list is Scheme’s fundamental data
  structure
• Special syntax for lists:
 • ‘(1 2 3 “foo”)
 • ‘(1 2 3 (4 5 6))
 • `(1 2 3 ,data) (define data “foo”)
 • `(1 2 3 ,@data) (define data ‘(4 5 6))
                                           λ
Lists
• Lists are made up of “cons cells” or pairs
• Fundamental list functions:
 • car
   • (car ‘(1 2 3)) => 1
 • cdr
   • (cdr ‘(1 2 3)) => (2 3)
 • cons
   • (cons 1 ‘(2 3)) => (1 2 3)                λ
Lists

• Question: is a function not simply a list of
  elements?
  • ‘(define (foo x y) (* x y))
• Yes, it is.
• In fact, any code in Scheme is data — simply
  a list of elements.


                                                 λ
Macros
• Macros are Scheme functions that take
  arguments and expand into different code
• Macros usually parse code, which is easy in
  Scheme because code is data!
• (define-macro (my-define func . body)
    (let ((name (car func))
          (args (cdr func)))
      `(define ,name (lambda ,args ,@body))))
• (my-define (foo x y) (* x y)) expands into
 • (define foo (lambda (x y) (* x y)))           λ
Macros
• Macros are lazy
• Macros allow an extremely powerful tool for
  extending the language for your needs
• Any new construct can be integrated
• You could redefine `if`
• Other macro systems exist which integrate
  pattern matching and other features

                                                λ
Say again?
• Because of consistency and conciseness, it’s
  easy to write reusable, small bits of code in
  Scheme, which is good
• Other libraries implement tons of stuff, such
  as object systems, vectors, etc.
  • SRFI’s
• Not covered: continuations, eval, and more
• Questions or comments?
                                                  λ
Practical Examples
• It turns out that it’s easy to implement
  functional programming in an imperative
  language like C [3]
• Gambit-C is a Scheme system which takes
  Scheme and compiles it to C [2]
  • Extremely fast and portable
  • Easy to interface to C/C++/Obj-C
    libraries

                                             λ
Taking Scheme to the iPhone


• Cross-compiled Gambit’s run-time library
  for the ARM architecture (for the iPhone)
• Compiled my Scheme code to C
• Linked everything together, and it ran fine!
• Wasn’t that easy? [4]




                                                λ
Example
Benefits

• Write iPhone apps in Scheme, of course
• Garbage collector
• Faster, real-time development
 • Load in Scheme files at run-time
 • Much more sane debugging

                                           λ
Loading in Scheme at run-time

• Scheme has a `load` procedure which takes
  a filename, loads in the code and evaluates it
• In Gambit, this function loads code at run-
  time (`include` does the same thing at
  compile-time)
• Compile an app with a `load` statement,
  install it once, and develop with interpreted
  code forever.

                                                  λ
Example
Sane Debugging
• What is a REPL?
 • Read-Eval-Print-Loop
• A debugger is a REPL with special
  commands
• Gambit comes with a nice command-line
  debugger, so we want this to work for our
  iPhone apps.

                                              λ
Sane Debugging
• Since code is simply S-expressions, it’s really
  easy to parse, pass around the network, etc.
• We’ve created a “remote debugger” which
  implements the functionality of a networked
  REPL
• Instead of reading from the console, the
  REPL reads and writes from/to a network
  port
• A “debugging server” gives you access to
  REPLs running inside the application              λ
Example
Optimizing
• Compiling to C makes it easy to fine tune
  hotspots in your application
 • (define fast-sqrt
       (c-lambda (float) float “fast_sqrt”))
• Once you’ve written and debugged your app
  sanely, profile and optimize specific parts of
  your app
 • Re-write small pieces of code in C
 • Use `declare` in Gambit                       λ
Paredit
• Another benefit of concise syntax is more
  advanced text editing
• Instead of thinking in terms of lines, think in
  terms of S-expressions
• Paredit implements key-bindings in Emacs to
  manipulate S-expressions
  • Really powerful way of writing code
                                                    λ
Example
[1] R5RS: http://schemers.org/Documents/Standards/R5RS/

[2] Gambit Scheme: http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Main_Page

[3] 90 Minute Scheme-to-C compiler http://lambda-the-ultimate.org/node/349

[4] Writing iPhone apps in Scheme: http://jlongster.com/blog/2009/06/17/write-apps-iphone-scheme/




           For more info, check out my blog:
               http://jlongster.com/blog

                                                                          @jlongster

The Scheme Language -- Using it on the iPhone

  • 1.
    Writing iPhone appsin Scheme λ
  • 2.
    What is Scheme? •Scheme is a dialect of Lisp, around since the 70s • Functional, although not “pure” • Extremely minimal, concise, and expressive • Fully defined in R5RS [1] • Build bigger parts from smaller parts λ
  • 3.
    Implementations • Scheme byitself is the language specification • There are many implementations of Scheme, each with different strengths: • Gambit-C: speed, portability • PLT: ease-of-use, libraries • Scheme48: modules, formal semantics • etc. λ
  • 4.
    Syntax • Uses S-expressionsand prefix notation • (function arg1 arg2 ...) • (+ 5 5) • 10 • (- (foo 3 2) 1) •? • (+ 1 2 3 4 5) • 15 λ
  • 5.
  • 6.
    Functions • `define` declaresfunctions • (define (multiply x y) (other-function x) (* x y)) • The last value is returned, so unless `other-function` has a side effect, that call is essentially ignored • `define` also create variables • (define foo 5) λ
  • 7.
    Functions • `lambda` createsan anonymous function • (lambda () (+ 1 2)) • (lambda (x y) (* x y)) • lambdas are ubiquitous in Scheme, too powerful to fully explain here, but it’s another dimension of Scheme’s expressiveness • Our “multiply” function could be defined as: • (define multiply (lambda (x y) (* x y))) λ
  • 8.
    Functions • Functions arefull closures with tail- recursion where possible • (define (foo x y) (define z (get-z-axis)) (lambda () (+ x y z))) • (define (bar) (read-network-blocking-and-act) (bar)) λ
  • 9.
    Identifiers • The nameof an identifier is very flexible; can contain almost any character • Very expressive • (define the-number 5) • (define !@#$%^&* 10) • (define (is-alive?) ...) λ
  • 10.
    Lists • The listis Scheme’s fundamental data structure • Special syntax for lists: • ‘(1 2 3 “foo”) • ‘(1 2 3 (4 5 6)) • `(1 2 3 ,data) (define data “foo”) • `(1 2 3 ,@data) (define data ‘(4 5 6)) λ
  • 11.
    Lists • Lists aremade up of “cons cells” or pairs • Fundamental list functions: • car • (car ‘(1 2 3)) => 1 • cdr • (cdr ‘(1 2 3)) => (2 3) • cons • (cons 1 ‘(2 3)) => (1 2 3) λ
  • 12.
    Lists • Question: isa function not simply a list of elements? • ‘(define (foo x y) (* x y)) • Yes, it is. • In fact, any code in Scheme is data — simply a list of elements. λ
  • 13.
    Macros • Macros areScheme functions that take arguments and expand into different code • Macros usually parse code, which is easy in Scheme because code is data! • (define-macro (my-define func . body) (let ((name (car func)) (args (cdr func))) `(define ,name (lambda ,args ,@body)))) • (my-define (foo x y) (* x y)) expands into • (define foo (lambda (x y) (* x y))) λ
  • 14.
    Macros • Macros arelazy • Macros allow an extremely powerful tool for extending the language for your needs • Any new construct can be integrated • You could redefine `if` • Other macro systems exist which integrate pattern matching and other features λ
  • 15.
    Say again? • Becauseof consistency and conciseness, it’s easy to write reusable, small bits of code in Scheme, which is good • Other libraries implement tons of stuff, such as object systems, vectors, etc. • SRFI’s • Not covered: continuations, eval, and more • Questions or comments? λ
  • 16.
    Practical Examples • Itturns out that it’s easy to implement functional programming in an imperative language like C [3] • Gambit-C is a Scheme system which takes Scheme and compiles it to C [2] • Extremely fast and portable • Easy to interface to C/C++/Obj-C libraries λ
  • 17.
    Taking Scheme tothe iPhone • Cross-compiled Gambit’s run-time library for the ARM architecture (for the iPhone) • Compiled my Scheme code to C • Linked everything together, and it ran fine! • Wasn’t that easy? [4] λ
  • 18.
  • 19.
    Benefits • Write iPhoneapps in Scheme, of course • Garbage collector • Faster, real-time development • Load in Scheme files at run-time • Much more sane debugging λ
  • 20.
    Loading in Schemeat run-time • Scheme has a `load` procedure which takes a filename, loads in the code and evaluates it • In Gambit, this function loads code at run- time (`include` does the same thing at compile-time) • Compile an app with a `load` statement, install it once, and develop with interpreted code forever. λ
  • 21.
  • 22.
    Sane Debugging • Whatis a REPL? • Read-Eval-Print-Loop • A debugger is a REPL with special commands • Gambit comes with a nice command-line debugger, so we want this to work for our iPhone apps. λ
  • 23.
    Sane Debugging • Sincecode is simply S-expressions, it’s really easy to parse, pass around the network, etc. • We’ve created a “remote debugger” which implements the functionality of a networked REPL • Instead of reading from the console, the REPL reads and writes from/to a network port • A “debugging server” gives you access to REPLs running inside the application λ
  • 24.
  • 25.
    Optimizing • Compiling toC makes it easy to fine tune hotspots in your application • (define fast-sqrt (c-lambda (float) float “fast_sqrt”)) • Once you’ve written and debugged your app sanely, profile and optimize specific parts of your app • Re-write small pieces of code in C • Use `declare` in Gambit λ
  • 26.
    Paredit • Another benefitof concise syntax is more advanced text editing • Instead of thinking in terms of lines, think in terms of S-expressions • Paredit implements key-bindings in Emacs to manipulate S-expressions • Really powerful way of writing code λ
  • 27.
  • 28.
    [1] R5RS: http://schemers.org/Documents/Standards/R5RS/ [2]Gambit Scheme: http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Main_Page [3] 90 Minute Scheme-to-C compiler http://lambda-the-ultimate.org/node/349 [4] Writing iPhone apps in Scheme: http://jlongster.com/blog/2009/06/17/write-apps-iphone-scheme/ For more info, check out my blog: http://jlongster.com/blog @jlongster