SlideShare a Scribd company logo
1 of 33
Download to read offline
WhatYou Need To
Know About
@jamie_allen
Jamie	
  Allen
•Director	
  of	
  Consulting	
  
•User	
  of	
  Lambdas	
  on	
  the	
  JVM	
  for	
  4+	
  years
@jamie_allen
I	
  Love	
  Functional	
  
Programming!
•Functional	
  Programming	
  is:
•Immutable	
  state
•Referential	
  transparency
•Functions	
  as	
  first-­‐class	
  citizens
@jamie_allen
What	
  is	
  a	
  Lambda?
•A	
  Function	
  Literal
•A	
  function	
  that	
  is	
  not	
  bound	
  to	
  a	
  name,	
  to	
  
be	
  used	
  only	
  within	
  the	
  context	
  of	
  where	
  
it	
  is	
  defined
•Merely	
  an	
  implementation	
  detail	
  of	
  
Functional	
  Programming!
@jamie_allen
Java	
  8
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
public class LambdaDemo {
public static void main(String... args) {
final List<Integer> numbers =
Arrays.asList(1, 2, 3);
final List<Integer> numbersPlusOne =
numbers.stream().map(number -> number + 1).
collect(Collectors.toList());
}
}
λ
@jamie_allen
Scala
object LambdaDemo extends App {
val numbers = List(1, 2, 3)
val numbersPlusOne =
numbers.map(number => number + 1)
}
λ
@jamie_allen
Clojure
(ns LambdaDemo.core)
(defn -main [& args]
(println(map #(+ % 1) [1, 2, 3])))
λ
@jamie_allen
JRuby
require "java"
array = [1, 2, 3]
array.collect! do |n|
n + 1
end
λ
@jamie_allen
So	
  What	
  Is	
  The	
  
Problem?
@jamie_allen
Not	
  Reusable
•Lambdas	
  are	
  limited	
  in	
  scope	
  to	
  their	
  call	
  
site
•You	
  cannot	
  reuse	
  the	
  functionality	
  
elsewhere
@jamie_allen
Not	
  Testable	
  in	
  
Isolation
•How	
  do	
  you	
  test	
  code	
  that	
  does	
  not	
  have	
  
a	
  name	
  through	
  which	
  you	
  can	
  call	
  it?
•You	
  can	
  only	
  test	
  lambdas	
  in	
  the	
  context	
  
of	
  their	
  call	
  site
@jamie_allen
Maintainability
•Developers	
  have	
  to	
  read	
  through	
  the	
  
lambda	
  to	
  figure	
  out	
  what	
  it’s	
  trying	
  to	
  do
•The	
  more	
  complex	
  the	
  lambda,	
  the	
  
harder	
  this	
  is	
  to	
  do
•Waste	
  of	
  valuable	
  development	
  time
@jamie_allen
Lousy	
  Stack	
  Traces
•Compilers	
  have	
  to	
  come	
  up	
  with	
  generic	
  
names	
  for	
  the	
  classes	
  that	
  represent	
  the	
  
lambdas	
  on	
  the	
  JVM,	
  called	
  “name	
  
mangling”
•The	
  stack	
  trace	
  output	
  tells	
  you	
  very	
  little	
  
about	
  where	
  the	
  problem	
  occurred
@jamie_allen
Java	
  8
final List<Integer> numbersPlusOne =
numbers.stream().map(number -> number / 0).
collect(Collectors.toList());
Exception in thread "main" java.lang.ArithmeticException: / by zero
at LambdaDemo.lambda$0(LambdaDemo.java:1)
at LambdaDemo$$Lambda$1.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:188)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:467)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:457)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:710)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:231)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:474)
at LambdaDemo.main(LambdaDemo.java:9)
wat
@jamie_allen
Scala
val numbersPlusOne = numbers.map(number => number / 0)
Exception in thread "main" java.lang.ArithmeticException: / by zero
at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:23)
at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:23)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.Range.foreach(Range.scala:141)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:23)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
at scala.App$class.main(App.scala:71)
at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22)
at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala)
wat
@jamie_allen
Clojure
println(map #(/ % 0) [1, 2, 3])))
Exception in thread "main" (java.lang.ArithmeticException: Divide by zero
at clojure.lang.Numbers.divide(Numbers.java:156)
at clojure.lang.Numbers.divide(Numbers.java:3671)
at helloclj.core$_main$fn__10.invoke(core.clj:5)
at clojure.core$map$fn__4087.invoke(core.clj:2432)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.RT.seq(RT.java:473)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$print_sequential.invoke(core_print.clj:46)
at clojure.core$fn__5270.invoke(core_print.clj:140)
at clojure.lang.MultiFn.invoke(MultiFn.java:167)
at clojure.core$pr_on.invoke(core.clj:3266)
at clojure.core$pr.invoke(core.clj:3278)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$prn.doInvoke(core.clj:3311)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$println.doInvoke(core.clj:3331)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at helloclj.core$_main.invoke(core.clj:5)
at clojure.lang.Var.invoke(Var.java:411)
...
at clojure.main.main(main.java:37)
wat
@jamie_allen
JRuby
array.collect! do |n|
n / 0
ZeroDivisionError: divided by 0
/ at org/jruby/RubyFixnum.java:547
(root) at HelloWorld.rb:11
collect! at org/jruby/RubyArray.java:2385
(root) at HelloWorld.rb:10
not half bad, really
@jamie_allen
Difficult	
  Debugging
•Debuggers	
  on	
  the	
  JVM	
  can	
  only	
  
disambiguate	
  code	
  at	
  the	
  source	
  line,	
  so	
  
you	
  need	
  to	
  make	
  your	
  lambdas	
  multi-­‐line	
  
to	
  be	
  able	
  to	
  step	
  through	
  them
•Some	
  languages	
  allow	
  lambdas	
  to	
  use	
  
“placeholders”	
  instead	
  of	
  names,	
  which	
  
cannot	
  currently	
  be	
  “watched”	
  in	
  a	
  
debugger
@jamie_allen
Digression:	
  Lambdas	
  
vs	
  Closures
•Closures	
  are	
  merely	
  lambdas	
  that	
  “close	
  
over”	
  state	
  available	
  to	
  them	
  from	
  their	
  
enclosing	
  scope
val x = 1
(1 to 20).map(num => num + x)
@jamie_allen
Closing	
  Over	
  State
•Lambdas	
  have	
  access	
  to	
  all	
  state	
  within	
  
their	
  enclosing	
  scope
•It	
  is	
  very	
  easy	
  to	
  manipulate	
  these	
  values	
  
and	
  change	
  something	
  important
•If	
  the	
  lambda	
  is	
  in	
  use	
  for	
  a	
  Future	
  
operation,	
  this	
  can	
  lead	
  to	
  race	
  conditions
@jamie_allen
SOLUTION
•We	
  want	
  to	
  maintain	
  our	
  ability	
  to	
  
program	
  in	
  a	
  functional	
  style,	
  while	
  
having	
  something	
  usable	
  in	
  production
@jamie_allen
Named	
  Functions?
•Seems	
  like	
  it	
  would	
  help,	
  but	
  it	
  depends	
  
on	
  the	
  compiler	
  and	
  how	
  it	
  manages	
  the	
  
“scope”	
  of	
  that	
  function
•It	
  is	
  possible	
  that	
  the	
  stack	
  trace	
  will	
  still	
  
not	
  show	
  you	
  the	
  name	
  of	
  the	
  function	
  
you	
  used
@jamie_allen
Named	
  Function
object LambdaTest extends App {
val addOneToValue = (x: Int) => x + 1
val myList = (1 to 20).map(addOneToValue(_))
println(myList)
}
@jamie_allen
Stack	
  Trace?
val badFunction = (x: Int) => x / 0
val myList = (1 to 20).map(badFunction(_))
Exception in thread "main" java.lang.ArithmeticException: / by zero
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply$mcII$sp(LambdaPlayground.scala:23)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$2.apply(LambdaPlayground.scala:24)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$2.apply(LambdaPlayground.scala:24)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.immutable.Range.foreach(Range.scala:141)
	 at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
	 at scala.collection.AbstractTraversable.map(Traversable.scala:105)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:24)
	 at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
	 at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.collection.immutable.List.foreach(List.scala:318)
	 at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
	 at scala.App$class.main(App.scala:71)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala)
wat
@jamie_allen
Eta	
  Expansion
•“Lifting”,	
  or	
  coercing,	
  a	
  method	
  to	
  be	
  
used	
  as	
  a	
  function
•Must	
  meet	
  the	
  contract	
  of	
  the	
  lambda	
  
usage	
  defined	
  by	
  the	
  compiler	
  in	
  use,	
  
such	
  as	
  one	
  argument	
  for	
  the	
  value	
  to	
  be	
  
manipulated
@jamie_allen
Methods	
  as	
  Functions
•In	
  Scala,	
  if	
  we	
  use	
  a	
  method,	
  it	
  can	
  be	
  
“lifted”	
  into	
  a	
  function	
  and	
  give	
  us	
  
everything	
  we	
  need
•But	
  what	
  syntax	
  should	
  we	
  use?
@jamie_allen
Stack	
  Trace	
  of	
  Method
def badFunction = (x: Int) => x / 0
val myList = (1 to 20).map(badFunction(_))
Exception in thread "main" java.lang.ArithmeticException: / by zero
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$badFunction$1.apply$mcII$sp(LambdaPlayground.scala:23)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:24)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:24)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.immutable.Range.foreach(Range.scala:141)
	 at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
	 at scala.collection.AbstractTraversable.map(Traversable.scala:105)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:24)
	 at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
	 at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.collection.immutable.List.foreach(List.scala:318)
	 at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
	 at scala.App$class.main(App.scala:71)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala)
Yay!
@jamie_allen
Digression
•You	
  can	
  define	
  your	
  function	
  like	
  this,	
  but	
  
“def”	
  is	
  not	
  stable	
  -­‐	
  it	
  will	
  re-­‐evaluate	
  the	
  
right	
  side	
  of	
  the	
  equals	
  sign	
  and	
  return	
  a	
  
new	
  but	
  identical	
  function	
  each	
  time!
def badFunction = (x: Int) => x / 0
•Better	
  to	
  stick	
  with	
  simple	
  method	
  syntax
def badFunction(x: Int) = x / 0
@jamie_allen
Stack	
  Trace	
  of	
  Method
def badFunction(x: Int) = x / 0
val myList = (1 to 20).map(badFunction(_))
Exception in thread "main" java.lang.ArithmeticException: / by zero
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.badFunction(LambdaPlayground.scala:24)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:25)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:25)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
	 at scala.collection.immutable.Range.foreach(Range.scala:141)
	 at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
	 at scala.collection.AbstractTraversable.map(Traversable.scala:105)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:25)
	 at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
	 at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.App$$anonfun$main$1.apply(App.scala:71)
	 at scala.collection.immutable.List.foreach(List.scala:318)
	 at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
	 at scala.App$class.main(App.scala:71)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22)
	 at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala)
Even better!
@jamie_allen
Benefits
•Can’t	
  close	
  over	
  variables
•Internal	
  variables	
  are	
  operands
•Better	
  stack	
  traces
•More	
  debuggable
•More	
  testable
•Easier	
  maintenance
•Reusability
@jamie_allen
Rule	
  of	
  Thumb
•Keep	
  lambda	
  usage	
  for	
  the	
  smallest	
  
expressions
•Externalize	
  anything	
  more	
  than	
  the	
  most	
  
basic	
  logic	
  into	
  methods
@jamie_allen
Language	
  Creators
•Language	
  designers	
  need	
  to	
  help	
  you	
  
with	
  this!
•At	
  Typesafe,	
  we’re	
  making	
  our	
  Scala	
  IDE	
  
debugger	
  more	
  lambda-­‐friendly	
  with	
  each	
  
version
@jamie_allen
Thank	
  You!
•Questions?

More Related Content

What's hot

Java SE 8 - New Features
Java SE 8 - New FeaturesJava SE 8 - New Features
Java SE 8 - New FeaturesNaveen Hegde
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffJAX London
 
Java 8 - Project Lambda
Java 8 - Project LambdaJava 8 - Project Lambda
Java 8 - Project LambdaRahman USTA
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scalaStratio
 
Scala Presentation Work
Scala Presentation WorkScala Presentation Work
Scala Presentation WorkSkills Matter
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8Talha Ocakçı
 
Java ap is you should know
Java ap is you should knowJava ap is you should know
Java ap is you should knowHendrik Ebbers
 
Functional Programming Essentials
Functional Programming EssentialsFunctional Programming Essentials
Functional Programming EssentialsKelley Robinson
 
Refactoring to Scala DSLs and LiftOff 2009 Recap
Refactoring to Scala DSLs and LiftOff 2009 RecapRefactoring to Scala DSLs and LiftOff 2009 Recap
Refactoring to Scala DSLs and LiftOff 2009 RecapDave Orme
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the futureAnsviaLab
 
Android Auto instrumentation
Android Auto instrumentationAndroid Auto instrumentation
Android Auto instrumentationPrzemek Jakubczyk
 
Aspects of love slideshare
Aspects of love slideshareAspects of love slideshare
Aspects of love slideshareMark Baker
 
Java 8 - A step closer to Parallelism
Java 8 - A step closer to ParallelismJava 8 - A step closer to Parallelism
Java 8 - A step closer to Parallelismjbugkorea
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaDerek Chen-Becker
 

What's hot (20)

Java 8 Features
Java 8 FeaturesJava 8 Features
Java 8 Features
 
Java SE 8 - New Features
Java SE 8 - New FeaturesJava SE 8 - New Features
Java SE 8 - New Features
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
Java 8 - Project Lambda
Java 8 - Project LambdaJava 8 - Project Lambda
Java 8 - Project Lambda
 
Functional programming in scala
Functional programming in scalaFunctional programming in scala
Functional programming in scala
 
Intro to Scala
 Intro to Scala Intro to Scala
Intro to Scala
 
Scala Presentation Work
Scala Presentation WorkScala Presentation Work
Scala Presentation Work
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 Overview
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Java ap is you should know
Java ap is you should knowJava ap is you should know
Java ap is you should know
 
Functional Programming Essentials
Functional Programming EssentialsFunctional Programming Essentials
Functional Programming Essentials
 
Java SE 8 library design
Java SE 8 library designJava SE 8 library design
Java SE 8 library design
 
Refactoring to Scala DSLs and LiftOff 2009 Recap
Refactoring to Scala DSLs and LiftOff 2009 RecapRefactoring to Scala DSLs and LiftOff 2009 Recap
Refactoring to Scala DSLs and LiftOff 2009 Recap
 
Scala : language of the future
Scala : language of the futureScala : language of the future
Scala : language of the future
 
Java 8 Bootcamp
Java 8 BootcampJava 8 Bootcamp
Java 8 Bootcamp
 
Android Auto instrumentation
Android Auto instrumentationAndroid Auto instrumentation
Android Auto instrumentation
 
Java 8 Intro - Core Features
Java 8 Intro - Core FeaturesJava 8 Intro - Core Features
Java 8 Intro - Core Features
 
Aspects of love slideshare
Aspects of love slideshareAspects of love slideshare
Aspects of love slideshare
 
Java 8 - A step closer to Parallelism
Java 8 - A step closer to ParallelismJava 8 - A step closer to Parallelism
Java 8 - A step closer to Parallelism
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to Scala
 

Similar to What you need to know about Lambdas - Jamie Allen

What You Need to Know about Lambdas
What You Need to Know about LambdasWhat You Need to Know about Lambdas
What You Need to Know about LambdasRyan Knight
 
Project Lambda: Evolution of Java
Project Lambda: Evolution of JavaProject Lambda: Evolution of Java
Project Lambda: Evolution of JavaCan Pekdemir
 
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time APIModern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time APIGanesh Samarthyam
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scalashinolajla
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhHarmeet Singh(Taara)
 
whats new in java 8
whats new in java 8 whats new in java 8
whats new in java 8 Dori Waldman
 
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)jaxLondonConference
 
Java 8 lambdas expressions
Java 8 lambdas expressionsJava 8 lambdas expressions
Java 8 lambdas expressionsLars Lemos
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8IndicThreads
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Codemotion
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1Todor Kolev
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1Todor Kolev
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1Todor Kolev
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern JavaSina Madani
 

Similar to What you need to know about Lambdas - Jamie Allen (20)

What You Need to Know about Lambdas
What You Need to Know about LambdasWhat You Need to Know about Lambdas
What You Need to Know about Lambdas
 
Java8
Java8Java8
Java8
 
Project Lambda: Evolution of Java
Project Lambda: Evolution of JavaProject Lambda: Evolution of Java
Project Lambda: Evolution of Java
 
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time APIModern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Functional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singhFunctional programming in java 8 by harmeet singh
Functional programming in java 8 by harmeet singh
 
whats new in java 8
whats new in java 8 whats new in java 8
whats new in java 8
 
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)What You Need to Know About Lambdas - Jamie Allen (Typesafe)
What You Need to Know About Lambdas - Jamie Allen (Typesafe)
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
 
Java 8 lambdas expressions
Java 8 lambdas expressionsJava 8 lambdas expressions
Java 8 lambdas expressions
 
Colloquium Report
Colloquium ReportColloquium Report
Colloquium Report
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
 
Lazy java
Lazy javaLazy java
Lazy java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1
 
Java findamentals1
Java findamentals1Java findamentals1
Java findamentals1
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern Java
 

Recently uploaded

Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 

Recently uploaded (20)

Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 

What you need to know about Lambdas - Jamie Allen

  • 2. @jamie_allen Jamie  Allen •Director  of  Consulting   •User  of  Lambdas  on  the  JVM  for  4+  years
  • 3. @jamie_allen I  Love  Functional   Programming! •Functional  Programming  is: •Immutable  state •Referential  transparency •Functions  as  first-­‐class  citizens
  • 4. @jamie_allen What  is  a  Lambda? •A  Function  Literal •A  function  that  is  not  bound  to  a  name,  to   be  used  only  within  the  context  of  where   it  is  defined •Merely  an  implementation  detail  of   Functional  Programming!
  • 5. @jamie_allen Java  8 import java.util.List; import java.util.Arrays; import java.util.stream.Collectors; public class LambdaDemo { public static void main(String... args) { final List<Integer> numbers = Arrays.asList(1, 2, 3); final List<Integer> numbersPlusOne = numbers.stream().map(number -> number + 1). collect(Collectors.toList()); } } λ
  • 6. @jamie_allen Scala object LambdaDemo extends App { val numbers = List(1, 2, 3) val numbersPlusOne = numbers.map(number => number + 1) } λ
  • 7. @jamie_allen Clojure (ns LambdaDemo.core) (defn -main [& args] (println(map #(+ % 1) [1, 2, 3]))) λ
  • 8. @jamie_allen JRuby require "java" array = [1, 2, 3] array.collect! do |n| n + 1 end λ
  • 9. @jamie_allen So  What  Is  The   Problem?
  • 10. @jamie_allen Not  Reusable •Lambdas  are  limited  in  scope  to  their  call   site •You  cannot  reuse  the  functionality   elsewhere
  • 11. @jamie_allen Not  Testable  in   Isolation •How  do  you  test  code  that  does  not  have   a  name  through  which  you  can  call  it? •You  can  only  test  lambdas  in  the  context   of  their  call  site
  • 12. @jamie_allen Maintainability •Developers  have  to  read  through  the   lambda  to  figure  out  what  it’s  trying  to  do •The  more  complex  the  lambda,  the   harder  this  is  to  do •Waste  of  valuable  development  time
  • 13. @jamie_allen Lousy  Stack  Traces •Compilers  have  to  come  up  with  generic   names  for  the  classes  that  represent  the   lambdas  on  the  JVM,  called  “name   mangling” •The  stack  trace  output  tells  you  very  little   about  where  the  problem  occurred
  • 14. @jamie_allen Java  8 final List<Integer> numbersPlusOne = numbers.stream().map(number -> number / 0). collect(Collectors.toList()); Exception in thread "main" java.lang.ArithmeticException: / by zero at LambdaDemo.lambda$0(LambdaDemo.java:1) at LambdaDemo$$Lambda$1.apply(Unknown Source) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:188) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:467) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:457) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:710) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:231) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:474) at LambdaDemo.main(LambdaDemo.java:9) wat
  • 15. @jamie_allen Scala val numbersPlusOne = numbers.map(number => number / 0) Exception in thread "main" java.lang.ArithmeticException: / by zero at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:23) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:23) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.Range.foreach(Range.scala:141) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:23) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) at scala.App$class.main(App.scala:71) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala) wat
  • 16. @jamie_allen Clojure println(map #(/ % 0) [1, 2, 3]))) Exception in thread "main" (java.lang.ArithmeticException: Divide by zero at clojure.lang.Numbers.divide(Numbers.java:156) at clojure.lang.Numbers.divide(Numbers.java:3671) at helloclj.core$_main$fn__10.invoke(core.clj:5) at clojure.core$map$fn__4087.invoke(core.clj:2432) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:60) at clojure.lang.RT.seq(RT.java:473) at clojure.core$seq.invoke(core.clj:133) at clojure.core$print_sequential.invoke(core_print.clj:46) at clojure.core$fn__5270.invoke(core_print.clj:140) at clojure.lang.MultiFn.invoke(MultiFn.java:167) at clojure.core$pr_on.invoke(core.clj:3266) at clojure.core$pr.invoke(core.clj:3278) at clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.RestFn.applyTo(RestFn.java:132) at clojure.core$apply.invoke(core.clj:601) at clojure.core$prn.doInvoke(core.clj:3311) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invoke(core.clj:601) at clojure.core$println.doInvoke(core.clj:3331) at clojure.lang.RestFn.invoke(RestFn.java:408) at helloclj.core$_main.invoke(core.clj:5) at clojure.lang.Var.invoke(Var.java:411) ... at clojure.main.main(main.java:37) wat
  • 17. @jamie_allen JRuby array.collect! do |n| n / 0 ZeroDivisionError: divided by 0 / at org/jruby/RubyFixnum.java:547 (root) at HelloWorld.rb:11 collect! at org/jruby/RubyArray.java:2385 (root) at HelloWorld.rb:10 not half bad, really
  • 18. @jamie_allen Difficult  Debugging •Debuggers  on  the  JVM  can  only   disambiguate  code  at  the  source  line,  so   you  need  to  make  your  lambdas  multi-­‐line   to  be  able  to  step  through  them •Some  languages  allow  lambdas  to  use   “placeholders”  instead  of  names,  which   cannot  currently  be  “watched”  in  a   debugger
  • 19. @jamie_allen Digression:  Lambdas   vs  Closures •Closures  are  merely  lambdas  that  “close   over”  state  available  to  them  from  their   enclosing  scope val x = 1 (1 to 20).map(num => num + x)
  • 20. @jamie_allen Closing  Over  State •Lambdas  have  access  to  all  state  within   their  enclosing  scope •It  is  very  easy  to  manipulate  these  values   and  change  something  important •If  the  lambda  is  in  use  for  a  Future   operation,  this  can  lead  to  race  conditions
  • 21. @jamie_allen SOLUTION •We  want  to  maintain  our  ability  to   program  in  a  functional  style,  while   having  something  usable  in  production
  • 22. @jamie_allen Named  Functions? •Seems  like  it  would  help,  but  it  depends   on  the  compiler  and  how  it  manages  the   “scope”  of  that  function •It  is  possible  that  the  stack  trace  will  still   not  show  you  the  name  of  the  function   you  used
  • 23. @jamie_allen Named  Function object LambdaTest extends App { val addOneToValue = (x: Int) => x + 1 val myList = (1 to 20).map(addOneToValue(_)) println(myList) }
  • 24. @jamie_allen Stack  Trace? val badFunction = (x: Int) => x / 0 val myList = (1 to 20).map(badFunction(_)) Exception in thread "main" java.lang.ArithmeticException: / by zero at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply$mcII$sp(LambdaPlayground.scala:23) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$2.apply(LambdaPlayground.scala:24) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$2.apply(LambdaPlayground.scala:24) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.Range.foreach(Range.scala:141) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:24) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) at scala.App$class.main(App.scala:71) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala) wat
  • 25. @jamie_allen Eta  Expansion •“Lifting”,  or  coercing,  a  method  to  be   used  as  a  function •Must  meet  the  contract  of  the  lambda   usage  defined  by  the  compiler  in  use,   such  as  one  argument  for  the  value  to  be   manipulated
  • 26. @jamie_allen Methods  as  Functions •In  Scala,  if  we  use  a  method,  it  can  be   “lifted”  into  a  function  and  give  us   everything  we  need •But  what  syntax  should  we  use?
  • 27. @jamie_allen Stack  Trace  of  Method def badFunction = (x: Int) => x / 0 val myList = (1 to 20).map(badFunction(_)) Exception in thread "main" java.lang.ArithmeticException: / by zero at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$badFunction$1.apply$mcII$sp(LambdaPlayground.scala:23) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:24) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:24) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.Range.foreach(Range.scala:141) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:24) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) at scala.App$class.main(App.scala:71) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala) Yay!
  • 28. @jamie_allen Digression •You  can  define  your  function  like  this,  but   “def”  is  not  stable  -­‐  it  will  re-­‐evaluate  the   right  side  of  the  equals  sign  and  return  a   new  but  identical  function  each  time! def badFunction = (x: Int) => x / 0 •Better  to  stick  with  simple  method  syntax def badFunction(x: Int) = x / 0
  • 29. @jamie_allen Stack  Trace  of  Method def badFunction(x: Int) = x / 0 val myList = (1 to 20).map(badFunction(_)) Exception in thread "main" java.lang.ArithmeticException: / by zero at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.badFunction(LambdaPlayground.scala:24) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:25) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$$anonfun$1.apply(LambdaPlayground.scala:25) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.Range.foreach(Range.scala:141) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$delayedInit$body.apply(LambdaPlayground.scala:25) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) at scala.App$class.main(App.scala:71) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest$.main(LambdaPlayground.scala:22) at org.jamieallen.effectiveakka.pattern.extra.LambdaTest.main(LambdaPlayground.scala) Even better!
  • 30. @jamie_allen Benefits •Can’t  close  over  variables •Internal  variables  are  operands •Better  stack  traces •More  debuggable •More  testable •Easier  maintenance •Reusability
  • 31. @jamie_allen Rule  of  Thumb •Keep  lambda  usage  for  the  smallest   expressions •Externalize  anything  more  than  the  most   basic  logic  into  methods
  • 32. @jamie_allen Language  Creators •Language  designers  need  to  help  you   with  this! •At  Typesafe,  we’re  making  our  Scala  IDE   debugger  more  lambda-­‐friendly  with  each   version