G meredith scala

1,048 views

Published on

Monadic Design Patterns for the Web

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,048
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
22
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

G meredith scala

  1. 1. Monadic Design Patterns for the Web Session 1Monday, October 17, 2011
  2. 2. 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
  3. 3. 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
  4. 4. 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
  5. 5. What to expect Service Domain Logic Browser Container Resource Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
  6. 6. 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
  7. 7. 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
  8. 8. 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
  9. 9. 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
  10. 10. 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
  11. 11. 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
  12. 12. 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
  13. 13. Who is the audience • But, really, monads are everywhere! Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
  14. 14. 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
  15. 15. 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
  16. 16. Shapely monads • Three key ingredients in a monad • Shape • wrap • rollMonday, October 17, 2011
  17. 17. Embracing shape “monads” Shape “eh?” roll “eh?” wrap “monads,” “eh?” “eh?”Monday, October 17, 2011
  18. 18. 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
  19. 19. 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
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 24. 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
  25. 25. 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
  26. 26. 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
  27. 27. 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
  28. 28. 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
  29. 29. 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
  30. 30. 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
  31. 31. 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
  32. 32. 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
  33. 33. 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
  34. 34. 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
  35. 35. 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
  36. 36. 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
  37. 37. 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
  38. 38. 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
  39. 39. 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
  40. 40. 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
  41. 41. 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
  42. 42. 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
  43. 43. 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
  44. 44. 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
  45. 45. 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
  46. 46. Intensions and comprehensions If monads are like containers, where’s the “take something out of the container interface”?Monday, October 17, 2011
  47. 47. 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
  48. 48. 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
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. 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
  53. 53. 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
  54. 54. 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
  55. 55. 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
  56. 56. 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
  57. 57. 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
  58. 58. 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
  59. 59. 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
  60. 60. 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
  61. 61. Parsing - compositional at multiple levels Syntax tree Expressions in a DSL Parser Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
  62. 62. Parsing Concrete syntax Abstract syntax Normalization Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
  63. 63. Parsing Abstract syntax Domain value Evaluation Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011
  64. 64. 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
  65. 65. 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
  66. 66. 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
  67. 67. 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
  68. 68. 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
  69. 69. 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
  70. 70. 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
  71. 71. 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
  72. 72. 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
  73. 73. 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
  74. 74. 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
  75. 75. 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
  76. 76. 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
  77. 77. 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
  78. 78. 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
  79. 79. Questions? Lucius Gregory Meredith, Managing Partner, Biosimilarity LLC -- SDEC 2011Monday, October 17, 2011

×