SlideShare ist ein Scribd-Unternehmen logo
1 von 111
Downloaden Sie, um offline zu lesen
Functional Scaλa

                   Functional Programming with Scala

          25.08.2010
          Java User Group Frankfurt / Main
          Mario Gleichmann




Mario Gleichmann                                       JUG Frankfurt / Main
Introduction

               Mario Gleichmann

                   site:   www.mg-informatik.de


                   blog:   'brain driven development'
                           gleichmann.wordpress.com


                   mail:   mario.gleichmann@mg-informatik.de



Mario Gleichmann                      2                        JUG Frankfurt / Main
What is Functional Programming ?


                             Imperative Style

                         int sum = 0;

                         for( int i=1; i<=10; i++ ){
                              sum = sum + i;
                         }




Mario Gleichmann                     3                 JUG Frankfurt / Main
What is Functional Programming ?


                               Imperative Style

                           int sum = 0;

                           for( int i=1; i<=10; i++ ){
                                sum = sum + i;
                           }

                                 Instruction based

                   Computation method is variable assignment

Mario Gleichmann                       4                       JUG Frankfurt / Main
What is Functional Programming ?


                          Functional Style


                      val sum = fold( 1 to 10, _+_ )




Mario Gleichmann                    5                  JUG Frankfurt / Main
What is Functional Programming ?


                          Functional Style


                      val sum = fold( 1 to 10, add )




Mario Gleichmann                    6                  JUG Frankfurt / Main
What is Functional Programming ?


                             Functional Style


                        val sum = fold( 1 to 10, add )




                               Expression based

                   Computation method is function application

Mario Gleichmann                      7   fcn                   JUG Frankfurt / Main
What makes a Function ?


                      Function Literals



                     ( x :Int, y :Int ) => x + y




Mario Gleichmann                 8   Fcn val       JUG Frankfurt / Main
What makes a Function ?


                                Function Values



                   val add = ( x :Int, y :Int ) => x + y




Mario Gleichmann                          9   Elm          JUG Frankfurt / Main
What makes a Function ?


                                     Elements



                   val add = ( x :Int, y :Int ) => x + y


            Function name       Argument list        Function expression




Mario Gleichmann                           10   Tp                         JUG Frankfurt / Main
What makes a Function ?


                                 Function Types



                    val add = ( x :Int, y :Int ) => x + y



                   Type of add : ( Int , Int ) => Int




Mario Gleichmann                           11   Obj         JUG Frankfurt / Main
What makes a Function ?


                       Note : In Scala, everything is an Object



                   val add = ( x :Int, y :Int ) => x + y



                   val add = new Function2[ Int, Int, Int ] {
                        def apply( x :Int, y: Int ) : Int = x + y
                   }


Mario Gleichmann                               12   xplct Tp dcl    JUG Frankfurt / Main
What makes a Function ?


                                   Function Types



                   val add : ( Int, Int ) => Int = ( x :Int, y :Int ) => x + y


                         Explicit Type Declaration




Mario Gleichmann                             13   Shrt                      JUG Frankfurt / Main
What makes a Function ?


                                Argument Shortcuts

                                       Argument List omitted !

                   val add : ( Int, Int ) => Int =      _+_



                                      First Parameter     Second Parameter




Mario Gleichmann                             14   app                    JUG Frankfurt / Main
What makes a Function ?


                                 Function Application



                   val add : ( Int, Int ) => Int =          _+_


                             Function Application
                   ...

                   add( 3, 8 )           >> 11



Mario Gleichmann                             15   App obj         JUG Frankfurt / Main
What makes a Function ?


                                 Function Application



                   val add : ( Int, Int ) => Int =       _+_


                   ...

                   add( 3, 8 )           >> 11

                   add.apply( 3, 8 )     >> 11

Mario Gleichmann                             16   Mthd         JUG Frankfurt / Main
What makes a Function ?


                                             Methods
                   object Math{
                    ...

                       def mult( x :Int, y :Int ) : Int = x * y

                       ...
                   }




Mario Gleichmann                                  17   Elm        JUG Frankfurt / Main
What makes a Function ?


                                          Elements
                   object Math{
                                                             Result Type

                    def mult( x :Int, y :Int ) : Int = x * y


           }
          Method name             Argument list              Method body




Mario Gleichmann                                  18   Tpe                 JUG Frankfurt / Main
What makes a Function ?


                                     Method Types



                   def mult( x :Int, y :Int ) : Int = x * y



        Type of mult : ( Int , Int )           Int




Mario Gleichmann                              19   clsrs      JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit

                   Type of isAdult : Int => Boolean




Mario Gleichmann                          20   Bnd var          JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit



                                     Bound variable




Mario Gleichmann                           21   Fre var         JUG Frankfurt / Main
Closures



                   var limit = 18                        Free variable


                   val isAdult = ( age :Int ) => age >= limit




Mario Gleichmann                          22   Opn Trm                   JUG Frankfurt / Main
Closures


                                    Open Terms
                   var limit = 18                          Free variable


                   val isAdult = ( age :Int ) => age >= limit



                                    'Open term'




Mario Gleichmann                            23   Cls ovr                   JUG Frankfurt / Main
Closures



                                                          'Closing over'
                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit




Mario Gleichmann                          24   Clsd trm                    JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit




                                    'Closed term'




Mario Gleichmann                             25   appl          JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit

                   val isGermanAdult = isAdult( 20 )       >> true




Mario Gleichmann                           26   Lim chng             JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit

                   val isGermanAdult = isAdult( 20 )         >> true


                   limit = 21

                   val isUnitesStatesAdult = isAdult( 20 )


Mario Gleichmann                            27   Dym bnd               JUG Frankfurt / Main
Closures



                   var limit = 18

                   val isAdult = ( age :Int ) => age >= limit

                   val isGermanAdult = isAdult( 20 )             >> true

                                                          'Dynamic' bound
                   limit = 21

                   val isUnitesStatesAdult = isAdult( 20 )       >> false


Mario Gleichmann                            28   Dta Tp                     JUG Frankfurt / Main
Data types



            data Natural = Zero | Succ( Natural )


                            'Constructors'




Mario Gleichmann                       29    smp    JUG Frankfurt / Main
Data types



            data Natural = Zero | Succ( Natural )


            val zero = Zero

            val one = Succ( Zero )

            val four = Succ( Succ ( Succ ( Succ ( Zero ) ) ) )




Mario Gleichmann                       30   Int                  JUG Frankfurt / Main
Data types



            data Integer = … , -3, -2, -1, 0, 1, 2, 3, ...


            val zero = 0

            val one = 1

            val four = 4




Mario Gleichmann                        31   Fib pttn        JUG Frankfurt / Main
Operating on data types


                            Pattern Matching


            fibonacci( 0 ) → 0

            fibonacci( 1 ) → 1

            fibonacci( n ) → fibonacci( n – 1 ) + fibonacci( n – 2 )




Mario Gleichmann                     32   Ptt mtc               JUG Frankfurt / Main
Operating on data types


                                  Pattern Matching


            val fib : Int => Int = ( i :Int ) => i match {

                   case 0 => 0

                   case 1 => 1

                   case n => fib( n - 1 ) + fib( n - 2 )
            }


Mario Gleichmann                            33   othw        JUG Frankfurt / Main
Operating on data types


                                    Pattern Matching


            val fib : Int => Int = ( i :Int ) => i match {

                   case 0 => 0

                   case 1 => 1

                   case _ => fib( i - 1 ) + fib( i - 2 )
            }
                      'otherwise'

Mario Gleichmann                             34   Lst        JUG Frankfurt / Main
Algebraic Datatypes




            data List a = Nil | Cons a ( List a )




Mario Gleichmann                     35   Cnstr     JUG Frankfurt / Main
Algebraic Datatypes


                           Value Constructors


            data List[T] = Nil | T :: List[T]


                            'Constructors'




Mario Gleichmann                         36   smp   JUG Frankfurt / Main
Algebraic Datatypes


                           Value Construction


            data List[T] = Nil | T :: List[T]



            val emptyList = Nil




Mario Gleichmann                       37   smp   JUG Frankfurt / Main
Algebraic Datatypes


                             Value Construction


            data List[T] = Nil | T :: List[T]



            val emptyList = Nil

            val anotherList = 5 :: 4 :: 3 :: 2 :: 1 :: Nil




Mario Gleichmann                         38   Rght assoc     JUG Frankfurt / Main
Algebraic Datatypes


                             Value Construction


            data List[T] = Nil | T :: List[T]



            val emptyList = Nil

            val anotherList = 5 :: ( 4 :: ( 3 :: ( 2 :: (1 :: Nil ) ) ) )




Mario Gleichmann                           39   Smp tl                      JUG Frankfurt / Main
Operating on algebraic data types


                                Pattern Matching


            def tail [T] ( list :List[T] ) = list match {

                   case Nil    => Nil

                   case x :: xs => xs
            }

           Type of tail: [T] ( List[T] ) List[T]


Mario Gleichmann                           40   De con      JUG Frankfurt / Main
Operating on algebraic data types


                                   Pattern Matching


            def tail [T] ( list :List[T] ) = list match {

                   case Nil      => Nil

                   case x :: xs => xs
            }

                     'De-Construction'



Mario Gleichmann                           41   Dnt cr      JUG Frankfurt / Main
Operating on algebraic data types


                                   Pattern Matching


            val length : List[ _ ] => Int = _ match {

                   case Nil       => 0

                   case _ :: xs => 1 + length( xs )
            }
                    'some head' (don't care)


           Type of length: ( List[ _ ] ) => Int

Mario Gleichmann                               42   Grd    JUG Frankfurt / Main
Operating on algebraic data types


                                  Pattern Matching

      def insert[ T <% Ordered[ T ] ] ( elem :T, list :List[T] ) : List[T] =

         list match {

                   case Nil                                  => elem :: Nil

                   case x :: xs if elem <= x                 => elem :: x :: xs

                   case x :: xs                              => x :: insert( elem, xs )
         }
                                     Guard

Mario Gleichmann                               43   Smp Tr                                JUG Frankfurt / Main
Algebraic Datatypes


                          Example - Tree

         data Tree = Empty | Leaf Int | Node Int Tree Tree




Mario Gleichmann                  44   Cs clss               JUG Frankfurt / Main
Algebraic Datatypes


                               Example - Tree

         data Tree = Empty | Leaf Int | Node Int Tree Tree


         abstract case class Tree()
         case object Empty extends Tree
         case class Leaf( value: Int ) extends Tree
         case class Node( value: Int, left :Tree, right: Tree ) extends Tree




Mario Gleichmann                          45   insrt                       JUG Frankfurt / Main
Algebraic Datatypes


                   Buildin' an unbalanced, ordered Tree

    val insert :( Int, Tree ) => Tree = ( elem :Int, tree :Tree ) => tree match {

        case Empty                                        => Leaf( elem )

        case Node( x, left, right ) if elem < x           => Node( x, insert( elem, left ), right )

        case Node( x, left, right ) if elem >= x => Node( x, left, insert( elem, right ) )

        case Leaf( x ) if elem < x                        => Node( x, Leaf( elem ), Empty )

        case leaf @ Leaf( x ) if elem >= x                => Node( elem, leaf, Empty )

    }

Mario Gleichmann                              46   dpth                                     JUG Frankfurt / Main
Algebraic Datatypes


                                  Pattern Matching

       val depth :Tree => Int = _ match {

              case Empty                    => 0

              case Leaf( _ )                => 1

              case Node( _, left, right )   => 1 + max( depth( left ), depth( right ) )
       }




Mario Gleichmann                              47   Prt isb                      JUG Frankfurt / Main
Partial Functions


         case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int )


         val publisherRegionDE = ( isbn :Isbn ) => isbn match {

               case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 )
         }

         …

         publisherRegionDE( Isbn( 3, 677873, 8823 ) ) )           >> “D6“




Mario Gleichmann                            48   unmtch                     JUG Frankfurt / Main
Partial Functions


         case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int )


         val publisherRegionDE = ( isbn :Isbn ) => isbn match {

               case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 )
         }




                                                                       ?
         …

         publisherRegionDE( Isbn( 0, 677873, 8823 ) ) )           >>




Mario Gleichmann                            49   Mtch err                  JUG Frankfurt / Main
Partial Functions


         case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int )


         val publisherRegionDE = ( isbn :Isbn ) => isbn match {

               case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 )
         }

         …

         publisherRegionDE( Isbn( 0, 677873, 8823 ) ) )           >> MatchError




Mario Gleichmann                            50   Prt fnc                   JUG Frankfurt / Main
Partial Functions


         type =>?[-A, +B] = PartialFunction[A, B]


         val publisherRegionDE : Isbn =>? String = {

                   case Isbn( 3, pubNr, _ )   => "D" + ( pubNr.toString charAt 0 )
         }

         …

         publisherRegionDE.isDefinedAt( Isbn( 0, 677873, 8823 ) ) ) >> false




Mario Gleichmann                               51   chn                        JUG Frankfurt / Main
Partial Functions


                          Partial Function Chaining

      val publisherRegionUS : Isbn =>? String = {
              case Isbn( 0, pubNr, _ ) => …
              case Isbn( 1, pubNr, _ ) => ...
      }


      ...
      val allKnownPubs = publisherRegionDE orElse publisherRegionUS

      ...
      allKnownPubs( Isbn( 0, 677873, 8823 ) )            >> “WY“

Mario Gleichmann                            52   cmprn             JUG Frankfurt / Main
Comprehensions


                    Set Comprehensions (Mathematics)



                   { x2 | x ∈ { 1 .. 5 } }

                   >> Set : { 1, 4, 9, 16, 25 }



Mario Gleichmann                       53   Smp scla   JUG Frankfurt / Main
Comprehensions



            val pow :(Int,Int) => Int = ( base :Int, exp :Int ) =>
                   if( exp == 0 ) 1 else base * pow( base, exp - 1 )


                                       Range ...
            …
            val squares = for( x <- ( 1 to 5 ) ) yield pow( x, 2 )




Mario Gleichmann                         54   grn                      JUG Frankfurt / Main
Comprehensions



            val pow :(Int,Int) => Int = ( base :Int, exp :Int ) =>
                   if( exp == 0 ) 1 else base * pow( base, exp - 1 )


                                   … as Generator
            …
            val squares = for( x <- ( 1 to 5 ) ) yield pow( x, 2 )

            >> Seq( 1, 4, 9, 16, 25 )



Mario Gleichmann                         55   Mltp gen                 JUG Frankfurt / Main
Comprehensions


                            Multiple Generators

                                                                  Tuple2

            val pairs = for( x <- (1 to 3 ); y <- ( 1 to x ) ) yield (y,x)


            >> Seq( (1,1), (1,2), (2,2), (1,3), (2,3), (3,3) )




Mario Gleichmann                         56   Smp fltn                 JUG Frankfurt / Main
Comprehensions


                   Example – Flatten a List of Lists


            val flatten = ( xss :List[ List[Int] ] ) =>
                                   for( xs <- xss; x <- xs ) yield x


            ...
            flatten( List( List(1,2), List( 5,6,8 ), List( 21,23,24 ) ) )

            >> List(1, 2, 5, 6, 8, 21, 23, 24)

Mario Gleichmann                          57   Smp int fact                 JUG Frankfurt / Main
Comprehensions


                   Example – All factors of an Integer

      val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x

      ...                                              Guard

      factors( 15 )

      >> Seq( 1, 3, 5, 15 )




Mario Gleichmann                       58   def prm                     JUG Frankfurt / Main
Comprehensions


                   Example – Test 'prime' on Integer

      val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x

      ...

      val prime = ( n :Int ) => factors( n ).toList == List( 1, n )




Mario Gleichmann                        59   def prms                    JUG Frankfurt / Main
Comprehensions


                   Example – All primes up to an Integer

      val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x

      ...

      val prime = ( n :Int ) => factors( n ).toList == List( 1, n )

      …

      val primes = (n :Int) => for( x <- (1 to n) if prime( x ) ) yield x


Mario Gleichmann                        60   Hgh rdr Fcn                 JUG Frankfurt / Main
Higher Order Functions




                   val filterEvenValues = ( xs :List[Int] ) => {

                       for( x <- xs; if x % 2 == 0 ) yield x
                   }




Mario Gleichmann                            61   Lcl fcn           JUG Frankfurt / Main
Higher Order Functions


                                  Local Functions



                   val filterEvenValues = ( xs :List[Int] ) => {
                                                                    Local
                       val isEven = ( i :Int ) => i % 2 == 0       Function
                                                                   Definition
                       for( x <- xs; if isEven( x ) ) yield x
                   }



Mario Gleichmann                            62   Smp od                   JUG Frankfurt / Main
Higher Order Functions




                   val filterOddValues = ( xs :List[Int] ) => {

                       val isOdd = ( i :Int ) => i % 2 == 1

                       for( x <- xs; if isOdd( x ) ) yield x
                   }



Mario Gleichmann                            63   rfctg            JUG Frankfurt / Main
Higher Order Functions


                                   Refactoring ...



                   val filterOddValues = ( xs :List[Int] ) => {

                       val isOdd : Int => Boolean = _ % 2 == 1

                       for( x <- xs; if isOdd( x ) ) yield x
                   }



Mario Gleichmann                             64   bstrcn          JUG Frankfurt / Main
Higher Order Functions


                               … via Abstraction



         val filter = ( predicate: Int => Boolean , xs :List[Int] ) => {

                   for( x <- xs; if predicate( x ) ) yield x
         }




Mario Gleichmann                           65   Fcn Tp              JUG Frankfurt / Main
Higher Order Functions


                             Functions as values

                        Accepting a Function as Argument


         val filter = ( predicate: Int => Boolean , xs :List[Int] ) => {

                   for( x <- xs; if predicate( x ) ) yield x
         }



             Type of filter: ( Int => Boolean, List[Int] ) => List[Int]

Mario Gleichmann                           66   smp                       JUG Frankfurt / Main
Higher Order Functions


                                        Examples

                   val even : Int => Boolean = _ % 2 == 0
                   val odd : Int => Boolean = _ % 2 == 1
                   val prime : Int => Boolean = …
                   ...

                   val candidates = List( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 )

                   val evenValues = filter( even, candidates )
                   val oddValues = filter( odd, candidates )
                   val primes = filter( prime, candidates )
Mario Gleichmann                              67   Mthd crcn                JUG Frankfurt / Main
Higher Order Functions


                                        Coercion

                   def isPositive( x : Int ) : Boolean = x > 0


                   val candidates = List( -3, -2, -1, 0, 1, 2, 3 )

                   val positiveValues = filter( isPositive, candidates )




Mario Gleichmann                              68   vs                      JUG Frankfurt / Main
Higher Order Functions


                                         Coercion

                   def isPositive( x : Int ) : Boolean = x > 0




                                                                          ?
                   val candidates = List( -3, -2, -1, 0, 1, 2, 3 )

                   val positiveValues = filter( isPositive, candidates )


                               ( Int ) : Boolean vs. ( Int ) => Boolean




Mario Gleichmann                                69   mplct crcn            JUG Frankfurt / Main
Higher Order Functions


                                          Coercion

                   def isPositive( x : Int ) : Boolean = x > 0




                                                                          !
                   val candidates = List( -3, -2, -1, 0, 1, 2, 3 )

                   val positiveValues = filter( isPositive, candidates )


                                Implicit Coercion to ( Int ) => Boolean




Mario Gleichmann                                70   xplct crcn            JUG Frankfurt / Main
Higher Order Functions


                                          Coercion
                                         Explicit Coercion to ( Int ) => Boolean


                   val isPositiveFunc : Int => Boolean = isPositive


                   val candidates = List( -3, -2, -1, 0, 1, 2, 3 )

                   val positiveValues = filter( isPositiveFunc, candidates )




Mario Gleichmann                               71   lmbd xpr                       JUG Frankfurt / Main
Anonymous Functions




                   val isNegative = ( x :Int ) => x < 0



                                  filter( isNegative, candidates )




Mario Gleichmann                             72   nsrt               JUG Frankfurt / Main
Anonymous Functions




                   val isNegative = ( x :Int ) => x < 0



                                  filter( ( x :Int ) => x < 0, candidates )

                                         'Lambda' Expression




Mario Gleichmann                             73   TP infr                     JUG Frankfurt / Main
Anonymous Functions


                                         Shortcuts

                   val isNegative = ( x :Int ) => x < 0



                                  filter( x => x < 0, candidates )

                                   Type of Argument inferred

            Type of filter: ( Int => Boolean, List[Int] ) => List[Int]

Mario Gleichmann                              74   shrtct                JUG Frankfurt / Main
Anonymous Functions


                                         Shortcuts

                   val isNegative = ( x :Int ) => x < 0



                                  filter( _ < 0, candidates )

                                        First Argument




Mario Gleichmann                             75   Smp rsc ctrl   JUG Frankfurt / Main
Example 1 - Resource Control




               Reader reader = new BufferedReader( ... );

               try{

                   System.out.println( reader.readLine() );
               }
               finally{

                   reader.close();
               }

Mario Gleichmann                         76   Mrk rc cnt      JUG Frankfurt / Main
Example 1 - Resource Control




               Reader reader = new BufferedReader( ... );

               try{

                   System.out.println( reader.readLine() );
               }
               finally{

                   reader.close();                      Resource Control !
               }

Mario Gleichmann                         77   Ln pttn                        JUG Frankfurt / Main
Example 1 - Resource Control


                                  Loan Pattern

               using ( new BufferedReader( ... ) ,

                   reader => println( reader.readLine() );
               )




Mario Gleichmann                         78   fst arg        JUG Frankfurt / Main
Example 1 - Resource Control


                                   Loan Pattern
                       1st Argument: Resource under control


               using ( new BufferedReader( ... ) ,

                   reader => println( reader.readLine() );
               )




Mario Gleichmann                          79   scnd arg       JUG Frankfurt / Main
Example 1 - Resource Control


                                   Loan Pattern

               using ( new BufferedReader( ... ) ,

                   reader => println( reader.readLine() );
               )


                   2nd Argument: Anonymous Function, using Resource




Mario Gleichmann                          80   def fcn                JUG Frankfurt / Main
Example 1 - Resource Control


                                            Loan Pattern

         val using = ( reader: Reader , block: Reader => Unit ) => {
                   try{
                          block( reader )
                   }
                   finally{
                       reader.close
                   }
         }



Mario Gleichmann                                81   Smp lggn          JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
                   val canLog = logger.canLog( level )
                   ( msg :String ) => if( canLog ) logger.log( level, msg )
         }


         Type of log: ( Logger, LogLevel ) => ( String => Unit )

                                                           Returning a Function



Mario Gleichmann                           82   Fcn appl                          JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
                   val canLog = logger.canLog( level )
                   ( msg :String ) => if( canLog ) logger.log( level, msg )
         }
         …
         val info = log( myErrorLogger , INFO )
         val fatal = log( myErrorLogger , FATAL )
         ...
         info( “...“ )                   Expensive operation 'for nothing'
         ...
         fatal( “failure occured ...“ + “...“ + ... )

Mario Gleichmann                           83   cndn evln                    JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
                   val canLog = logger.canLog( level )
                   ( x: () => String ) => if( canLog ) logger.log( level, x() )
         }
                   Accepting a Function ...               … conditional evaluation


     Type of log: ( Logger, LogLevel ) => ( () => String ) => Unit




Mario Gleichmann                              84   appl                       JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
                   val canLog = logger.canLog( level )
                   ( x: () => String ) => if( isLog ) logger.log( level, x() )
         }
         …

         val fatal = log( myErrorLogger , FATAL )
         ...
                                                  won't be evaluated at all
         ...
         fatal( () => “failure occured ...“ + “...“ + ... )

Mario Gleichmann                             85   blplt                          JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
                   val canLog = logger.canLog( level )
                   ( x: () => String ) => if( isLog ) logger.log( level, x() )
         }
         …

         val fatal = log( myErrorLogger , FATAL )
         ...
                                                              Annoying boilerplate
          ...
         fatal( () => “failure occured ...“ + “...“ + ... )

Mario Gleichmann                             86   cll b nme                          JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
              val canLog = logger.isLog( level )
              def logMsg(x : => String) = if( canLog ) logger.log( level, x )
              logMsg _
         }                       By-Name Parameter




Mario Gleichmann                          87   appl                      JUG Frankfurt / Main
Example 2 - Logging


         val log = ( logger :Logger, level :LogLevel ) => {
              val isLog = logger.canLog( level )
              def logMsg(x : => String) = if( canLog ) logger.log( level, x )
              logMsg _
         }

         …
         val fatal = log( myErrorLogger , FATAL )
         ...

         fatal( “failure occured ...“ + “...“ + ... )


Mario Gleichmann                            88   Smp cstm cntl            JUG Frankfurt / Main
Example 3 – Custom Control Structures



         def loop( body: => Unit ) : LoopUnlessCond =
                   new LoopUnlessCond( body )



         protected class LoopUnlessCond( body: => Unit ) {
                   def unless( cond: => Boolean ) {
                     body
                     if ( !cond ) unless( cond )
                   }
         }
Mario Gleichmann                             89   appl       JUG Frankfurt / Main
Example 3 – Custom Control Structures



           var i = 10

           loop {

                   println( "i = " + i )

                   i-=1

           } unless ( i == 0 )




Mario Gleichmann                           90   obj instc   JUG Frankfurt / Main
Example 3 – Custom Control Structures



           var i = 10

           loop {
                                           Instance of LoopUnlessCond
                   println( "i = " + i )

                   i-=1

           } unless ( i == 0 )




Mario Gleichmann                           91   prt appl                JUG Frankfurt / Main
Partial Application




                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )

                   Type of isPrime: Int => Boolean




Mario Gleichmann                              92   def prms wthn           JUG Frankfurt / Main
Partial Application


                                         Delegation



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs )


             Type of filter: ( Int => Boolean, List[Int] ) => List[Int]



Mario Gleichmann                              93   fxd var                   JUG Frankfurt / Main
Partial Application


                                         Delegation



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs )

                                                                fixed    variable




Mario Gleichmann                              94   appl nappl                JUG Frankfurt / Main
Partial Application


                                     New from Old ...



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = filter( isPrime, _ :List[Int] )


                                            applied         unapplied




Mario Gleichmann                              95   Fcn Tp                  JUG Frankfurt / Main
Partial Application


                                     New from Old ...



                   val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 )


                   val primesWithin = filter( isPrime, _ :List[Int] )

              Type of primesWithin: List[Int] => List[Int]



Mario Gleichmann                              96   Crrng                   JUG Frankfurt / Main
Currying




                   val filter = ( pred: Int => Boolean , xs :List[Int] ) => {

                        for( x <- xs; if pred( x ) ) yield x
                   }

                   Type of filter: ( Int => Boolean , List[Int] ) => List[Int]




Mario Gleichmann                              97   Crrd fcn                  JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }




Mario Gleichmann                           98   Crrd fcn Tp           JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]




Mario Gleichmann                           99   sngl arg              JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]

                                                Curried Function
                                                  Curried Function


Mario Gleichmann                          100   xpln                  JUG Frankfurt / Main
Currying


                       'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                       for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]

                                  ... accepting one            ... resulting in another
                   A function
                                    (Function) Arg                     function

Mario Gleichmann                              101   lmbd xpr                         JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]


                                       ... is defined as a Lambda expession


Mario Gleichmann                          102   cls ovr                  JUG Frankfurt / Main
Currying


                   'Higher Order Lambda Closures' ...


           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }

          Type of filter: ( Int => Boolean ) => List[Int] => List[Int]

                                      ... closes over to Arguments (Scope)
                                           of surrounding Function 'filter'

Mario Gleichmann                          103   Smp prms wthn             JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )




Mario Gleichmann                          104   Fcn Tp                JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )

           Type of primesWithin: List[Int] => List[Int]



Mario Gleichmann                          105   appl                  JUG Frankfurt / Main
Example 1 – Extract primes



           val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => {

                   for( x <- xs; if pred( x ) ) yield x
           }


           val primesWithin = filter( isPrime )

           ...
           primesWithin( List( 3, 4, 5, 6, 7 ) )              >> List( 3, 5, 7 )


Mario Gleichmann                          106   Smp rc mgmt                  JUG Frankfurt / Main
Example 2 – Ressource Management
     val initQuery =
      (dataSource :DataSource) => (query :String) => ( extractor :ResultSet => Unit ) => {

          try{
            val conn = dataSource.getConnection
            val stmt = conn.createStatement
            val resultSet = stmt.executeQuery( query )
            extractor( resultSet )
          }
          finally{
            try{
              if( conn != null ) conn.close
            }
            finally{
              if( stmt != null ) stmt.close
            }
          }
      }


Mario Gleichmann                               107   appl                          JUG Frankfurt / Main
Example 2 – Ressource Management
     val dataSource :DataSource = ...;

     ...
     val query = initQuery( dataSource )

     …

     query( "select * from User where age > 18" ) { result :ResultSet =>
           while( result.next ) { .... }
       }

     …

     query( "select * from Account where balance < 1000" ) { result :ResultSet =>
           while( result.next ) { .... }
       }



Mario Gleichmann                           108   smmy                      JUG Frankfurt / Main
Summary

         Scala supports a style of expression based, functional programming,
                                           offering

                   ●   Functions and Closures as first class values

                   ●   Algebraic Datatypes and Pattern Matching

                   ●   Comprehensions

                   ●   Higher Order Functions and Lambda Expressions

                   ●   Currying


Mario Gleichmann                           109                        JUG Frankfurt / Main
Thank you !




Mario Gleichmann       110       JUG Frankfurt / Main
References


            Scala Home                www.scala-lang.org


            Dr. Erik Meijer           C9 Lectures – Functional Programming Fundamentals
                                      http://channel9.msdn.com


            Graham Hutton             Programming in Haskell
                                      Cambridge


            Odersky, Spoon, Venners   Programming in Scala
                                      artima




Mario Gleichmann                                     111                                  JUG Frankfurt / Main

Weitere ähnliche Inhalte

Kürzlich hochgeladen

Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 

Kürzlich hochgeladen (20)

201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 

Functional Scala I

  • 1. Functional Scaλa Functional Programming with Scala 25.08.2010 Java User Group Frankfurt / Main Mario Gleichmann Mario Gleichmann JUG Frankfurt / Main
  • 2. Introduction Mario Gleichmann site: www.mg-informatik.de blog: 'brain driven development' gleichmann.wordpress.com mail: mario.gleichmann@mg-informatik.de Mario Gleichmann 2 JUG Frankfurt / Main
  • 3. What is Functional Programming ? Imperative Style int sum = 0; for( int i=1; i<=10; i++ ){ sum = sum + i; } Mario Gleichmann 3 JUG Frankfurt / Main
  • 4. What is Functional Programming ? Imperative Style int sum = 0; for( int i=1; i<=10; i++ ){ sum = sum + i; } Instruction based Computation method is variable assignment Mario Gleichmann 4 JUG Frankfurt / Main
  • 5. What is Functional Programming ? Functional Style val sum = fold( 1 to 10, _+_ ) Mario Gleichmann 5 JUG Frankfurt / Main
  • 6. What is Functional Programming ? Functional Style val sum = fold( 1 to 10, add ) Mario Gleichmann 6 JUG Frankfurt / Main
  • 7. What is Functional Programming ? Functional Style val sum = fold( 1 to 10, add ) Expression based Computation method is function application Mario Gleichmann 7 fcn JUG Frankfurt / Main
  • 8. What makes a Function ? Function Literals ( x :Int, y :Int ) => x + y Mario Gleichmann 8 Fcn val JUG Frankfurt / Main
  • 9. What makes a Function ? Function Values val add = ( x :Int, y :Int ) => x + y Mario Gleichmann 9 Elm JUG Frankfurt / Main
  • 10. What makes a Function ? Elements val add = ( x :Int, y :Int ) => x + y Function name Argument list Function expression Mario Gleichmann 10 Tp JUG Frankfurt / Main
  • 11. What makes a Function ? Function Types val add = ( x :Int, y :Int ) => x + y Type of add : ( Int , Int ) => Int Mario Gleichmann 11 Obj JUG Frankfurt / Main
  • 12. What makes a Function ? Note : In Scala, everything is an Object val add = ( x :Int, y :Int ) => x + y val add = new Function2[ Int, Int, Int ] { def apply( x :Int, y: Int ) : Int = x + y } Mario Gleichmann 12 xplct Tp dcl JUG Frankfurt / Main
  • 13. What makes a Function ? Function Types val add : ( Int, Int ) => Int = ( x :Int, y :Int ) => x + y Explicit Type Declaration Mario Gleichmann 13 Shrt JUG Frankfurt / Main
  • 14. What makes a Function ? Argument Shortcuts Argument List omitted ! val add : ( Int, Int ) => Int = _+_ First Parameter Second Parameter Mario Gleichmann 14 app JUG Frankfurt / Main
  • 15. What makes a Function ? Function Application val add : ( Int, Int ) => Int = _+_ Function Application ... add( 3, 8 ) >> 11 Mario Gleichmann 15 App obj JUG Frankfurt / Main
  • 16. What makes a Function ? Function Application val add : ( Int, Int ) => Int = _+_ ... add( 3, 8 ) >> 11 add.apply( 3, 8 ) >> 11 Mario Gleichmann 16 Mthd JUG Frankfurt / Main
  • 17. What makes a Function ? Methods object Math{ ... def mult( x :Int, y :Int ) : Int = x * y ... } Mario Gleichmann 17 Elm JUG Frankfurt / Main
  • 18. What makes a Function ? Elements object Math{ Result Type def mult( x :Int, y :Int ) : Int = x * y } Method name Argument list Method body Mario Gleichmann 18 Tpe JUG Frankfurt / Main
  • 19. What makes a Function ? Method Types def mult( x :Int, y :Int ) : Int = x * y Type of mult : ( Int , Int ) Int Mario Gleichmann 19 clsrs JUG Frankfurt / Main
  • 20. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit Type of isAdult : Int => Boolean Mario Gleichmann 20 Bnd var JUG Frankfurt / Main
  • 21. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit Bound variable Mario Gleichmann 21 Fre var JUG Frankfurt / Main
  • 22. Closures var limit = 18 Free variable val isAdult = ( age :Int ) => age >= limit Mario Gleichmann 22 Opn Trm JUG Frankfurt / Main
  • 23. Closures Open Terms var limit = 18 Free variable val isAdult = ( age :Int ) => age >= limit 'Open term' Mario Gleichmann 23 Cls ovr JUG Frankfurt / Main
  • 24. Closures 'Closing over' var limit = 18 val isAdult = ( age :Int ) => age >= limit Mario Gleichmann 24 Clsd trm JUG Frankfurt / Main
  • 25. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit 'Closed term' Mario Gleichmann 25 appl JUG Frankfurt / Main
  • 26. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit val isGermanAdult = isAdult( 20 ) >> true Mario Gleichmann 26 Lim chng JUG Frankfurt / Main
  • 27. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit val isGermanAdult = isAdult( 20 ) >> true limit = 21 val isUnitesStatesAdult = isAdult( 20 ) Mario Gleichmann 27 Dym bnd JUG Frankfurt / Main
  • 28. Closures var limit = 18 val isAdult = ( age :Int ) => age >= limit val isGermanAdult = isAdult( 20 ) >> true 'Dynamic' bound limit = 21 val isUnitesStatesAdult = isAdult( 20 ) >> false Mario Gleichmann 28 Dta Tp JUG Frankfurt / Main
  • 29. Data types data Natural = Zero | Succ( Natural ) 'Constructors' Mario Gleichmann 29 smp JUG Frankfurt / Main
  • 30. Data types data Natural = Zero | Succ( Natural ) val zero = Zero val one = Succ( Zero ) val four = Succ( Succ ( Succ ( Succ ( Zero ) ) ) ) Mario Gleichmann 30 Int JUG Frankfurt / Main
  • 31. Data types data Integer = … , -3, -2, -1, 0, 1, 2, 3, ... val zero = 0 val one = 1 val four = 4 Mario Gleichmann 31 Fib pttn JUG Frankfurt / Main
  • 32. Operating on data types Pattern Matching fibonacci( 0 ) → 0 fibonacci( 1 ) → 1 fibonacci( n ) → fibonacci( n – 1 ) + fibonacci( n – 2 ) Mario Gleichmann 32 Ptt mtc JUG Frankfurt / Main
  • 33. Operating on data types Pattern Matching val fib : Int => Int = ( i :Int ) => i match { case 0 => 0 case 1 => 1 case n => fib( n - 1 ) + fib( n - 2 ) } Mario Gleichmann 33 othw JUG Frankfurt / Main
  • 34. Operating on data types Pattern Matching val fib : Int => Int = ( i :Int ) => i match { case 0 => 0 case 1 => 1 case _ => fib( i - 1 ) + fib( i - 2 ) } 'otherwise' Mario Gleichmann 34 Lst JUG Frankfurt / Main
  • 35. Algebraic Datatypes data List a = Nil | Cons a ( List a ) Mario Gleichmann 35 Cnstr JUG Frankfurt / Main
  • 36. Algebraic Datatypes Value Constructors data List[T] = Nil | T :: List[T] 'Constructors' Mario Gleichmann 36 smp JUG Frankfurt / Main
  • 37. Algebraic Datatypes Value Construction data List[T] = Nil | T :: List[T] val emptyList = Nil Mario Gleichmann 37 smp JUG Frankfurt / Main
  • 38. Algebraic Datatypes Value Construction data List[T] = Nil | T :: List[T] val emptyList = Nil val anotherList = 5 :: 4 :: 3 :: 2 :: 1 :: Nil Mario Gleichmann 38 Rght assoc JUG Frankfurt / Main
  • 39. Algebraic Datatypes Value Construction data List[T] = Nil | T :: List[T] val emptyList = Nil val anotherList = 5 :: ( 4 :: ( 3 :: ( 2 :: (1 :: Nil ) ) ) ) Mario Gleichmann 39 Smp tl JUG Frankfurt / Main
  • 40. Operating on algebraic data types Pattern Matching def tail [T] ( list :List[T] ) = list match { case Nil => Nil case x :: xs => xs } Type of tail: [T] ( List[T] ) List[T] Mario Gleichmann 40 De con JUG Frankfurt / Main
  • 41. Operating on algebraic data types Pattern Matching def tail [T] ( list :List[T] ) = list match { case Nil => Nil case x :: xs => xs } 'De-Construction' Mario Gleichmann 41 Dnt cr JUG Frankfurt / Main
  • 42. Operating on algebraic data types Pattern Matching val length : List[ _ ] => Int = _ match { case Nil => 0 case _ :: xs => 1 + length( xs ) } 'some head' (don't care) Type of length: ( List[ _ ] ) => Int Mario Gleichmann 42 Grd JUG Frankfurt / Main
  • 43. Operating on algebraic data types Pattern Matching def insert[ T <% Ordered[ T ] ] ( elem :T, list :List[T] ) : List[T] = list match { case Nil => elem :: Nil case x :: xs if elem <= x => elem :: x :: xs case x :: xs => x :: insert( elem, xs ) } Guard Mario Gleichmann 43 Smp Tr JUG Frankfurt / Main
  • 44. Algebraic Datatypes Example - Tree data Tree = Empty | Leaf Int | Node Int Tree Tree Mario Gleichmann 44 Cs clss JUG Frankfurt / Main
  • 45. Algebraic Datatypes Example - Tree data Tree = Empty | Leaf Int | Node Int Tree Tree abstract case class Tree() case object Empty extends Tree case class Leaf( value: Int ) extends Tree case class Node( value: Int, left :Tree, right: Tree ) extends Tree Mario Gleichmann 45 insrt JUG Frankfurt / Main
  • 46. Algebraic Datatypes Buildin' an unbalanced, ordered Tree val insert :( Int, Tree ) => Tree = ( elem :Int, tree :Tree ) => tree match { case Empty => Leaf( elem ) case Node( x, left, right ) if elem < x => Node( x, insert( elem, left ), right ) case Node( x, left, right ) if elem >= x => Node( x, left, insert( elem, right ) ) case Leaf( x ) if elem < x => Node( x, Leaf( elem ), Empty ) case leaf @ Leaf( x ) if elem >= x => Node( elem, leaf, Empty ) } Mario Gleichmann 46 dpth JUG Frankfurt / Main
  • 47. Algebraic Datatypes Pattern Matching val depth :Tree => Int = _ match { case Empty => 0 case Leaf( _ ) => 1 case Node( _, left, right ) => 1 + max( depth( left ), depth( right ) ) } Mario Gleichmann 47 Prt isb JUG Frankfurt / Main
  • 48. Partial Functions case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int ) val publisherRegionDE = ( isbn :Isbn ) => isbn match { case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 ) } … publisherRegionDE( Isbn( 3, 677873, 8823 ) ) ) >> “D6“ Mario Gleichmann 48 unmtch JUG Frankfurt / Main
  • 49. Partial Functions case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int ) val publisherRegionDE = ( isbn :Isbn ) => isbn match { case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 ) } ? … publisherRegionDE( Isbn( 0, 677873, 8823 ) ) ) >> Mario Gleichmann 49 Mtch err JUG Frankfurt / Main
  • 50. Partial Functions case class Isbn( groupNr :Int, publisherNr :Int, titleNr :Int ) val publisherRegionDE = ( isbn :Isbn ) => isbn match { case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 ) } … publisherRegionDE( Isbn( 0, 677873, 8823 ) ) ) >> MatchError Mario Gleichmann 50 Prt fnc JUG Frankfurt / Main
  • 51. Partial Functions type =>?[-A, +B] = PartialFunction[A, B] val publisherRegionDE : Isbn =>? String = { case Isbn( 3, pubNr, _ ) => "D" + ( pubNr.toString charAt 0 ) } … publisherRegionDE.isDefinedAt( Isbn( 0, 677873, 8823 ) ) ) >> false Mario Gleichmann 51 chn JUG Frankfurt / Main
  • 52. Partial Functions Partial Function Chaining val publisherRegionUS : Isbn =>? String = { case Isbn( 0, pubNr, _ ) => … case Isbn( 1, pubNr, _ ) => ... } ... val allKnownPubs = publisherRegionDE orElse publisherRegionUS ... allKnownPubs( Isbn( 0, 677873, 8823 ) ) >> “WY“ Mario Gleichmann 52 cmprn JUG Frankfurt / Main
  • 53. Comprehensions Set Comprehensions (Mathematics) { x2 | x ∈ { 1 .. 5 } } >> Set : { 1, 4, 9, 16, 25 } Mario Gleichmann 53 Smp scla JUG Frankfurt / Main
  • 54. Comprehensions val pow :(Int,Int) => Int = ( base :Int, exp :Int ) => if( exp == 0 ) 1 else base * pow( base, exp - 1 ) Range ... … val squares = for( x <- ( 1 to 5 ) ) yield pow( x, 2 ) Mario Gleichmann 54 grn JUG Frankfurt / Main
  • 55. Comprehensions val pow :(Int,Int) => Int = ( base :Int, exp :Int ) => if( exp == 0 ) 1 else base * pow( base, exp - 1 ) … as Generator … val squares = for( x <- ( 1 to 5 ) ) yield pow( x, 2 ) >> Seq( 1, 4, 9, 16, 25 ) Mario Gleichmann 55 Mltp gen JUG Frankfurt / Main
  • 56. Comprehensions Multiple Generators Tuple2 val pairs = for( x <- (1 to 3 ); y <- ( 1 to x ) ) yield (y,x) >> Seq( (1,1), (1,2), (2,2), (1,3), (2,3), (3,3) ) Mario Gleichmann 56 Smp fltn JUG Frankfurt / Main
  • 57. Comprehensions Example – Flatten a List of Lists val flatten = ( xss :List[ List[Int] ] ) => for( xs <- xss; x <- xs ) yield x ... flatten( List( List(1,2), List( 5,6,8 ), List( 21,23,24 ) ) ) >> List(1, 2, 5, 6, 8, 21, 23, 24) Mario Gleichmann 57 Smp int fact JUG Frankfurt / Main
  • 58. Comprehensions Example – All factors of an Integer val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x ... Guard factors( 15 ) >> Seq( 1, 3, 5, 15 ) Mario Gleichmann 58 def prm JUG Frankfurt / Main
  • 59. Comprehensions Example – Test 'prime' on Integer val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x ... val prime = ( n :Int ) => factors( n ).toList == List( 1, n ) Mario Gleichmann 59 def prms JUG Frankfurt / Main
  • 60. Comprehensions Example – All primes up to an Integer val factors = ( n :Int ) => for( x <- ( 1 to n ) if n % x == 0 ) yield x ... val prime = ( n :Int ) => factors( n ).toList == List( 1, n ) … val primes = (n :Int) => for( x <- (1 to n) if prime( x ) ) yield x Mario Gleichmann 60 Hgh rdr Fcn JUG Frankfurt / Main
  • 61. Higher Order Functions val filterEvenValues = ( xs :List[Int] ) => { for( x <- xs; if x % 2 == 0 ) yield x } Mario Gleichmann 61 Lcl fcn JUG Frankfurt / Main
  • 62. Higher Order Functions Local Functions val filterEvenValues = ( xs :List[Int] ) => { Local val isEven = ( i :Int ) => i % 2 == 0 Function Definition for( x <- xs; if isEven( x ) ) yield x } Mario Gleichmann 62 Smp od JUG Frankfurt / Main
  • 63. Higher Order Functions val filterOddValues = ( xs :List[Int] ) => { val isOdd = ( i :Int ) => i % 2 == 1 for( x <- xs; if isOdd( x ) ) yield x } Mario Gleichmann 63 rfctg JUG Frankfurt / Main
  • 64. Higher Order Functions Refactoring ... val filterOddValues = ( xs :List[Int] ) => { val isOdd : Int => Boolean = _ % 2 == 1 for( x <- xs; if isOdd( x ) ) yield x } Mario Gleichmann 64 bstrcn JUG Frankfurt / Main
  • 65. Higher Order Functions … via Abstraction val filter = ( predicate: Int => Boolean , xs :List[Int] ) => { for( x <- xs; if predicate( x ) ) yield x } Mario Gleichmann 65 Fcn Tp JUG Frankfurt / Main
  • 66. Higher Order Functions Functions as values Accepting a Function as Argument val filter = ( predicate: Int => Boolean , xs :List[Int] ) => { for( x <- xs; if predicate( x ) ) yield x } Type of filter: ( Int => Boolean, List[Int] ) => List[Int] Mario Gleichmann 66 smp JUG Frankfurt / Main
  • 67. Higher Order Functions Examples val even : Int => Boolean = _ % 2 == 0 val odd : Int => Boolean = _ % 2 == 1 val prime : Int => Boolean = … ... val candidates = List( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) val evenValues = filter( even, candidates ) val oddValues = filter( odd, candidates ) val primes = filter( prime, candidates ) Mario Gleichmann 67 Mthd crcn JUG Frankfurt / Main
  • 68. Higher Order Functions Coercion def isPositive( x : Int ) : Boolean = x > 0 val candidates = List( -3, -2, -1, 0, 1, 2, 3 ) val positiveValues = filter( isPositive, candidates ) Mario Gleichmann 68 vs JUG Frankfurt / Main
  • 69. Higher Order Functions Coercion def isPositive( x : Int ) : Boolean = x > 0 ? val candidates = List( -3, -2, -1, 0, 1, 2, 3 ) val positiveValues = filter( isPositive, candidates ) ( Int ) : Boolean vs. ( Int ) => Boolean Mario Gleichmann 69 mplct crcn JUG Frankfurt / Main
  • 70. Higher Order Functions Coercion def isPositive( x : Int ) : Boolean = x > 0 ! val candidates = List( -3, -2, -1, 0, 1, 2, 3 ) val positiveValues = filter( isPositive, candidates ) Implicit Coercion to ( Int ) => Boolean Mario Gleichmann 70 xplct crcn JUG Frankfurt / Main
  • 71. Higher Order Functions Coercion Explicit Coercion to ( Int ) => Boolean val isPositiveFunc : Int => Boolean = isPositive val candidates = List( -3, -2, -1, 0, 1, 2, 3 ) val positiveValues = filter( isPositiveFunc, candidates ) Mario Gleichmann 71 lmbd xpr JUG Frankfurt / Main
  • 72. Anonymous Functions val isNegative = ( x :Int ) => x < 0 filter( isNegative, candidates ) Mario Gleichmann 72 nsrt JUG Frankfurt / Main
  • 73. Anonymous Functions val isNegative = ( x :Int ) => x < 0 filter( ( x :Int ) => x < 0, candidates ) 'Lambda' Expression Mario Gleichmann 73 TP infr JUG Frankfurt / Main
  • 74. Anonymous Functions Shortcuts val isNegative = ( x :Int ) => x < 0 filter( x => x < 0, candidates ) Type of Argument inferred Type of filter: ( Int => Boolean, List[Int] ) => List[Int] Mario Gleichmann 74 shrtct JUG Frankfurt / Main
  • 75. Anonymous Functions Shortcuts val isNegative = ( x :Int ) => x < 0 filter( _ < 0, candidates ) First Argument Mario Gleichmann 75 Smp rsc ctrl JUG Frankfurt / Main
  • 76. Example 1 - Resource Control Reader reader = new BufferedReader( ... ); try{ System.out.println( reader.readLine() ); } finally{ reader.close(); } Mario Gleichmann 76 Mrk rc cnt JUG Frankfurt / Main
  • 77. Example 1 - Resource Control Reader reader = new BufferedReader( ... ); try{ System.out.println( reader.readLine() ); } finally{ reader.close(); Resource Control ! } Mario Gleichmann 77 Ln pttn JUG Frankfurt / Main
  • 78. Example 1 - Resource Control Loan Pattern using ( new BufferedReader( ... ) , reader => println( reader.readLine() ); ) Mario Gleichmann 78 fst arg JUG Frankfurt / Main
  • 79. Example 1 - Resource Control Loan Pattern 1st Argument: Resource under control using ( new BufferedReader( ... ) , reader => println( reader.readLine() ); ) Mario Gleichmann 79 scnd arg JUG Frankfurt / Main
  • 80. Example 1 - Resource Control Loan Pattern using ( new BufferedReader( ... ) , reader => println( reader.readLine() ); ) 2nd Argument: Anonymous Function, using Resource Mario Gleichmann 80 def fcn JUG Frankfurt / Main
  • 81. Example 1 - Resource Control Loan Pattern val using = ( reader: Reader , block: Reader => Unit ) => { try{ block( reader ) } finally{ reader.close } } Mario Gleichmann 81 Smp lggn JUG Frankfurt / Main
  • 82. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.canLog( level ) ( msg :String ) => if( canLog ) logger.log( level, msg ) } Type of log: ( Logger, LogLevel ) => ( String => Unit ) Returning a Function Mario Gleichmann 82 Fcn appl JUG Frankfurt / Main
  • 83. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.canLog( level ) ( msg :String ) => if( canLog ) logger.log( level, msg ) } … val info = log( myErrorLogger , INFO ) val fatal = log( myErrorLogger , FATAL ) ... info( “...“ ) Expensive operation 'for nothing' ... fatal( “failure occured ...“ + “...“ + ... ) Mario Gleichmann 83 cndn evln JUG Frankfurt / Main
  • 84. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.canLog( level ) ( x: () => String ) => if( canLog ) logger.log( level, x() ) } Accepting a Function ... … conditional evaluation Type of log: ( Logger, LogLevel ) => ( () => String ) => Unit Mario Gleichmann 84 appl JUG Frankfurt / Main
  • 85. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.canLog( level ) ( x: () => String ) => if( isLog ) logger.log( level, x() ) } … val fatal = log( myErrorLogger , FATAL ) ... won't be evaluated at all ... fatal( () => “failure occured ...“ + “...“ + ... ) Mario Gleichmann 85 blplt JUG Frankfurt / Main
  • 86. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.canLog( level ) ( x: () => String ) => if( isLog ) logger.log( level, x() ) } … val fatal = log( myErrorLogger , FATAL ) ... Annoying boilerplate ... fatal( () => “failure occured ...“ + “...“ + ... ) Mario Gleichmann 86 cll b nme JUG Frankfurt / Main
  • 87. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val canLog = logger.isLog( level ) def logMsg(x : => String) = if( canLog ) logger.log( level, x ) logMsg _ } By-Name Parameter Mario Gleichmann 87 appl JUG Frankfurt / Main
  • 88. Example 2 - Logging val log = ( logger :Logger, level :LogLevel ) => { val isLog = logger.canLog( level ) def logMsg(x : => String) = if( canLog ) logger.log( level, x ) logMsg _ } … val fatal = log( myErrorLogger , FATAL ) ... fatal( “failure occured ...“ + “...“ + ... ) Mario Gleichmann 88 Smp cstm cntl JUG Frankfurt / Main
  • 89. Example 3 – Custom Control Structures def loop( body: => Unit ) : LoopUnlessCond = new LoopUnlessCond( body ) protected class LoopUnlessCond( body: => Unit ) { def unless( cond: => Boolean ) { body if ( !cond ) unless( cond ) } } Mario Gleichmann 89 appl JUG Frankfurt / Main
  • 90. Example 3 – Custom Control Structures var i = 10 loop { println( "i = " + i ) i-=1 } unless ( i == 0 ) Mario Gleichmann 90 obj instc JUG Frankfurt / Main
  • 91. Example 3 – Custom Control Structures var i = 10 loop { Instance of LoopUnlessCond println( "i = " + i ) i-=1 } unless ( i == 0 ) Mario Gleichmann 91 prt appl JUG Frankfurt / Main
  • 92. Partial Application val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) Type of isPrime: Int => Boolean Mario Gleichmann 92 def prms wthn JUG Frankfurt / Main
  • 93. Partial Application Delegation val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs ) Type of filter: ( Int => Boolean, List[Int] ) => List[Int] Mario Gleichmann 93 fxd var JUG Frankfurt / Main
  • 94. Partial Application Delegation val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = ( xs :List[Int] ) => filter( isPrime , xs ) fixed variable Mario Gleichmann 94 appl nappl JUG Frankfurt / Main
  • 95. Partial Application New from Old ... val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = filter( isPrime, _ :List[Int] ) applied unapplied Mario Gleichmann 95 Fcn Tp JUG Frankfurt / Main
  • 96. Partial Application New from Old ... val isPrime = (x :Int) => ( 2 to x/2 ).forall( x % _ != 0 ) val primesWithin = filter( isPrime, _ :List[Int] ) Type of primesWithin: List[Int] => List[Int] Mario Gleichmann 96 Crrng JUG Frankfurt / Main
  • 97. Currying val filter = ( pred: Int => Boolean , xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean , List[Int] ) => List[Int] Mario Gleichmann 97 Crrd fcn JUG Frankfurt / Main
  • 98. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Mario Gleichmann 98 Crrd fcn Tp JUG Frankfurt / Main
  • 99. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] Mario Gleichmann 99 sngl arg JUG Frankfurt / Main
  • 100. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] Curried Function Curried Function Mario Gleichmann 100 xpln JUG Frankfurt / Main
  • 101. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] ... accepting one ... resulting in another A function (Function) Arg function Mario Gleichmann 101 lmbd xpr JUG Frankfurt / Main
  • 102. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] ... is defined as a Lambda expession Mario Gleichmann 102 cls ovr JUG Frankfurt / Main
  • 103. Currying 'Higher Order Lambda Closures' ... val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } Type of filter: ( Int => Boolean ) => List[Int] => List[Int] ... closes over to Arguments (Scope) of surrounding Function 'filter' Mario Gleichmann 103 Smp prms wthn JUG Frankfurt / Main
  • 104. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) Mario Gleichmann 104 Fcn Tp JUG Frankfurt / Main
  • 105. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) Type of primesWithin: List[Int] => List[Int] Mario Gleichmann 105 appl JUG Frankfurt / Main
  • 106. Example 1 – Extract primes val filter = ( pred: Int => Boolean ) => ( xs :List[Int] ) => { for( x <- xs; if pred( x ) ) yield x } val primesWithin = filter( isPrime ) ... primesWithin( List( 3, 4, 5, 6, 7 ) ) >> List( 3, 5, 7 ) Mario Gleichmann 106 Smp rc mgmt JUG Frankfurt / Main
  • 107. Example 2 – Ressource Management val initQuery = (dataSource :DataSource) => (query :String) => ( extractor :ResultSet => Unit ) => { try{ val conn = dataSource.getConnection val stmt = conn.createStatement val resultSet = stmt.executeQuery( query ) extractor( resultSet ) } finally{ try{ if( conn != null ) conn.close } finally{ if( stmt != null ) stmt.close } } } Mario Gleichmann 107 appl JUG Frankfurt / Main
  • 108. Example 2 – Ressource Management val dataSource :DataSource = ...; ... val query = initQuery( dataSource ) … query( "select * from User where age > 18" ) { result :ResultSet => while( result.next ) { .... } } … query( "select * from Account where balance < 1000" ) { result :ResultSet => while( result.next ) { .... } } Mario Gleichmann 108 smmy JUG Frankfurt / Main
  • 109. Summary Scala supports a style of expression based, functional programming, offering ● Functions and Closures as first class values ● Algebraic Datatypes and Pattern Matching ● Comprehensions ● Higher Order Functions and Lambda Expressions ● Currying Mario Gleichmann 109 JUG Frankfurt / Main
  • 110. Thank you ! Mario Gleichmann 110 JUG Frankfurt / Main
  • 111. References Scala Home www.scala-lang.org Dr. Erik Meijer C9 Lectures – Functional Programming Fundamentals http://channel9.msdn.com Graham Hutton Programming in Haskell Cambridge Odersky, Spoon, Venners Programming in Scala artima Mario Gleichmann 111 JUG Frankfurt / Main