28
Writing iPhone apps in Scheme λ

The Scheme Language -- Using it on the iPhone

Embed Size (px)

DESCRIPTION

An introduction to the Scheme programming language and some practical examples of why it's a cool languages (using it on the iPhone, for example).

Citation preview

Page 1: The Scheme Language -- Using it on the iPhone

Writing iPhone apps in Schemeλ

Page 2: The Scheme Language -- Using it on the iPhone

λ

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

Page 3: The Scheme Language -- Using it on the iPhone

λ

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.

Page 4: The Scheme Language -- Using it on the iPhone

λ

Syntax• Uses S-expressions and prefix notation

• (function arg1 arg2 ...)

• (+ 5 5)

• 10

• (- (foo 3 2) 1)

• ?

• (+ 1 2 3 4 5)

• 15

Page 5: The Scheme Language -- Using it on the iPhone

λ

Syntax

Page 6: The Scheme Language -- Using it on the iPhone

λ

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)

Page 7: The Scheme Language -- Using it on the iPhone

λ

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)))

Page 8: The Scheme Language -- Using it on the iPhone

λ

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))

Page 9: The Scheme Language -- Using it on the iPhone

λ

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?) ...)

Page 10: The Scheme Language -- Using it on the iPhone

λ

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))

Page 11: The Scheme Language -- Using it on the iPhone

λ

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)

Page 12: The Scheme Language -- Using it on the iPhone

λ

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.

Page 13: The Scheme Language -- Using it on the iPhone

λ

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)))

Page 14: The Scheme Language -- Using it on the iPhone

λ

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

Page 15: The Scheme Language -- Using it on the iPhone

λ

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?

Page 16: The Scheme Language -- Using it on the iPhone

λ

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

Page 17: The Scheme Language -- Using it on the iPhone

λ

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]

Page 18: The Scheme Language -- Using it on the iPhone

Example

Page 19: The Scheme Language -- Using it on the iPhone

λ

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

Page 20: The Scheme Language -- Using it on the iPhone

λ

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.

Page 21: The Scheme Language -- Using it on the iPhone

Example

Page 22: The Scheme Language -- Using it on the iPhone

λ

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.

Page 23: The Scheme Language -- Using it on the iPhone

λ

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

Page 24: The Scheme Language -- Using it on the iPhone

Example

Page 25: The Scheme Language -- Using it on the iPhone

λ

• 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

Optimizing

Page 26: The Scheme Language -- Using it on the iPhone

λ

• 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

Paredit

Page 27: The Scheme Language -- Using it on the iPhone

Example

Page 28: The Scheme Language -- Using it on the iPhone

[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