Android &
Functional Programming
For Great Good™
A kind of candy?
## What is functional programming?
Composability
↓
Abstraction
→
Abstraction
→
## Now it makes sense
![hans](http://static.bips.channel4.com/bips/orig/videos/2776180868001.jpg)
> “Plumbing’s just Lego, innit? Water Lego...”
— Superhans, *Peep Show*
## Who uses Scala?
![users](scalausers.png)
## Values
```scala
val x = 4
```
## Values
```scala
val x: Int = 4
```
## Methods
```scala
def add(x: Int, y: Int) = x + y
```
## Methods
```scala
def add(x: Int, y: Int): Int = {
x + y
}
```
## Anonymous functions
```scala
(x: Int) ⇒ x + 3
```
## Anonymous functions
```scala
x ⇒ x + 3
```
## Anonymous functions
```scala
_ + 3
```
Syntax-bending
```scala
5.add(5) ⇔ 5 add 5
```
```scala
bird.♫("lala") ⇔ bird ♫ "lala"
```
```scala
say("Hi!") ⇔ say { "Hi!" }
```
## Let’s see it in action!
A cartographic case
→
## A cartographic case
> Given a list of cities,
> **select** those with a river,
> **take** top-**5** of
> the **most populated ones**, and
> put **each** of them on the map.
## Code poetry? [[+]](http://twitter.github.io/scala_school/collections.html)
```scala
cities
.filter(_.hasRiver)
.sortBy(-_.population)
.take(5)
.foreach { c ⇒
addToMap(c.name, c.coordinates)
}
```
## Not too early!
> Declare a property you need,
> but do not call any APIs
> before the UI is ready
## Some laziness helps
```scala
lazy val title =
getArguments.getString("title")
```
## What about all those `null`s?
## Code haiku! [[+]](http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html)
```scala
lazy val title =
Option(getArguments)
.flatMap(a ⇒ Option(a.getString("title")))
.getOrElse("Hello")
```
## Get off my lawn!
> Run a difficult computation
> **outside the main thread**
> and do something with the result
> when it’s ready.
The future [+]
```scala
val result = Future {
val x = longComputation(41.5)
x + 5
}
```
```scala
result onComplete {
case Success(x) ⇒ doSomething(x)
case Failure(t) ⇒ handle(t)
}
```
> “Don’t put off until tomorrow what you can do today”
— Benjamin Franklin
Operating in the future
↓
## Operating in the future [[+]](http://docs.scala-lang.org/overviews/core/futures.html)
```scala
val fortyTwo = Future { ... }
val fortyThree = fortyTwo.map(_ + 1)
fortyThree onComplete { ... }
```
Async orchestration
*
↓
a few seconds later |
⇒ €21.6 |
## Async orchestration [[+]](http://docs.scala-lang.org/sips/pending/async.html)
```scala
val euros = async {
val future1 = getDollarsFromDb
val future2 = googleConversionRate
val d = await(future1)
val r = await(future2)
d * r
}
```
## Android XML layouts
![xml](xml.png)
* Verbose
* XML + code boilerplate
* Only one per file
* No namespacing
## Macroid [[+]](https://github.com/macroid/macroid)
> Experimental modular functional UI language for Android, written in Scala.
## Bricks
```scala
w[Button]
```
## Bricks
```scala
l[LinearLayout](
w[Button],
w[TextView]
)
```
## Bricks
```scala
val brick1 = w[Button]
val brick2 = w[TextView]
l[LinearLayout](
brick1, brick2
)
```
## Tweaking
```scala
w[TextView] <~ text("Hello")
```
## Tweaking
```scala
def largeText(str: String) =
text(str) +
TextSize.large +
padding(left = 8 dp)
w[TextView] <~ largeText("Hello")
```
## A complete example
```scala
var greeting = slot[TextView]
l[LinearLayout](
w[Button] <~
text("Greet me!") <~
On.click {
greeting <~ show
},
w[TextView] <~
text("Hello there") <~
wire(greeting) <~ hide
)
```
## What about adaptivity?
## The Android way
* A folder per screen size
* Limited layout reuse
## Media queries
```scala
val textStyle =
widerThan(400 dp) ?
TextSize.large |
TextSize.medium
w[TextView] <~ textStyle
```
## New ways of expression
```scala
? <~ ?
```
## Optional tweaking
```scala
onlySeenInHD <~ (hdpi ? show)
```
## Batch tweaking
```scala
List(textView1, textView2) <~ hide
```
Tweaking from the future
↓
many seconds |
⇒ text("Hello") |
## Tweaking from the future
```scala
val futureCaption = Future {
Thread.sleep(5000)
text("Hello")
}
myTextView <~ futureCaption
```
## And now for something completely different...
![Cleese](http://static.tvtropes.org/pmwiki/pub/images/and-now-for-something-completely-different_2729.jpg)
## Starting procedures
1. Install [SBT](http://www.scala-sbt.org/) (build tool)
2. Install [Intellij IDEA](http://www.jetbrains.com/idea/) (or Android Studio)
3. Add [Scala](http://plugins.jetbrains.com/plugin/?id=1347) and [SBT](http://plugins.jetbrains.com/plugin/5007?pr=idea) plugins to IDEA
4. Add [Android](https://github.com/pfn/android-sdk-plugin) and [IDEA](https://github.com/mpeltonen/sbt-idea) plugins to SBT
5. Write a build file
6. Generate IDE project files
7. Run! *-or-* In utter rage, post in the [Mailing list](https://groups.google.com/forum/#!forum/scala-on-android)
## The build file
```scala
name := "Project-name"
version := "1.0"
platformTarget in Android := "android-19"
libraryDependencies ++= Seq(
"com.loopj.android" % "android-async-http" % "1.4.4",
"com.android.support" % "support-v13" % "19.1.0",
aar("com.google.android.gms" % "play-services" % "4.0.30")
)
```
## Connecting the IDE
```
sbt
> gen-idea
```
## Some flies in the ointment
#### Scala library is around 5 MB
↓
#### Squeeze it with ProGuard
↓
#### Build time goes up to 1 min / 10K LOC;
#### ProGuard config takes some effort
![fly](http://www.picgifs.com/graphics/f/flies/graphics-flies-254732.gif)