SlideShare una empresa de Scribd logo
1 de 33
Descargar para leer sin conexión
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, .

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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
 

Destacado

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
 

Destacado (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 a 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 a 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
 

Último

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 

Último (20)

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 

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, .