• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
G meredith scala
 

G meredith scala

on

  • 994 views

Monadic Design Patterns for the Web

Monadic Design Patterns for the Web

Statistics

Views

Total Views
994
Views on SlideShare
994
Embed Views
0

Actions

Likes
0
Downloads
19
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    G meredith scala G meredith scala Presentation Transcript

    • Monadic Design Patterns for the Web Session 1Monday, October 17, 2011
    • Agenda • What to expect • Who is the audience • Why monads • The monadic toolbox • A simple example • Another simple example Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Agenda (cont) • Hinting at a more complex example • Where we might go from here • Questions? Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect • Fun! • Simplicity! • Engagement! • Ok... and some challenge • Occasionally, people’s brains do melt out of their ears... Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Service Domain Logic Browser Container Resource Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Service Domain Logic Browser Container Resource Monads for managing streams Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Monads for managing requests Service Domain Logic Browser Container Resource Monads for managing streams Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Monads for domain model Monads for managing requests Service Domain Logic Browser Container Resource Monads for managing streams Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Monads for domain model Monads for managing requests Service Domain Logic Browser Monads for accessing store Container Resource Monads for managing streams Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect Algebraic data types Parsing combinators Service Domain Logic Browser LINQ XQuery SQL Container Resource streams and continuations Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • What to expect • Monads provide a practical abstraction for everyday sorts of control flow and data structure in modern web app • If objects were supposed to be the packaging of control and structure that provided optimal reuse, then monads seem to be a better object than object Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Who is the audience • People who write code that serves a purpose • Monads will feel natural to those with 2yrs functional programming • Or, people who have 2yrs with distributed and network programming • Nota bene: all code examples in Scala! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Who is the audience • But, really, monads are everywhere! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Why monads • To manage complexity • Monads help your code scale • Abstract structure and control • Engage the compiler more • Compositional Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • The monadic toolbox • What is a monad? • Shape, wrap and roll, baby! • Monads in a larger context • Comprehensive comprehensions! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Shapely monads • Three key ingredients in a monad • Shape • wrap • rollMonday, October 17, 2011
    • Embracing shape “monads” Shape “eh?” roll “eh?” wrap “monads,” “eh?” “eh?”Monday, October 17, 2011
    • Embracing shape • Monads may be canonically thought of as a way to structure an interface to “colored” braces • Shape -- the color of the braces [ ] • wrap -- putting things between braces [ “eh?” ] • roll -- flattening nested braces (i.e. rolling them up) [ [ “monads” ] [ “eh?” ] ] [ “monads” , “eh?” ]Monday, October 17, 2011
    • Embracing shape Shape : <red> ... </red> wrap : queen => <red>queen</red> roll : <red><red>knight</red><red>queen</red></red> => <red>knight queen</red>Monday, October 17, 2011
    • Data structures as “colored” braces Shape : <list> ... </list> wrap : queen => <list>queen</list> roll : <list><list>knight</list><list>queen</list></list> => <list>knight queen</list>Monday, October 17, 2011
    • Data structures as “colored” braces Shape : <set> ... </set> wrap : queen => <set>queen</set> roll : <set><set>knight</set><set>queen</set></set> => <set>knight queen</set>Monday, October 17, 2011
    • Monads refactor container code • List and Set are actually the same structure up to a certain point -- the difference can be captured by a set of equations that Sets obey and Lists don’t • a + b = b + a • a + a = a • How do we relate these equations to Shape, wrap and roll?Monday, October 17, 2011
    • Monads refactor container code a + b could just as easily be written +( a, b ) which could just as easily be written <+> a b </+> which could just as easily be written roll( <+><+>a</+><+>b</+></+> ) which could just as easily be written roll( <+> wrap( a ) wrap( b ) </+> ) or roll( wrap( a ) + wrap( b ) )Monday, October 17, 2011
    • Monads refactor container code wrap( a ) + wrap( b ) in the case of both List and Set as long as we have safely ‘wrapped’ everything, then ‘+’ is the natural polymorphic interpretation in the ‘container’ Set1 + Set2 := Set1 U Set2 List1 + List2 := List1 append List2Monday, October 17, 2011
    • Monads refactor container code Set1 U Set2 == Set2 U Set1 (not true of Lists) Set1 U Set1 == Set1 (not true of Lists)Monday, October 17, 2011
    • Monads refactor container code wrap( a ) + wrap( b ) <set><set>a</set> <set>b</set></set> if this is really Set then this has to be the same as <set><set>b</set> <set>a</set></set> aka wrap( b ) + wrap( a )Monday, October 17, 2011
    • Monads refactor container code • So List and Set can actually be thought of as factored into two pieces of information • ( M, equations ) where • M is the colored brace structure (Shape-wrap-n-roll) • the equations give additional constraints about how braces behave. • Lists have no additional equations -- such structures are called free.Monday, October 17, 2011
    • Monads refactor container code Every monad can be seen as a version of a data structure that has a ‘+’ and a unit for the ‘+’, 1. We’ve seen how the brace metaphor gives a simple model of how the extra structure of wrap and roll allow to extend ‘+’ over entities we put inside the monadic container roll( wrap( a ) + wrap( b ) ) It also relates the unit, 1, of the ‘+’ to wrap (which is often called the unit of the monad)Monday, October 17, 2011
    • Monads refactor container code The unit of the ‘+’ has a canonical representation as the empty braces: <red> </red> roll( <red><red> </red> <red> queen </red></red> ) = <red> queen </red> = roll( <red><red> queen </red><red> </red></red> )Monday, October 17, 2011
    • A simple example class MList[A]( elems : A* ) extends List[A]( elems ) { def wrap ( a : A ) : MList[A] = { new MList( a ) } def roll ( mma : MList[MList[A]] ) : MList[A] = { ( Nil /: mma )( ( acc, ma ) => acc.append( ma ) ) } } Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • A simple example (cont) • What can we say about this code? • What about legacy uses of List? • What about future uses of List? Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • A simple example trait Option[+A] case class Some[+A]( a : A ) extends Option[A] case object None extends Option[Nothing] for( Some( a ) <- optA ) yield { f( a ) } Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Another simple example trait LeftRightTree[A] case class Leaf[A]( a : A ) extends LeftRightTree[A] case class Branch[A]( left : List[LeftRightTree[A]], right : List[LeftRightTree[A]] ) extends LeftRightTree[A] Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Another simple example (cont) • We have a choice when we implement unit def wrap( a : A ) : LeftRightTree[A] = { Branch( List( a ), Nil ) } or def wrap( a : A ) : LeftRightTree[A] = { Branch( Nil, List( a ) ) } Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • The Monadic API as a View if you google for Shape, wrap and roll, you’ll only find my presentations; if you use unit/ yield/return and mult/bind, you’ll find lots of hits shape trait Monad[M[_]] { wrap def unit [A] ( a : A ) : M[A] def bind [A,B] ( ma : M[A], fn : A => M[B] ) : M[B] } jelly roll Lucius Gregory Meredith, Managing Partner, Biosimiliarity LLCMonday, October 17, 2011
    • A word about presentations def bind [A,B] ( ma : M[A], f : A => M[B] ) : M[B] = { mult( fmap( f )( ma ) ) } def fmap [A,B] ( f : A => B ) : M[A] => M[B] def mult [A] ( mma : M[M[A]] ) : M[A] = { bind[M[A],A]( mma, ( ma ) => ma ) i confess! this is all a plot to expose you subliminally to } Category Theory Lucius Gregory Meredith, Managing Partner, Biosimiliarity LLCMonday, October 17, 2011
    • The Monadic API as a View class ListM[A] extends Monad[List] { override def unit [S] ( s : S ) : List[S] = { List[S]( s ) } override def bind [S,T] ( ls : List[S], fn : S => List[T] ) = { ( ( Nil : List[T] ) /: ls )( { ( acc, e ) => { acc ++ fn( e ) } } ) } } Lucius Gregory Meredith, Managing Partner, Biosimiliarity LLCMonday, October 17, 2011
    • Two kinds of collections • Extensional • We can explicitly give each element of the collection • Intensional • We must specify the elements programmatically -- such as by a ruleMonday, October 17, 2011
    • Embracing shape Shape : <red> ... </red> wrap : queen => <red>queen</red> roll : <red><red>knight</red><red>queen</red></red> => <red>knight queen</red>Monday, October 17, 2011
    • Two kinds of collections • Extensional -- examples • { a, b, c } • ( 1, 2, 3 ) • f(1) + g(2) + h(3) • Intensional • { a in Nat | a % 2 == 0 } • fibs = 0 :: 1 :: zipWith (+) fibs (tail fibs) • ∑ fi ( i )Monday, October 17, 2011
    • Situations and intensions • Infinite collections -- fibs, primes, etc, and also languages! • Compressed collections -- individual elements are more easily computed than stored or otherwise expressed • Collections calculated from data from the environment -- such as user inputMonday, October 17, 2011
    • Intensionally lazy • Infinite collections require some form of laziness or “just-in-time-ness” to avoid consuming all available memory • Compressed collections can make use of laziness to avoid consuming compute cycles until it’s necessary • Lazy also blurs the boundary between computing something just in time and waiting on i/oMonday, October 17, 2011
    • In the stream... • More importantly the web 2.0 is teaching us that what initially looks like a small thing type TwitterMsg = Char [140] // not legal Scala becomes pretty valuable when it is iterated into a stream abstract class TwitterStream case class Twitterful( msg : TwitterMsg, strm : TwitterStream ) extends TwitterStreamMonday, October 17, 2011
    • Intensions and comprehensions { pattern | generator1, ..., generatorM, condition1, ..., conditionN } ≈ for( generator1; ...; generatorM; condition1;...; conditionN ) yield { pattern } ≈ SELECT pattern FROM generator1, ..., generatorN WHERE condition1, ..., conditionNMonday, October 17, 2011
    • Intensions and comprehensions Consider Set[A] { a, b, c, ... } the language of extensional collections comes from the constructors of the type, A, we said we’d put in the collection, together with the Set operators { pattern | generator1, ..., generatorM, condition1, ..., conditionN } where does the language of patterns and conditions come from?Monday, October 17, 2011
    • Intensions and comprehensions If monads are like containers, where’s the “take something out of the container interface”?Monday, October 17, 2011
    • The Monadic API as a View shape trait Monad[M[_]] { wrap def unit [A] ( a : A ) : M[A] def bind [A,B] ( ma : M[A], fn : A => M[B] ) : M[B] } jelly roll Lucius Gregory Meredith, Managing Partner, Biosimiliarity LLCMonday, October 17, 2011
    • Intensions and the Ruby Slippers Q: When can you check an element out of a monad? A: With map you can check out (anything) any time you want, but you can never leave! f : A => B M[f] : M[A] => M[B]Monday, October 17, 2011
    • Intensions and the Ruby Slippers def transformResults( normalizeResults : A => B ) : Option[B] = { val intermediateRslts : Option[A] = getRawResults( ... ) for( rslt <- intermediateRslts ) yield { normalizeResults( rslt ) } }Monday, October 17, 2011
    • Intensions and comprehensions for( ptn <- src ; if condition ) yield { e( ptn ) } ≈ src.map( p => p match { case ptn => if condition { e( ptn ) } case _ => throw new Exception( “” ) } )Monday, October 17, 2011
    • Intensions and comprehensions SELECT pattern FROM generator1, ..., generatorN WHERE condition1, ..., conditionN for( ptn <- src ; if condition ) yield { e( ptn ) } ≈ src.map( p => p match { case ptn => if condition { e( ptn ) } case _ => throw new Exception( “” ) } )Monday, October 17, 2011
    • Intensions and comprehensions SELECT pattern FROM generator1, ..., generatorN WHERE condition1, ..., conditionN for( ptn <- src ; if condition ) yield { e( ptn ) } ≈ { pattern | generator1, ..., generatorM, condition1, ..., conditionN } src.map( p => p match { case ptn => if condition { e( ptn ) } case _ => throw new Exception( “” ) } )Monday, October 17, 2011
    • Comprehension syntax for( x <- expr1 ; y <- expr2 ; <stmts> ) yield expr3 = expr1 flatMap( x => for( y <- expr2; <stmts> ) yield expr3 ) for( x<-expr1 ; y = expr2 ;<stmts> ) yield expr3 = for( ( x, y ) <- for( x <- expr1 ) yield ( x , expr2 ); <stmts> ) yield expr3 for( x <- expr1 if pred ) yield expr2 = expr1 filter(x => pred) map (x => expr2 )Monday, October 17, 2011
    • Three kinds of monad? • Stuff goes in but never comes out -- the IO-monad • Stuff goes in and sometimes comes out -- nearly all standard collections • Every thing that goes in is matched by something coming out -- linearly typed collections Notice that these correspond to transactional modes!Monday, October 17, 2011
    • Towards a more complex example • Parsing • Moral: the dog doesn’t bark • Evaluation • Moral: the dog barks quietly -- even in a distributed setting • Storage? Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • REPLs and Web Apps and DSLs, oh my! Service Domain Logic Browser Container Resource Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • REPLs and Web Apps and DSLs, oh my! Service Domain Logic Browser Container Resource Non-blocking continuation-based request handling Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • REPLs and Web Apps and DSLs, oh my! User actions become expressions in a DSL Service Domain Logic Browser Container Resource Non-blocking continuation-based request handling Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • REPLs and Web Apps and DSLs, oh my! Domain model = User actions become abstract syntax of expressions DSL in a DSL Service Domain Logic Browser Container Resource Non-blocking continuation-based request handling Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • REPLs and Web Apps and DSLs, oh my! Domain model = User actions become abstract syntax of expressions DSL in a DSL Service Domain Logic Browser Evaluation as a service Container Resource Non-blocking continuation-based request handling Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing - compositional at multiple levels Syntax tree Expressions in a DSL Parser Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing Concrete syntax Abstract syntax Normalization Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing Abstract syntax Domain value Evaluation Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing (DSLs) • The surface API for parsing doesn’t (have to) change • Grammars are already compositional: grammars are algebras! • The programmatic API changes: parser combinators Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing (DSLs) • Internal vs External • Parsing combinators vs higher level abstraction • Domain requirements Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Internal vs External DSLs • External • independent, self-contained language with own grammar and semantics • Example: SQL is a DSL for accessing relational storage Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Internal vs External DSLs • Internal • embedded or hosted DSL • makes use of expressions and computations in ambient language • examples • lex/yacc -- semantic actions in C • LINQ -- internal DSL for accessing storage Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Parsing combinators vs higher level abstraction • Parsing combinators • provide compositional mechanism • work well in embedded situation • BNF and other higher level abstractions • considerably more concise • target multiple platforms Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Example term ::= symbol( term* ) | list | variable | ground ground ::= strLit | numLit | boolLit variable ::= uppercaseIdent symbol ::= lowercaseIdent Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Example class TermParser extends JavaTokenParsers { def term : Parser[Any] = application | list | ground | variable def list : Parser[Any] = "["~repsep( term, "," )~"]" def ground : Parser[Any] = stringLiteral | floatingPointNumber | "true" | "false" def variable : Parser[Any] = ident def application : Parser[Any] = ident~"("~repsep( term, "," )~")" } Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Domain requirements • When DSL supports service-based/ program-to-program computing • language is “closed” -- no expression sublanguage • When DSL supports human-interaction • language is often “open” -- containing some expression sublanguage Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • DSLs and algebras • An algebra is a domain model (and don’t you forget it!) • An algebra is the abstract syntax to the ... • ... concrete syntax of a DSL Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Algebras • Algebras and types are closely related • Functional types are algebraic data types • Understanding how these are related and languages for manipulating them will get you far • Most importantly -- algebras are monads! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Monads refactor container code • List and Set are actually the same structure up to a certain point -- the difference can be captured by a set of equations that Sets obey and Lists don’t • a + b = b + a • Remember this? a + a = a • How do we relate these equations to Shape, wrap and roll?Monday, October 17, 2011
    • Monads refactor container code • So List and Set can actually be thought of as factored into two pieces of information • ( M, equations ) And this? where • M is the colored brace structure (Shape-wrap-n-roll) • the equations give additional constraints about how braces behave. • Lists have no additional equations -- such structures are called free.Monday, October 17, 2011
    • Monads and algebras • An algebra is expressed entirely as a set of generators • ≈ constructors • ≈ grammar • and relations aka equations • Generators and relations are 2/3’s of the specification of a DSLMonday, October 17, 2011
    • Where we might go from here • We haven’t talked about control flow • So, let’s talk a little about it... Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Why monads -- did we do what we promised? • To manage complexity • Monads help your code scale • Abstract structure and control • Engage the compiler more • Compositional Actually... monads don’t necessarily compose! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
    • Questions? Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011