<commit_before><!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">

  <title>Scala 2.12 &amp; Java 8: more fun together!</title>

  <meta name="description" content="Presented at Philly ETE, April 11 2016.">
  <meta name="abstract" content="
To take full advantage of Java 8&#x27;s support for lambdas and interfaces with concrete methods, a lot is changing behind the scenes of the Scala 2.12 compiler!

At the language level, Scala has always had first-class support for lambdas, of course, and with Java 8&#x27;s invokedynamic machinery we can now compile them to more compact and efficient bytecode. We also interoperate fully with Java&#x27;s modeling of functions as Single Abstract Method types  (aka functional interfaces). 

The other advantage of compiling to Java 8 bytecode is a more direct encoding of traits. The invokedynamic instruction plays an interesting role here as well, surprisingly!

While we were revamping the back-end, we&#x27;ve also replaced the old optimizer with a much more robust and powerful one, based on Miguel Garcia&#x27;s earlier work.

Finally, I&#x27;ll talk about the crucial ingredients of my kind of functional programming language (beyond nice syntax for functions). Thrilling slide titles will include: &quot;val is your friend&quot;, &quot;everything is an expression&quot;, &quot;patterns for destruction&quot;, &quot;how I stopped worrying about variance&quot;.">

  <meta name="author" content="<NAME>">

  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">

  <link rel="stylesheet" href="css/reveal.css">
  <link rel="stylesheet" href="css/theme/typesafe.css" id="theme">

  <!-- Code syntax highlighting -->
  <link rel="stylesheet" href="lib/css/zenburn.css">

  <!-- Printing and PDF exports -->
  <script>
    var link = document.createElement( 'link' );
    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
    document.getElementsByTagName( 'head' )[0].appendChild( link );
  </script>

  <!--[if lt IE 9]>
  <script src="lib/js/html5shiv.js"></script>
  <![endif]-->
</head>

<body>
  <div class="reveal">
    <div class='footer'> 
      <img style="height:1.5em; opacity: 0.66" src="images/lightbend-color-reverse.svg" title="Lightbend"> </img>
    </div>

    <!-- data-background="images/bg.png" data-background-size="100% 100%" -->
    <div class="slides">
      <section>
        <h2>Scala 2.12 & Java 8</h2>
        <h3 class="orange">More Fun Together!</h3>
        <h4 style="margin-top:75px">Adriaan <a style="opacity:0.75" href="http://twitter.com/adriaanm">@adriaanm</a> Moors</h4>
        <h5 class="orange">Scala Team Lead</h5>
        <h5 style="opacity: 0.75">adriaanm.github.io/reveal.js/scala-2.12.html</h5>
      </section>

      <section>
         <img src="images/lightbend-color-reverse.svg" title="Lightbend" width="66%"></img>
      </section>



<!- --------------------- roadmap etc --------------------------------------------------- -->
<section> <section data-markdown><script type="text/template">

# Who are you?

</script></section> <section data-markdown><script type="text/template">

## Team
##### @szeiger
##### @sethtisue
##### @lrytz
##### @adriaanm
##### @retronym

</script></section> <section data-markdown><script type="text/template">

# What have you been up to lately?

</script></section> <section data-markdown><script type="text/template">

## 1 release / 6 weeks
  - Q1 2015: 2.11.5, 2.11.6, 2.10.5
  - Q2 2015: 2.12.0-M1, 2.11.7
  - Q3 2015: 2.12.0-M2, 2.10.6
  - Q4 2015: 2.12.0-M3
  - Q1 2016: 2.11.8, 2.12.0-M4

</script></section> <section data-markdown><script type="text/template">

# What's next?
## Same
  - Q2 2016: 2.12.0-M5, 2.12.0-RC1
  - Q3 2016: 2.12.0, 2.12.1, 2.11.9
  - Q4 2016: 2.12.2, 2.12.3

</script></section> <section data-markdown><script type="text/template">


# What are you most excited about?

</script></section> <section data-markdown><script type="text/template">

## Compiling to JVM 8!

</script></section> <section data-markdown><script type="text/template">

## New Backend & Optimizer!

* GenBCode ASM-based backend
* Inline from classes/objects/traits ([scala/scala#4711](https://github.com/scala/scala/issues/4711))
* Eliminate: closures ([scala/scala-dev#14](https://github.com/scala/scala-dev/issues/14)), box/unbox ([scala/scala#4858](https://github.com/scala/scala/issues/4858)),...
* Inliner scope configurable: project, classpath

</script></section> <section data-markdown><script type="text/template">

## Incremental build improvements!
  - Class-based name hashing ([sbt/sbt#1104](https://github.com/sbt/sbt/issues/1104))
  - More efficient IO for analysis ([sbt/sbt#2525](https://github.com/sbt/sbt/issues/2525))

</script></section> <section data-markdown><script type="text/template">

## Community!

</script></section> <section data-markdown><script type="text/template">

### friendly & inclusive

</script></section> <section data-markdown><script type="text/template">

### co-passionate & compassionate

</script></section> <section data-markdown><script type="text/template">

### GROWING

</script></section> <section data-markdown><script type="text/template">

# Thank You!

</script></section> <section data-markdown><script type="text/template">

### Investing in opening up
  - Scala Center!
  - Standard sbt build (WIP)
  - PR validation on EC2 ([scala/scala-jenkins-infra](https://github.com/scala/scala-jenkins-infra))
  - Modularization (more to come in 2.13)
    - community owned (merge PRs, push tag to release)
    - smaller core to standardize & stabilize

</script></section> <section data-markdown><script type="text/template">

# 2.12
## Compiler release
 - Java 8 <small>(λ, SAM, `default`)</small>
 - New Optimizer <small>(based on <NAME>'s work)</small>
 - <small>~~Abide (time permitting)~~</small>
 - Set scene for library cleanups
 - ~~Q1~~ *Q2* 2016

</script></section> <section data-markdown><script type="text/template">

# 2.13 (Aida)
## Library release
## [scala-lang.org/news/roadmap-next](http://scala-lang.org/news/roadmap-next)
## 2.12.1 + 18 months

</script></section> <section data-markdown><script type="text/template">

# Simpler Core Library
  - Composition over inheritance
  - Move out parallel collections & views
  - Caveat Inheritor Collectionis
    - 99% of users need not worry, though

</script></section> <section data-markdown><script type="text/template">

# Modules
  - Lazy collections (interop with Java 8 Streams)
  - Parallel collections (multiple impls? scala-blitz & Java 8)
  - Validation

</script></section> <section data-markdown><script type="text/template">

# Macros: `scala.meta`
  - Prototype, default in Don Giovanni
  - Complete rewrite!
  - Only use macros when all else fails...

</script></section> <section data-markdown><script type="text/template">

# <NAME>, act 1

</script></section> <section data-markdown><script type="text/template">

## Rework back-end (see [dotty](https://github.com/lampepfl/dotty))
  - keep front-end for source compatibility
  - faster compiler
  - improve [binary compat](https://www.youtube.com/watch?v=g1Pqyskjx8M)

</script></section> <section data-markdown><script type="text/template">

# <NAME>, act 2

</script></section> <section data-markdown><script type="text/template">

## Simpler syntax
 - Drop procedure syntax
   - all definitions: `kw name sig [= body]`
 - So long, XML literals!
   - `xml""<hello/>"""`
 - Anyone ever use early definitions?
   - introducing: trait parameters

</script></section> <section data-markdown><script type="text/template">

## Simpler semantics
 - Type members model type constructors, existentials,...
 - No more lub blow-ups (union types as lazy lubs)
 - Built-in support for some of shapeless (`HList/HMap`)

</script></section> <section data-markdown><script type="text/template">

## Fewer [puzzlers](http://www.amazon.com/Scala-Puzzlers-Andrew-Phillips/dp/0981531679)
Sorry, Andrew & Nermin!


</script></section> </section>
<!- --------------------- MAIN MEAT ----------------------------------------------- -->
<section> <section data-markdown><script type="text/template">


# 2.12 <3 Java 8
## [scala-lang.org/news/2.12-roadmap](http://scala-lang.org/news/2.12-roadmap)

</script></section> <section data-markdown><script type="text/template">

# `default` methods
#### 2.12.0-M[3, 4]
  - Java 8 λ assignable-to Scala `FunctionN` (a SAM)
  - Define Java 8 API in Scala
  - Compile `trait` to `interface`
    - Binary compat ftw

</script></section> <section data-markdown><script type="text/template">

# INDY-λ
#### 2.11.7, 2.12.0-M2
 1. scalac λ bytecode mimics javac's
 1. ride JIT perf tuning wave
 1. profit

</script></section> <section data-markdown><script type="text/template">

# Single Abstract Method
#### 2.11.5 (`-Xexperimental`)
  - Scala λ assignable-to Java 8 λ
  - Call Java 8 API from Scala
  - Also uses INDY since M4
  - TODO
    - Better type inference with Java wildcards...

</script></section> <section data-markdown><script type="text/template">

```scala
/* https://gist.github.com/adriaanm/892d6063dd485d7dd221
Original Java 8 version: 
http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples

$ scala                                                          */
scala> import java.util.stream.{Stream, IntStream}
scala> import java.util.{Arrays, List}

// List<String> myList= Arrays.asList("a1", "a2", "b1", "c2", "c1");
scala> val myList = Arrays.asList("a1", "a2", "b1", "c2", "c1")
myList: java.util.List[String] = [a1, a2, b1, c2, c1]

/*
myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);
*/
scala> myList.stream.
         filter(_.startsWith("c")).
         map(_.toUpperCase).
         sorted.
         forEach(println)
C1
C2

/*
Arrays.stream(new int[] {1, 2, 3})
    .map(n -> 2 * n + 1)
    .average()
    .ifPresent(System.out::println);  // 5.0
*/
scala> Arrays.stream(Array(1, 2, 3)).
         map(n => 2 * n + 1).average.ifPresent(println)
5.0


/*
Stream.of("a1", "a2", "a3")
    .map(s -> s.substring(1))
    .mapToInt(Integer::parseInt)
    .max()
    .ifPresent(System.out::println);  // 3
*/
scala> Stream.of("a1", "a2", "a3").
          map[String](_ substring 1).
          mapToInt(Integer.parseInt).
          max.
          ifPresent(println)
3

// wildcard capture is tricky, whence the `map[String]` above
scala> Stream.of("a1", "a2", "a3").map(_ substring 1)
res: java.util.stream.Stream[?0] = ReferencePipeline$3@4ef37659

/*
Stream.of(1.0, 2.0, 3.0)
    .mapToInt(Double::intValue)
    .mapToObj(i -> "a" + i)
    .forEach(System.out::println);
*/
scala> Stream.of(1.0, 2.0, 3.0).mapToInt(_.intValue).
         mapToObj(i => "a" + i).forEach(println)
a1
a2
a3

/*
Stream.of("d2", "a2", "b1", "b3", "c")
    .filter(s -> {
        System.out.println("filter: " + s);
        return s.startsWith("a");
    })
    .sorted((s1, s2) -> {
        System.out.printf("sort: %s; %s\n", s1, s2);
        return s1.compareTo(s2);
    })
    .map(s -> {
        System.out.println("map: " + s);
        return s.toUpperCase();
    })
    .forEach(s -> System.out.println("forEach: " + s));
*/
scala> Stream of ("d2", "a2", "b1", "b3", "c") filter { s =>
           println("filter: " + s)
           s.startsWith("a")
       } sorted { (s1, s2) =>
           println(f"sort: $s1%s; $s2%s\n")
           s1.compareTo(s2)
       } map { s =>
           println("map: " + s)
           s.toUpperCase
       } forEach { s =>
           println("forEach: " + s)
       }
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
map: a2
forEach: A2
```


</script></section> <section data-markdown><script type="text/template">


## SAM Synthesis
```scala
scala> Stream of ("d2", "a2", "b1", "b3", "c") filter { s => 
         println(s"filter: $s"); true
       }

// Behind the scenes, scalac generated:
scala> Stream of ("d2", "a2", "b1", "b3", "c") filter { 
    def test$body(s: String): Boolean = println(s"filter: $s"); true

    new Predicate { def test(s: String): Boolean = test$body(s) }
  }
```




</script></section>  </section>
<!- --------------------- WHAT'S IN FP ----------------------------------------------- -->
<section> <section data-markdown><script type="text/template">


# My Idea of FP

</script></section> <section data-markdown><script type="text/template">

## OO's complement
#### *Small* units of functionality over *known* set of types

</script></section> <section data-markdown><script type="text/template">

## My idea of P
### Express, Understand & Maintain
  - immutable first (val <> var, expr <> stmt, recursion)
  - pattern matching (analysis of input determines output)
  - local methods (divide & conquer)
  - (de)compose safely, guided by types
  - type inference (best types are unseen -- e.g., definition-site variance)

</script></section> <section data-markdown><script type="text/template">

<commit_msg>update code<commit_after><!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">

  <title>Scala 2.12 &amp; Java 8: more fun together!</title>

  <meta name="description" content="Presented at Philly ETE, April 11 2016.">
  <meta name="abstract" content="
To take full advantage of Java 8&#x27;s support for lambdas and interfaces with concrete methods, a lot is changing behind the scenes of the Scala 2.12 compiler!

At the language level, Scala has always had first-class support for lambdas, of course, and with Java 8&#x27;s invokedynamic machinery we can now compile them to more compact and efficient bytecode. We also interoperate fully with Java&#x27;s modeling of functions as Single Abstract Method types  (aka functional interfaces). 

The other advantage of compiling to Java 8 bytecode is a more direct encoding of traits. The invokedynamic instruction plays an interesting role here as well, surprisingly!

While we were revamping the back-end, we&#x27;ve also replaced the old optimizer with a much more robust and powerful one, based on Mig<NAME>&#x27;s earlier work.

Finally, I&#x27;ll talk about the crucial ingredients of my kind of functional programming language (beyond nice syntax for functions). Thrilling slide titles will include: &quot;val is your friend&quot;, &quot;everything is an expression&quot;, &quot;patterns for destruction&quot;, &quot;how I stopped worrying about variance&quot;.">

  <meta name="author" content="<NAME>">

  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">

  <link rel="stylesheet" href="css/reveal.css">
  <link rel="stylesheet" href="css/theme/typesafe.css" id="theme">

  <!-- Code syntax highlighting -->
  <link rel="stylesheet" href="lib/css/zenburn.css">

  <!-- Printing and PDF exports -->
  <script>
    var link = document.createElement( 'link' );
    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
    document.getElementsByTagName( 'head' )[0].appendChild( link );
  </script>

  <!--[if lt IE 9]>
  <script src="lib/js/html5shiv.js"></script>
  <![endif]-->
</head>

<body>
  <div class="reveal">
    <div class='footer'> 
      <img style="height:1.5em; opacity: 0.66" src="images/lightbend-color-reverse.svg" title="Lightbend"> </img>
    </div>

    <!-- data-background="images/bg.png" data-background-size="100% 100%" -->
    <div class="slides">
      <section>
        <h2>Scala 2.12 & Java 8</h2>
        <h3 class="orange">More Fun Together!</h3>
        <h4 style="margin-top:75px">Adriaan <a style="opacity:0.75" href="http://twitter.com/adriaanm">@adriaanm</a> Moors</h4>
        <h5 class="orange">Scala Team Lead</h5>
        <h5 style="opacity: 0.75">adriaanm.github.io/reveal.js/scala-2.12.html</h5>
      </section>

      <section>
         <img src="images/lightbend-color-reverse.svg" title="Lightbend" width="66%"></img>
      </section>



<!- --------------------- roadmap etc --------------------------------------------------- -->
<section> <section data-markdown><script type="text/template">

# Who are you?

</script></section> <section data-markdown><script type="text/template">

## Team
##### @szeiger
##### @sethtisue
##### @lrytz
##### @adriaanm
##### @retronym

</script></section> <section data-markdown><script type="text/template">

# What have you been up to lately?

</script></section> <section data-markdown><script type="text/template">

## 1 release / 6 weeks
  - Q1 2015: 2.11.5, 2.11.6, 2.10.5
  - Q2 2015: 2.12.0-M1, 2.11.7
  - Q3 2015: 2.12.0-M2, 2.10.6
  - Q4 2015: 2.12.0-M3
  - Q1 2016: 2.11.8, 2.12.0-M4

</script></section> <section data-markdown><script type="text/template">

# What's next?
## Same
  - Q2 2016: 2.12.0-M5, 2.12.0-RC1
  - Q3 2016: 2.12.0, 2.12.1, 2.11.9
  - Q4 2016: 2.12.2, 2.12.3

</script></section> <section data-markdown><script type="text/template">


# What are you most excited about?

</script></section> <section data-markdown><script type="text/template">

## Compiling to JVM 8!

</script></section> <section data-markdown><script type="text/template">

## New Backend & Optimizer!

* GenBCode ASM-based backend
* Inline from classes/objects/traits ([scala/scala#4711](https://github.com/scala/scala/issues/4711))
* Eliminate: closures ([scala/scala-dev#14](https://github.com/scala/scala-dev/issues/14)), box/unbox ([scala/scala#4858](https://github.com/scala/scala/issues/4858)),...
* Inliner scope configurable: project, classpath

</script></section> <section data-markdown><script type="text/template">

## Incremental build improvements!
  - Class-based name hashing ([sbt/sbt#1104](https://github.com/sbt/sbt/issues/1104))
  - More efficient IO for analysis ([sbt/sbt#2525](https://github.com/sbt/sbt/issues/2525))

</script></section> <section data-markdown><script type="text/template">

## Community!

</script></section> <section data-markdown><script type="text/template">

### friendly & inclusive

</script></section> <section data-markdown><script type="text/template">

### co-passionate & compassionate

</script></section> <section data-markdown><script type="text/template">

### GROWING

</script></section> <section data-markdown><script type="text/template">

# Thank You!

</script></section> <section data-markdown><script type="text/template">

### Investing in opening up
  - Scala Center!
  - Standard sbt build (WIP)
  - PR validation on EC2 ([scala/scala-jenkins-infra](https://github.com/scala/scala-jenkins-infra))
  - Modularization (more to come in 2.13)
    - community owned (merge PRs, push tag to release)
    - smaller core to standardize & stabilize

</script></section> <section data-markdown><script type="text/template">

# 2.12
## Compiler release
 - Java 8 <small>(λ, SAM, `default`)</small>
 - New Optimizer <small>(based on <NAME>'s work)</small>
 - <small>~~Abide (time permitting)~~</small>
 - Set scene for library cleanups
 - ~~Q1~~ *Q2* 2016

</script></section> <section data-markdown><script type="text/template">

# 2.13 (Aida)
## Library release
## [scala-lang.org/news/roadmap-next](http://scala-lang.org/news/roadmap-next)
## 2.12.1 + 18 months

</script></section> <section data-markdown><script type="text/template">

# Simpler Core Library
  - Composition over inheritance
  - Move out parallel collections & views
  - Caveat Inheritor Collectionis
    - 99% of users need not worry, though

</script></section> <section data-markdown><script type="text/template">

# Modules
  - Lazy collections (interop with Java 8 Streams)
  - Parallel collections (multiple impls? scala-blitz & Java 8)
  - Validation

</script></section> <section data-markdown><script type="text/template">

# Macros: `scala.meta`
  - Prototype, default in <NAME>anni
  - Complete rewrite!
  - Only use macros when all else fails...

</script></section> <section data-markdown><script type="text/template">

# <NAME>, act 1

</script></section> <section data-markdown><script type="text/template">

## Rework back-end (see [dotty](https://github.com/lampepfl/dotty))
  - keep front-end for source compatibility
  - faster compiler
  - improve [binary compat](https://www.youtube.com/watch?v=g1Pqyskjx8M)

</script></section> <section data-markdown><script type="text/template">

# <NAME>, act 2

</script></section> <section data-markdown><script type="text/template">

## Simpler syntax
 - Drop procedure syntax
   - all definitions: `kw name sig [= body]`
 - So long, XML literals!
   - `xml""<hello/>"""`
 - Anyone ever use early definitions?
   - introducing: trait parameters

</script></section> <section data-markdown><script type="text/template">

## Simpler semantics
 - Type members model type constructors, existentials,...
 - No more lub blow-ups (union types as lazy lubs)
 - Built-in support for some of shapeless (`HList/HMap`)

</script></section> <section data-markdown><script type="text/template">

## Fewer [puzzlers](http://www.amazon.com/Scala-Puzzlers-Andrew-Phillips/dp/0981531679)
Sorry, Andrew & Nermin!


</script></section> </section>
<!- --------------------- MAIN MEAT ----------------------------------------------- -->
<section> <section data-markdown><script type="text/template">


# 2.12 <3 Java 8
## [scala-lang.org/news/2.12-roadmap](http://scala-lang.org/news/2.12-roadmap)

</script></section> <section data-markdown><script type="text/template">

# `default` methods
#### 2.12.0-M[3, 4]
  - Compile `trait` to `interface`
    - Binary compat ftw
    - So long, implementation classes!
  - Define Java 8 API in Scala
    - Still with care...
  - Java 8 λ assignable-to Scala `FunctionN` (a SAM)

</script></section> <section data-markdown><script type="text/template">

# INDY-λ
#### 2.11.7, 2.12.0-M2
 1. scalac λ bytecode mimics javac's
 1. ride JIT perf tuning wave
 1. profit

</script></section> <section data-markdown><script type="text/template">

# Single Abstract Method
#### 2.11.5 (`-Xexperimental`)
  - Scala λ assignable-to Java 8 λ
  - Call Java 8 API from Scala
  - Also uses INDY since M4 ([scala/scala#4971](https://github.com/scala/scala/issues/4971))
  - TODO
    - Better type inference with Java wildcards...

</script></section> <section data-markdown><script type="text/template">

```scala
/* Original:
http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples
https://gist.github.com/adriaanm/892d6063dd485d7dd221

$ scala
Welcome to Scala 2.12.0-M4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_74).
Type in expressions for evaluation. Or try :help.                */

scala> import java.util.stream.{Stream, IntStream}
scala> import java.util.{Arrays, List}

// List<String> myList= Arrays.asList("a1", "a2", "b1", "c2", "c1");
scala> val myList = Arrays.asList("a1", "a2", "b1", "c2", "c1")
myList: java.util.List[String] = [a1, a2, b1, c2, c1]

/*
 myList
     .stream()
     .filter(s -> s.startsWith("c"))
     .map(String::toUpperCase)
     .sorted()
     .forEach(System.out::println);
 */
scala> myList.stream.
          filter(_.startsWith("c")).
          map(_.toUpperCase).
          sorted.
          forEach(println)
C1
C2

/*
 Arrays.stream(new int[] {1, 2, 3})
     .map(n -> 2 * n + 1)
     .average()
     .ifPresent(System.out::println);  // 5.0
 */
scala> Arrays.stream(Array(1, 2, 3)).
          map(n => 2 * n + 1).average.ifPresent(println)
5.0

/*
 Stream.of("a1", "a2", "a3")
     .map(s -> s.substring(1))
     .mapToInt(Integer::parseInt)
     .max()
     .ifPresent(System.out::println);  // 3
 */
scala> Stream.of("a1", "a2", "a3").
           map[String](_ substring 1).
           mapToInt(Integer.parseInt).
           max.
           ifPresent(println)
3

// wildcard capture is tricky, whence the `map[String]` above
scala> Stream.of("a1", "a2", "a3").map(_ substring 1)
res6: java.util.stream.Stream[?0] = java.util.stream.ReferencePipeline$3@435871cb

/*
 Stream.of(1.0, 2.0, 3.0)
     .mapToInt(Double::intValue)
     .mapToObj(i -> "a" + i)
     .forEach(System.out::println);
 */
scala> Stream.of(1.0, 2.0, 3.0).mapToInt(_.intValue).
          mapToObj(i => "a" + i).forEach(println)
a1
a2
a3

/*
 Stream.of("d2", "a2", "b1", "b3", "c")
     .filter(s -> {
         System.out.println("filter: " + s);
         return s.startsWith("a");
     })
     .sorted((s1, s2) -> {
         System.out.printf("sort: %s; %s\n", s1, s2);
         return s1.compareTo(s2);
     })
     .map(s -> {
         System.out.println("map: " + s);
         return s.toUpperCase();
     })
     .forEach(s -> System.out.println("forEach: " + s));
 */
scala> Stream of ("d2", "a2", "b1", "b3", "c") filter { s =>
            println("filter: " + s)
            s.startsWith("a")
        } sorted { (s1, s2) =>
            println(f"sort: $s1%s; $s2%s\n")
            s1.compareTo(s2)
        } map { s =>
            println("map: " + s)
            s.toUpperCase
        } forEach { s =>
            println("forEach: " + s)
        }
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
map: a2
forEach: A2

```


</script></section> <section data-markdown><script type="text/template">


## SAM Synthesis

```scala
// When you say
Stream of ("d2", "a2", "b1", "b3", "c") filter { s =>
   println(s"filter: $s"); true
}

// scalac generates
Stream of ("d2", "a2", "b1", "b3", "c") filter {
   def test$body(s: String) = { println(s"filter: $s"); true }

   // compiles to invokedynamic of LambdaMetaFactory:
   (s: String) => test$body(s) //: Predicate, sam = `test`
}
```




</script></section>  </section>
<!- --------------------- WHAT'S IN FP ----------------------------------------------- -->
<section> <section data-markdown><script type="text/template">


# My Idea of FP

</script></section> <section data-markdown><script type="text/template">

## OO's complement
#### *Small* units of functionality over *known* set of types

</script></section> <section data-markdown><script type="text/template">

## My idea of P
### Express, Understand & Maintain
  - immutable first (val <> var, expr <> stmt, recursion)
  - pattern matching (analysis of input determines output)
  - local methods (divide & conquer)
  - (de)compose safely, guided by types
  - type inference (best types are unseen -- e.g., definition-site variance)

</script></section> <section data-markdown><script type="text/template">


{'fraction_non_alphanumeric': 0.1875863098570522, 'fraction_numerical': 0.03299369238233867, 'mean_word_length': 3.3412184057031755, 'pattern_counts': {'":': 0, '<': 435, '<?xml version=': 0, '>': 484, 'https://': 19, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3255213', 'n_tokens_mistral': 9704, 'n_tokens_neox': 8887, 'n_words': 2286}