24
What is Ligretto? A case study in compositional and functional programming Peter Achten, Jurriën Stutterheim, László Domoszlai, Rinus Plasmeijer [email protected] , [email protected] , [email protected] , [email protected] Radboud University Nijmegen, Netherlands, ICIS, MBSD

What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Embed Size (px)

Citation preview

Page 1: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

What is Ligretto? A case study in compositional and functional programming

Peter Achten, Jurriën Stutterheim, László Domoszlai, Rinus Plasmeijer [email protected], [email protected], [email protected], [email protected]

Radboud University Nijmegen, Netherlands, ICIS, MBSD

Page 2: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

What is Ligretto?

FP day january 9 2015 / TU Twente 2

•  Card game for 2-12 players •  Simultaneous, not turn-based •  Player cards get moved to middle •  Player cards get moved per player •  It's hectic and fun!

Features: •  Application logic •  Interaction •  Coordination

FP

TOP iTask

Page 3: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

iTask = FP + Interaction + Coordination

FP day january 9 2015 / TU Twente 3

FP TOP

•  TOP paradigm for developing distributed multi-user applications •  Abstraction of work performed by computers and humans •  Tasks are observable and first-class citizens

Page 4: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

iTask = FP + Interaction + Coordination

FP day january 9 2015 / TU Twente 4

•  Typed abstraction: (Task m) •  Coordination via combinator functions (step (>>*), parallel, shared data sources, ...) •  Interaction via pure functions and editors

FP TOP viewSharedInformation :: Title [ViewOption r ] (RWShared r w) -> Task r | iTask r viewInformation :: Title [ViewOption r ] r -> Task r | iTask r

updateInformation :: Title [UpdateOption r r] r -> Task r | iTask r updateSharedInformation :: Title [UpdateOption r w] (RWShared r w) -> Task w | iTask r & iTask w

•  Compositional •  Implementation tool chain:

•  editlets, JavaScript, HTML, ... •  Works in any browser

Page 5: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Separation of concerns, part u

FP day january 9 2015 / TU Twente 5

FP model

TOP coordination

:: Card = { back :: Color , front :: Color , no :: Int } :: Color = Red | Green | Blue | Yellow

... updateSharedInformation name [] game >>* [OnValue player_wins] ...

C C D

Page 6: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

iTask = FP + Interaction + Coordination

FP day january 9 2015 / TU Twente 6

FP TOP

imageView :: (m -> Image m) -> ViewOption m | iTask m

imageUpdate :: (r -> m) (m -> Image m) (r m -> w) -> UpdateOption r w | iTask m

viewSharedInformation :: Title [ViewOption r ] (RWShared r w) -> Task r | iTask r viewInformation :: Title [ViewOption r ] r -> Task r | iTask r

updateInformation :: Title [UpdateOption r r] r -> Task r | iTask r updateSharedInformation :: Title [UpdateOption r w] (RWShared r w) -> Task w | iTask r & iTask w

customized

Page 7: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

iTask = FP + Interaction + Coordination

FP day january 9 2015 / TU Twente 7

•  Typed abstraction: (Image m) •  Interaction via pure functions and editors

FP TOP viewSharedInformation :: Title [ViewOption r ] (RWShared r w) -> Task r | iTask r viewInformation :: Title [ViewOption r ] r -> Task r | iTask r

updateInformation :: Title [UpdateOption r r] r -> Task r | iTask r updateSharedInformation :: Title [UpdateOption r w] (RWShared r w) -> Task w | iTask r & iTask w

•  Compositional •  Implementation tool chain:

•  editlets, JavaScript, HTML, SVG •  Works in any browser

•  Scalable by design •  XML-based standard by W3C •  Supported by major browsers •  Declarative by nature (mostly) •  Excellent hit detection

customized

Page 8: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Separation of concerns, part v

FP day january 9 2015 / TU Twente 8

FP model

Graphics.Scalable custom

interaction

TOP coordination

:: Card = { back :: Color , front :: Color , no :: Int } :: Color = Red | Green | Blue | Yellow

... updateSharedInformation name [imageUpdate ...] game >>* [OnValue player_wins] ... C

Page 9: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

A compositional Ligretto specification

FP day january 9 2015 / TU Twente 9

Model •  entities, relations •  rules of the game

Custom Interaction •  cards, layout, interaction

Coordination •  overall game structure

Page 10: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

FP day january 9 2015 / TU Twente 10

Model •  entities, relations •  rules of the game

:: Card = { back :: Color , front :: Color , no :: Int } :: Color = Red | Green | Blue | Yellow :: Pile :== [Card] :: Player = { color :: Color , row :: [Card] , ligretto :: Pile , hand :: Hand , seed :: Int } :: Hand = { conceal :: Pile , discard :: Pile } :: GameSt = { middle :: [Pile] , players :: [Player] } :: NoOfPlayers :== Int

play_concealed_pile :: Color GameSt -> GameSt play_hand_card :: Color GameSt -> GameSt play_row_card :: Color Int GameSt -> GameSt get_player :: Color GameSt -> Player colors :: NoOfPlayers -> [Color] initial_player :: NoOfPlayers Color Int -> Player

Page 11: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Coordination •  overall game structure

FP day january 9 2015 / TU Twente 11

play_Ligretto :: Task (Color,User) play_Ligretto = get currentUser >>= \me -> invite_friends >>= \you -> let us = zip2 (colors (1+length you)) [me:you] in allTasks (repeatn (length us) (get randomInt)) >>= \rs -> let game = { middle = repeatn 16 [] , players = [ initial_player (length us) c (abs r) \\ (c,_) <- us & r <- rs] } in withShared game (play_game us) invite_friends :: Task [User] invite_friends = enterSharedMultipleChoice "Select friends to play with" [] users >>= \you -> if (not (isMember (length you) [1..3])) ( viewInformation "Oops" [] "number of friends must be 1, 2, or 3" >>| invite_friends ) (return you)

Page 12: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Coordination •  overall game structure

FP day january 9 2015 / TU Twente 12

play_game :: [(Color,User)] (Shared GameSt) -> Task (Color,User) play_game us game_st = anyTask [u @: play (c,u) game_st \\ (c,u) <- us] >>= \w -> allTasks [u @: accolades w (c,u) game_st \\ (c,u) <- us] >>| return w play :: (Color,User) (Shared GameSt) -> Task (Color,User) play (c,u) game_st = updateSharedInformation (toString u) [imageViewUpdate id (player_perspective c) (\_ st -> st)] game_st >>* [OnValue player_wins] where player_wins (Value game _) | isEmpty (get_player c game).ligretto = Just (return (c,u)) player_wins _ = Nothing accolades :: (Color,User) (Color,User) (Shared GameSt) -> Task GameSt accolades (_,winner) (c,_) game_st = viewSharedInformation ("The winner is " <+++ winner) [imageView (player_perspective c)] game_st

Page 13: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

• Compositional images: •  which are the image patterns?

•  which are the layout patterns?

•  which are the image layers? •  Interactive images:

•  which (composite) images are interactive? FP day january 9 2015 / TU Twente 13

Page 14: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Graphics.Scalable concepts, part u •  Every value of type (Image m):

•  is infinitely wide and perfectly transparent •  has a local coordinate system defined by the span box •  measures are Span values (px :: Real -> Span) •  can be subject to transformation:

scaling, skewing, rotating, flipping, and masking

•  Basic images: the usual suspects •  empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

•  Image attributes •  attributes alter appearance but not span box class <@< attr :: (Image m) (attr m) -> Image m

FP day january 9 2015 / TU Twente 14

same as SVG name-attribute pairs

Page 15: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 15

card_width = px 58.5 card_height = px 90.0 no_stroke_color Red = Blue no_stroke_color Green = Red no_stroke_color Blue = Green no_stroke_color Yellow = Green instance toSVGColor Color where toSVGColor Red = toSVGColor "darkred" toSVGColor Green = toSVGColor "darkgreen" toSVGColor Blue = toSVGColor "midnightblue" toSVGColor Yellow = toSVGColor "gold" card_shape = rect card_width card_height <@< {xradius = card_height /. 18} <@< {yradius = card_height /. 18} cardfont size = normalFontDef "Verdana" size big_no no color = text (cardfont 20.0) (toString no) <@< {fill = toSVGColor "white"} <@< {stroke = toSVGColor color } ligretto color = text (cardfont 12.0) "Ligretto" <@< {fill = toSVGColor "none" } <@< {stroke = toSVGColor color }

Page 16: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Graphics.Scalable concepts, part v •  Image composition is just stacking (z-axis) and aligning (x-, y-axis)

:: Layout m :== [ImageOffset] [Image m] (Host m) -> Image m

:: Host m :== Maybe (Image m)

:: ImageOffset :== (Span, Span)

collage :: Layout m

•  Derived image composition functions: overlay, beside, above, grid, margin

FP day january 9 2015 / TU Twente 16

Page 17: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 17

card_image :: SideUp Card -> Image m card_image side card | side === Front = let no = margin (px 5.0) (big_no card.no (no_stroke_color card.front)) in overlay [(AtMiddleX,AtTop),(AtMiddleX,AtBottom)] [] [no, rotate (deg 180.0) no] host | otherwise = overlay [(AtLeft,AtBottom)] [] [skewy (deg -20.0) (ligretto card.back)] host where host = Just (card_shape <@< {fill = if (side === Front) (toSVGColor card.front) (toSVGColor "white")})

card = {back = Red, front = Green, no = 7}

Page 18: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 18

no_card_image :: Image m no_card_image = overlay [(AtMiddleX,AtMiddleY)] [] [text (cardfont 12.0) "empty"] (Just (card_shape <@< {fill = toSVGColor "lightgrey"})) pile_of_cards :: SideUp Pile -> Image m pile_of_cards side pile = overlay [] [(zero,card_height /. 18 *. dy) \\ dy <- [0..]] (map (card_image side) (reverse pile)) host where host = Just no_card_image pile_image :: SideUp Pile -> Image m pile_image side pile | no_of_cards > 10 = above [AtMiddleX] [] [text (cardfont 10.0) (toString no_of_cards) ,top_cards_image] Nothing | otherwise = top_cards_image where no_of_cards = length pile top_cards_image = pile_of_cards side (take 10 pile)

Page 19: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 19

middle_image :: [Pile] -> Image m middle_image middle = circular (card_height *. 2) (2.0 * pi) (map (pile_image Front) middle)) circular :: Span Real [Image m] -> Image m circular r a imgs = overlay (repeat (AtMiddleX,AtMiddleY)) [ (~r *. cos angle, ~r *. sin angle) \\ i <- [0.0, sign_a ..] , angle <- [i * alpha - pi / 2.0] ] [ rotate (rad (i * alpha)) img \\ i <- [0.0, sign_a ..] & img <- imgs ] (Just (empty (r *. 2) (r *. 2))) where sign_a = toReal (sign a) alpha = (toRad (normalize (rad a)))/(toReal (length imgs))

Page 20: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Graphics.Scalable concepts, part w •  Any (compositional) image is made interactive with the on-click attribute:

:: OnClickAttr m = { onclick :: (m -> m) }

instance <@< OnClickAttr

tuneIf :: Bool (Image m) (attr m) -> Image m | <@< attr

tuneIf yes img attr = if yes (img <@< attr) img

FP day january 9 2015 / TU Twente 20

Page 21: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 21

row_images :: Bool [Card] -> [Image GameSt] row_images interactive row = [ tuneIf interactive (card_image Front row_card) {onclick = play_row_card row_card.back no} \\ row_card <- row & no <- [1..] ] hand_images :: Bool Hand Color -> [Image GameSt] hand_images interactive {conceal,discard} c = [ tuneIf interactive (pile_image Back conceal) {onclick = play_concealed_pile c}, space , tuneIf interactive (pile_image Front discard) {onclick = play_hand_card c} ] space = empty (card_width /. 4) zero player_image :: Bool Span Player -> Image GameSt player_image interactive r player = circular r (0.4*pi) ( row_images interactive player.row ++ [space, pile_image Front player.ligretto, space] ++ hand_images interactive player.hand player.color )

Page 22: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Custom Interaction •  cards, layout, interaction

FP day january 9 2015 / TU Twente 22

game_image :: Color GameSt -> Image GameSt game_image color game = overlay (repeat (AtMiddleX,AtMiddleY)) [] [ rotate (rad (i * angle - 0.25 * pi)) img \\ img <- [ player_image (player.color === color) r player \\ player <- game.players ] & i <- [0.0, 1.0..] ] (Just (middle_image game.middle)) where r = card_height *. 4 angle = 2.0 * pi / (toReal (length game.players)) player_perspective :: Color GameSt -> Image GameSt player_perspective color game = rotate (rad (0.05 * pi - toReal my_no * angle)) (game_image color game) where my_no = hd [i \\ player <- game.players & i <- [0 .. ] | player.color === color ] angle = 2.0 * pi / (toReal (length game.players))

Page 23: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Graphics.Scalable to SVG challenges

•  SVG transformations vs Graphics.Scalable transformations •  SVG maintains a Current Transformation Matrix (CTM) for each image’s axes,

not the images •  Every transformation alters the CTM, therefore the axes •  SVG users need to think about the order in which transformations are applied •  Graphics.Scalable transforms the images, not the axes

•  Text widths can only be calculated on the client •  Width crucial for layout combinators •  Round-trip to client required

•  SVG API is lacking regarding font metrics •  ascent, descent, and x-height

FP day january 9 2015 / TU Twente 23

Page 24: What is Ligretto? - Universiteit Twentejankuper/fp-dag/ligretto.pdfWhat is Ligretto? A case study in ... • empty, text, circle, ellipse, rect, polygon, polyline, xline, yline, line

Current and future work

• More performance improvements • Complete the event model (currently limited to on-click) • Tonic: An Infrastructure to Graphically Represent the Definition and

Behaviour of Tasks1 (TFP'14) • Extend Graphics.Scalable layout formalism to include task layout

FP day january 9 2015 / TU Twente 24

1 http://link.springer.com/chapter/10.1007/978-3-319-14675-1_8