SlideShare a Scribd company logo
1 of 33
Download to read offline
Continuations
 and other Functional Patterns

      Christopher League
        Long Island University



      Northeast Scala Symposium
           February 
Sin & redemption
Java classes → SML runtime
Standard ML of New Jersey v110.30 [JFLINT 1.2]
- Java.classPath := [”/home/league/r/java/tests”];
val it = () : unit
- val main = Java.run ”Hello”;
[parsing Hello]
[parsing java/lang/Object]
[compiling java/lang/Object]
[compiling Hello]
[initializing java/lang/Object]
[initializing Hello]
val main = fn : string list -> unit
- main [”World”];
Hello, World
val it = () : unit
- main [];
uncaught exception ArrayIndexOutOfBounds
  raised at: Hello.main([Ljava/lang/String;)V
- ˆD
OO runtime ← functional languages

              Scala
             Clojure
               F
               etc.
Patterns
. Continuation-passing style
. Format combinators
. Nested data types


                    eme
  Higher-order {functions, types}
Pattern : Continuations
A continuation is an argument that represents
the rest of the computation meant to occur
after the current function.
Explicit continuations – straight-line
 def greeting [A] (name: String) (k: => A): A =
   printk(”Hello, ”) {
   printk(name) {
   printk(”!n”)(k)
   }}
 def printk [A] (s: String) (k: => A): A =
   { Console.print(s); k }

scala> greeting(”Scala peeps”) { true }
Hello, Scala peeps!
res0: Boolean = true
Pay it forward...
Current function can ‘return’ a value
by passing it as a parameter to its continuation.
Explicit continuations – return values
 def plus [A] (x: Int, y: Int) (k: Int => A): A =
   k(x+y)
 def times [A] (x: Int, y: Int) (k: Int => A): A =
   k(x*y)
 def less[A] (x: Int, y: Int) (kt: =>A) (kf: =>A):A =
   if(x < y) kt else kf

 def test[A](k: String => A): A =
   plus(3,2) { a => times(3,2) { b =>
   less(a,b) {k(”yes”)} {k(”no”)} }}

scala> test{printk(_){}}
yes
Delimited continuations
reset Serves as delimiter for CPS transformation.
shift Captures current continuation as a function
      (up to dynamically-enclosing reset)
      then runs specified block instead.
Delimited continuations
def doSomething0 = reset {
  println(”Ready?”)
  val result = 1 + ˜˜˜˜˜˜˜˜ * 3
  println(result)
}
ink of the rest of the computation
as a function with the hole as its parameter.
Delimited continuations
def doSomething1 = reset {
  println(”Ready?”)
  val result = 1 + special * 3
  println(result)
}
def special = shift {
  k: (Int => Unit) => println(99); ”Gotcha!”
}
shift captures continuation as k
and then determines its own future.
Delimited continuations
def doSomething1 = reset {
  println(”Ready?”)
  val result = 1 + special * 3
  println(result)
}
def special = shift {
  k: (Int => Unit) => println(99); ”Gotcha!”
}

scala> doSomething1
Ready?
99
res0: java.lang.String = Gotcha!
Continuation-based user interaction
def interact = reset {
  val a = ask(”Please give me a number”)
  val b = ask(”Please enter another number”)
  printf(”The sum of your numbers is: %dn”, a+b)
}

scala> interact
Please give me a number
answer using: submit(0xa9db9535, ...)
scala> submit(0xa9db9535, 14)
Please enter another number
answer using: submit(0xbd1b3eb0, ...)
scala> submit(0xbd1b3eb0, 28)
The sum of your numbers is: 42
Continuation-based user interaction
val sessions = new HashMap[UUID, Int=>Unit]
def ask(prompt: String): Int @cps[Unit] = shift {
    k: (Int => Unit) => {
      val id = uuidGen
      printf(”%snanswer using: submit(0x%x, ...)n”,
            prompt, id)
      sessions += id -> k
  }}
def submit(id: UUID, data: Int) = sessions(id)(data)

def interact = reset {
  val a = ask(”Please give me a number”)
  val b = ask(”Please enter another number”)
  printf(”The sum of your numbers is: %dn”, a+b)
}
Pattern : Format combinators
                                             [Danvy ]
Typeful programmers covet printf.
  int a = 5;
  int b = 2;
  float c = a / (float) b;
  printf(”%d over %d is %.2fn”, a, b, c);
Cannot type-check because format is just a string.
What if it has structure, like abstract syntax tree?
Typed format specifiers
 val frac: Int => Int => Float => String =
   d & ” over ” & d & ” is ” & f(2) & endl |
 val grade: Any => Double => Unit =
   ”Hello, ”&s&”: your exam score is ”&pct&endl |>
 val hex: (Int, Int, Int) => String =
   uncurried(”#”&x&x&x|)
                  (Type annotations are for reference – not required.)

scala> println(uncurried(frac)(a,b,c))
5 over 2 is 2.50

scala> grade(”Joshua”)(0.97)
Hello, Joshua: your exam score is 97%
scala> println(”Roses are ”&s | hex(250, 21, 42))
Roses are #fa152a
Buffer representation
type Buf = List[String]
def put(b: Buf, e: String): Buf = e :: b
def finish(b: Buf): String = b.reverse.mkString
def initial: Buf = Nil
Operational semantics
def lit(m:String)(k:Buf=>A)(b:Buf) = k(put(b,m))
def x(k:Buf=>A)(b:Buf)(i:Int) = k(put(b,i.toHexString))
def s(k:Buf=>A)(b:Buf)(o:Any) = k(put(b,o.toString))
                             (Not the actual implementation.)

         lit(”L”)(finish)(initial)      ”L”
         x(finish)(initial)(42)         ”2a”

where:
 type Buf = List[String]
 def put(b: Buf, e: String): Buf = e :: b
 def finish(b: Buf): String = b.reverse.mkString
 def initial: Buf = Nil
Function composition
 (lit(”L”) & x) (finish) (initial) (2815)

 lit(”L”)(x(finish)) (initial) (2815)

lit(”L”)(λ b0.λ i.finish(i.toHex :: b0)) (initial) (2815)

(λ b1.λ i.finish(i.toHex :: ”L” :: b1)) (initial) (2815)
       finish(2815.toHex :: ”L” :: initial)
          List(”aff”,”L”).reverse.mkString      ”Laff”
where:
def lit(m:String)(k:Buf=>A)(b:Buf) = k(put(b,m))
def x(k:Buf=>A)(b:Buf)(i:Int) = k(put(b,i.toHexString))
def s(k:Buf=>A)(b:Buf)(o:Any) = k(put(b,o.toString))
Combinator polymorphism
What is the answer type?
      x: ∀A.(Buf => A) => Buf => Int => A
 finish: Buf => String

          x(x(x(finish)))
                A	≡ String
              A	≡ Int	=>	String
            A	≡ Int	=>	Int	=>	String
Type constructor polymorphism
trait Compose[F[_],G[_]] { type T[X] = F[G[X]] }
trait Fragment[F[_]] {
  def apply[A](k: Buf=>A): Buf=>F[A]
  def & [G[_]] (g: Fragment[G]) =
    new Fragment[Compose[F,G]#T] {
      def apply[A](k: Buf=>A) = Fragment.this(g(k))
    }
  def | : F[String] = apply(finish(_))(initial)
}
Combinator implementations
type Id[A] = A
implicit def lit(s:String) = new Fragment[Id] {
  def apply[A](k: Cont[A]) = (b:Buf) => k(put(b,s))
}

type IntF[A] = Int => A
val x = new Fragment[IntF] {
  def apply[A](k: Cont[A]) = (b:Buf) => (i:Int) =>
    k(put(b,i.toHexString))
}
Pattern : Nested data types
Usually, a polymorphic recursive data type
is instantiated uniformly throughout:
trait List[A]
case class Nil[A]() extends List[A]
case class Cons[A](hd:A, tl:List[A]) extends List[A]
What if type parameter of recursive invocation differs?
Weird examples
trait Weird[A]
case class Wil[A]() extends Weird[A]
case class Wons[A](hd: A, tl: Weird[(A,A)])
extends Weird[A] // tail of Weird[A] is Weird[(A,A)]

val z: Weird[Int] = Wons(1, Wil[I2]())
val y: Weird[Int] = Wons(1, Wons((2,3), Wil[I4]))
val x: Weird[Int] =
       Wons( 1,
       Wons( (2,3),
       Wons( ((4,5),(6,7)),
       Wil[I8]())))

type I2 = (Int,Int)
type I4 = (I2,I2)
type I8 = (I4,I4)
Square matrices
                                     [Okasaki ]
Vector[Vector[A]] is a two-dimensional matrix
of elements of type A.
But lengths of rows (inner vectors) could differ.
Using nested data types, recursively build
a type constructor V[_] to represent a sequence
of a fixed number of elements.
en, Vector[V[A]] is a well-formed matrix,
and V[V[A]] is square.
Square matrix example
scala> val m = tabulate(6){(i,j) => (i+1)*(j+1)}
m: FastExpSquareMatrix.M[Int] =
  Even Odd Odd Zero (((),((((),(1,2)),((3,4),(5,6))
  ),(((),(2,4)),((6,8),(10,12))))),(((((),(3,6)),((
  9,12),(15,18))),(((),(4,8)),((12,16),(20,24)))),(
  (((),(5,10)),((15,20),(25,30))),(((),(6,12)),((18
  ,24),(30,36))))))
scala> val q = m(4,2)
q: Int = 15
scala> val m2 = m updated (4,2,999)
m2: FastExpSquareMatrix.M[Int] =
  Even Odd Odd Zero (((),((((),(1,2)),((3,4),(5,6))
  ),(((),(2,4)),((6,8),(10,12))))),(((((),(3,6)),((
  9,12),(15,18))),(((),(4,8)),((12,16),(20,24)))),(
  (((),(5,10)),((999,20),(25,30))),(((),(6,12)),((
  18,24),(30,36))))))
Analogy with fast exponentiation
fastexp r b 0 = r
fastexp r b n = fastexp r (b2 ) n/2         if n even
fastexp r b n = fastexp (r · b) (b2 ) n/2   otherwise
For example:
 fastexp 1 b 6 =                        Even
 fastexp 1 (b2 ) 3 =                    Odd
                      2
 fastexp (1 · b2 ) (b2 ) 1 =            Odd
                   2      22
fastexp (1 · b2 · b2 ) (b2 ) 0 =        Zero
            2
1 · b2 · b2
Fast exponentiation of product types
type U = Unit
type I = Int
fastExp U I 6 =                        //   Even
fastExp U (I,I) 3 =                    //   Odd
fastExp (U,(I,I)) ((I,I),(I,I)) 1 =    //   Odd
fastExp ((U,(I,I)),((I,I),(I,I)))      //   Zero
       (((I,I),(I,I)),((I,I),(I,I))) 0 =
((U,(I,I)),((I,I),(I,I)))
Implementation as nested data type
trait Pr[V[_], W[_]] {
  type T[A] = (V[A],W[A])
}
trait M [V[_],W[_],A]
case class Zero [V[_],W[_],A] (data: V[V[A]])
     extends M[V,W,A]
case class Even [V[_],W[_],A] (
           next: M[V, Pr[W,W]#T, A]
     ) extends M[V,W,A]
case class Odd [V[_],W[_],A] (
           next: M[Pr[V,W]#T, Pr[W,W]#T, A]
     ) extends M[V,W,A]

type Empty[A] = Unit
type Id[A] = A
type Matrix[A] = M[Empty,Id,A]
anks!
           league@contrapunctus.net
                 @chrisleague




github.com/league/                 slidesha.re/eREMXZ
scala-fun-patterns
   Danvy, Olivier. “Functional Unparsing” J. Functional
   Programming (), .
   Okasaki, Chris. “From Fast Exponentiation to Square
   Matrices: An Adventure in Types” Int’l Conf. Functional
   Programming, .

More Related Content

What's hot

First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)stasimus
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsKirill Kozlov
 
Functional programming with haskell
Functional programming with haskellFunctional programming with haskell
Functional programming with haskellfaradjpour
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskellJongsoo Lee
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about lazinessJohan Tibell
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in ScalaKnoldus Inc.
 
The java language cheat sheet
The java language cheat sheetThe java language cheat sheet
The java language cheat sheetanand_study
 
Type Parameterization
Type ParameterizationType Parameterization
Type ParameterizationKnoldus Inc.
 
Introduction to haskell
Introduction to haskellIntroduction to haskell
Introduction to haskellLuca Molteni
 

What's hot (18)

First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
 
Functional programming with haskell
Functional programming with haskellFunctional programming with haskell
Functional programming with haskell
 
Python lecture 05
Python lecture 05Python lecture 05
Python lecture 05
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about laziness
 
Python programming : Standard Input and Output
Python programming : Standard Input and OutputPython programming : Standard Input and Output
Python programming : Standard Input and Output
 
Java cheatsheet
Java cheatsheetJava cheatsheet
Java cheatsheet
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
 
The java language cheat sheet
The java language cheat sheetThe java language cheat sheet
The java language cheat sheet
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
 
Introduction to haskell
Introduction to haskellIntroduction to haskell
Introduction to haskell
 

Viewers also liked

Futzing with actors (etc.)
Futzing with actors (etc.)Futzing with actors (etc.)
Futzing with actors (etc.)league
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Chris Richardson
 
Building microservices with Scala, functional domain models and Spring Boot (...
Building microservices with Scala, functional domain models and Spring Boot (...Building microservices with Scala, functional domain models and Spring Boot (...
Building microservices with Scala, functional domain models and Spring Boot (...Chris Richardson
 
Reactive Programming in Spring 5
Reactive Programming in Spring 5Reactive Programming in Spring 5
Reactive Programming in Spring 5poutsma
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Toshiaki Maki
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootChris Richardson
 

Viewers also liked (7)

Futzing with actors (etc.)
Futzing with actors (etc.)Futzing with actors (etc.)
Futzing with actors (etc.)
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...
 
Building microservices with Scala, functional domain models and Spring Boot (...
Building microservices with Scala, functional domain models and Spring Boot (...Building microservices with Scala, functional domain models and Spring Boot (...
Building microservices with Scala, functional domain models and Spring Boot (...
 
Reactive Spring Framework 5
Reactive Spring Framework 5Reactive Spring Framework 5
Reactive Spring Framework 5
 
Reactive Programming in Spring 5
Reactive Programming in Spring 5Reactive Programming in Spring 5
Reactive Programming in Spring 5
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring Boot
 

Similar to Continuations and Functional Patterns

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2Hang Zhao
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator PatternEric Torreborre
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)Eric Torreborre
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellMichel Rijnders
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For GoogleEleanor McHugh
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
API design: using type classes and dependent types
API design: using type classes and dependent typesAPI design: using type classes and dependent types
API design: using type classes and dependent typesbmlever
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type ClassesTapio Rautonen
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aidDavid Hoyt
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 

Similar to Continuations and Functional Patterns (20)

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
Monadologie
MonadologieMonadologie
Monadologie
 
The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Go: It's Not Just For Google
Go: It's Not Just For GoogleGo: It's Not Just For Google
Go: It's Not Just For Google
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
 
API design: using type classes and dependent types
API design: using type classes and dependent typesAPI design: using type classes and dependent types
API design: using type classes and dependent types
 
Generic Functional Programming with Type Classes
Generic Functional Programming with Type ClassesGeneric Functional Programming with Type Classes
Generic Functional Programming with Type Classes
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 

Recently uploaded

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
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
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
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
 

Recently uploaded (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
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
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
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
 

Continuations and Functional Patterns

  • 1. Continuations and other Functional Patterns Christopher League Long Island University Northeast Scala Symposium  February 
  • 3.
  • 4.
  • 5. Java classes → SML runtime Standard ML of New Jersey v110.30 [JFLINT 1.2] - Java.classPath := [”/home/league/r/java/tests”]; val it = () : unit - val main = Java.run ”Hello”; [parsing Hello] [parsing java/lang/Object] [compiling java/lang/Object] [compiling Hello] [initializing java/lang/Object] [initializing Hello] val main = fn : string list -> unit - main [”World”]; Hello, World val it = () : unit - main []; uncaught exception ArrayIndexOutOfBounds raised at: Hello.main([Ljava/lang/String;)V - ˆD
  • 6. OO runtime ← functional languages Scala Clojure F etc.
  • 7. Patterns . Continuation-passing style . Format combinators . Nested data types eme Higher-order {functions, types}
  • 8. Pattern : Continuations A continuation is an argument that represents the rest of the computation meant to occur after the current function.
  • 9. Explicit continuations – straight-line def greeting [A] (name: String) (k: => A): A = printk(”Hello, ”) { printk(name) { printk(”!n”)(k) }} def printk [A] (s: String) (k: => A): A = { Console.print(s); k } scala> greeting(”Scala peeps”) { true } Hello, Scala peeps! res0: Boolean = true
  • 10. Pay it forward... Current function can ‘return’ a value by passing it as a parameter to its continuation.
  • 11. Explicit continuations – return values def plus [A] (x: Int, y: Int) (k: Int => A): A = k(x+y) def times [A] (x: Int, y: Int) (k: Int => A): A = k(x*y) def less[A] (x: Int, y: Int) (kt: =>A) (kf: =>A):A = if(x < y) kt else kf def test[A](k: String => A): A = plus(3,2) { a => times(3,2) { b => less(a,b) {k(”yes”)} {k(”no”)} }} scala> test{printk(_){}} yes
  • 12. Delimited continuations reset Serves as delimiter for CPS transformation. shift Captures current continuation as a function (up to dynamically-enclosing reset) then runs specified block instead.
  • 13. Delimited continuations def doSomething0 = reset { println(”Ready?”) val result = 1 + ˜˜˜˜˜˜˜˜ * 3 println(result) } ink of the rest of the computation as a function with the hole as its parameter.
  • 14. Delimited continuations def doSomething1 = reset { println(”Ready?”) val result = 1 + special * 3 println(result) } def special = shift { k: (Int => Unit) => println(99); ”Gotcha!” } shift captures continuation as k and then determines its own future.
  • 15. Delimited continuations def doSomething1 = reset { println(”Ready?”) val result = 1 + special * 3 println(result) } def special = shift { k: (Int => Unit) => println(99); ”Gotcha!” } scala> doSomething1 Ready? 99 res0: java.lang.String = Gotcha!
  • 16. Continuation-based user interaction def interact = reset { val a = ask(”Please give me a number”) val b = ask(”Please enter another number”) printf(”The sum of your numbers is: %dn”, a+b) } scala> interact Please give me a number answer using: submit(0xa9db9535, ...) scala> submit(0xa9db9535, 14) Please enter another number answer using: submit(0xbd1b3eb0, ...) scala> submit(0xbd1b3eb0, 28) The sum of your numbers is: 42
  • 17. Continuation-based user interaction val sessions = new HashMap[UUID, Int=>Unit] def ask(prompt: String): Int @cps[Unit] = shift { k: (Int => Unit) => { val id = uuidGen printf(”%snanswer using: submit(0x%x, ...)n”, prompt, id) sessions += id -> k }} def submit(id: UUID, data: Int) = sessions(id)(data) def interact = reset { val a = ask(”Please give me a number”) val b = ask(”Please enter another number”) printf(”The sum of your numbers is: %dn”, a+b) }
  • 18. Pattern : Format combinators [Danvy ] Typeful programmers covet printf. int a = 5; int b = 2; float c = a / (float) b; printf(”%d over %d is %.2fn”, a, b, c); Cannot type-check because format is just a string. What if it has structure, like abstract syntax tree?
  • 19. Typed format specifiers val frac: Int => Int => Float => String = d & ” over ” & d & ” is ” & f(2) & endl | val grade: Any => Double => Unit = ”Hello, ”&s&”: your exam score is ”&pct&endl |> val hex: (Int, Int, Int) => String = uncurried(”#”&x&x&x|) (Type annotations are for reference – not required.) scala> println(uncurried(frac)(a,b,c)) 5 over 2 is 2.50 scala> grade(”Joshua”)(0.97) Hello, Joshua: your exam score is 97% scala> println(”Roses are ”&s | hex(250, 21, 42)) Roses are #fa152a
  • 20. Buffer representation type Buf = List[String] def put(b: Buf, e: String): Buf = e :: b def finish(b: Buf): String = b.reverse.mkString def initial: Buf = Nil
  • 21. Operational semantics def lit(m:String)(k:Buf=>A)(b:Buf) = k(put(b,m)) def x(k:Buf=>A)(b:Buf)(i:Int) = k(put(b,i.toHexString)) def s(k:Buf=>A)(b:Buf)(o:Any) = k(put(b,o.toString)) (Not the actual implementation.) lit(”L”)(finish)(initial) ”L” x(finish)(initial)(42) ”2a” where: type Buf = List[String] def put(b: Buf, e: String): Buf = e :: b def finish(b: Buf): String = b.reverse.mkString def initial: Buf = Nil
  • 22. Function composition (lit(”L”) & x) (finish) (initial) (2815) lit(”L”)(x(finish)) (initial) (2815) lit(”L”)(λ b0.λ i.finish(i.toHex :: b0)) (initial) (2815) (λ b1.λ i.finish(i.toHex :: ”L” :: b1)) (initial) (2815) finish(2815.toHex :: ”L” :: initial) List(”aff”,”L”).reverse.mkString ”Laff” where: def lit(m:String)(k:Buf=>A)(b:Buf) = k(put(b,m)) def x(k:Buf=>A)(b:Buf)(i:Int) = k(put(b,i.toHexString)) def s(k:Buf=>A)(b:Buf)(o:Any) = k(put(b,o.toString))
  • 23. Combinator polymorphism What is the answer type? x: ∀A.(Buf => A) => Buf => Int => A finish: Buf => String x(x(x(finish))) A ≡ String A ≡ Int => String A ≡ Int => Int => String
  • 24. Type constructor polymorphism trait Compose[F[_],G[_]] { type T[X] = F[G[X]] } trait Fragment[F[_]] { def apply[A](k: Buf=>A): Buf=>F[A] def & [G[_]] (g: Fragment[G]) = new Fragment[Compose[F,G]#T] { def apply[A](k: Buf=>A) = Fragment.this(g(k)) } def | : F[String] = apply(finish(_))(initial) }
  • 25. Combinator implementations type Id[A] = A implicit def lit(s:String) = new Fragment[Id] { def apply[A](k: Cont[A]) = (b:Buf) => k(put(b,s)) } type IntF[A] = Int => A val x = new Fragment[IntF] { def apply[A](k: Cont[A]) = (b:Buf) => (i:Int) => k(put(b,i.toHexString)) }
  • 26. Pattern : Nested data types Usually, a polymorphic recursive data type is instantiated uniformly throughout: trait List[A] case class Nil[A]() extends List[A] case class Cons[A](hd:A, tl:List[A]) extends List[A] What if type parameter of recursive invocation differs?
  • 27. Weird examples trait Weird[A] case class Wil[A]() extends Weird[A] case class Wons[A](hd: A, tl: Weird[(A,A)]) extends Weird[A] // tail of Weird[A] is Weird[(A,A)] val z: Weird[Int] = Wons(1, Wil[I2]()) val y: Weird[Int] = Wons(1, Wons((2,3), Wil[I4])) val x: Weird[Int] = Wons( 1, Wons( (2,3), Wons( ((4,5),(6,7)), Wil[I8]()))) type I2 = (Int,Int) type I4 = (I2,I2) type I8 = (I4,I4)
  • 28. Square matrices [Okasaki ] Vector[Vector[A]] is a two-dimensional matrix of elements of type A. But lengths of rows (inner vectors) could differ. Using nested data types, recursively build a type constructor V[_] to represent a sequence of a fixed number of elements. en, Vector[V[A]] is a well-formed matrix, and V[V[A]] is square.
  • 29. Square matrix example scala> val m = tabulate(6){(i,j) => (i+1)*(j+1)} m: FastExpSquareMatrix.M[Int] = Even Odd Odd Zero (((),((((),(1,2)),((3,4),(5,6)) ),(((),(2,4)),((6,8),(10,12))))),(((((),(3,6)),(( 9,12),(15,18))),(((),(4,8)),((12,16),(20,24)))),( (((),(5,10)),((15,20),(25,30))),(((),(6,12)),((18 ,24),(30,36)))))) scala> val q = m(4,2) q: Int = 15 scala> val m2 = m updated (4,2,999) m2: FastExpSquareMatrix.M[Int] = Even Odd Odd Zero (((),((((),(1,2)),((3,4),(5,6)) ),(((),(2,4)),((6,8),(10,12))))),(((((),(3,6)),(( 9,12),(15,18))),(((),(4,8)),((12,16),(20,24)))),( (((),(5,10)),((999,20),(25,30))),(((),(6,12)),(( 18,24),(30,36))))))
  • 30. Analogy with fast exponentiation fastexp r b 0 = r fastexp r b n = fastexp r (b2 ) n/2 if n even fastexp r b n = fastexp (r · b) (b2 ) n/2 otherwise For example: fastexp 1 b 6 = Even fastexp 1 (b2 ) 3 = Odd 2 fastexp (1 · b2 ) (b2 ) 1 = Odd 2 22 fastexp (1 · b2 · b2 ) (b2 ) 0 = Zero 2 1 · b2 · b2
  • 31. Fast exponentiation of product types type U = Unit type I = Int fastExp U I 6 = // Even fastExp U (I,I) 3 = // Odd fastExp (U,(I,I)) ((I,I),(I,I)) 1 = // Odd fastExp ((U,(I,I)),((I,I),(I,I))) // Zero (((I,I),(I,I)),((I,I),(I,I))) 0 = ((U,(I,I)),((I,I),(I,I)))
  • 32. Implementation as nested data type trait Pr[V[_], W[_]] { type T[A] = (V[A],W[A]) } trait M [V[_],W[_],A] case class Zero [V[_],W[_],A] (data: V[V[A]]) extends M[V,W,A] case class Even [V[_],W[_],A] ( next: M[V, Pr[W,W]#T, A] ) extends M[V,W,A] case class Odd [V[_],W[_],A] ( next: M[Pr[V,W]#T, Pr[W,W]#T, A] ) extends M[V,W,A] type Empty[A] = Unit type Id[A] = A type Matrix[A] = M[Empty,Id,A]
  • 33. anks! league@contrapunctus.net @chrisleague github.com/league/ slidesha.re/eREMXZ scala-fun-patterns Danvy, Olivier. “Functional Unparsing” J. Functional Programming (), . Okasaki, Chris. “From Fast Exponentiation to Square Matrices: An Adventure in Types” Int’l Conf. Functional Programming, .