Witchcraft

A presentation at VanBEAM in February 2016 in Vancouver, BC, Canada by Brooklyn Zelenka

Slide 1

Slide 1

MONADS FOR THE WORKING ALCHEMIST WITCHCRAFT

Slide 2

Slide 2

F F U ST F O S T O L MONADS FOR THE WORKING ALCHEMIST WITCHCRAFT

Slide 3

Slide 3

A B O U T T H I S TA L K • The Witchcraft suite: easier algebraic code for Elixir • Don’t need to know Haskell/Idris/PureScript/cat theory, but it helps • Throwing a lot at you (sorry) • Only covering a subset of what’s in these libraries • One takeaway:

Slide 4

Slide 4

B R O O K LY N Z E L E N K A • @expede • Founding partner at Robot Overlord • Runs the Vancouver Functional Programming and Vancouver Erlang/Elixir Meetups • Author of Witchcraft, TypeClass, Algae, Quark, Exceptional, and others • I have Witchcraft stickers (come see me afterwards)

Slide 5

Slide 5

W H AT ’ S I N A N A M E ? witchcraft noun /ˈwɪtʃˌkrɑːft/ 1. the art or power of bringing magical or preternatural power to bear or the act or practice of attempting to do so 2. the influence of magic or sorcery 3. fascinating or bewitching influence or charm 4. an Elixir library

Slide 6

Slide 6

W H AT ’ S S O M Y S T I C A L A B O U T I T ? • High abstraction is powerful but can look intimidating to newcomers • “Monads” • Category theoretic basis • Don’t need to know it • Hask → Ex WAT

Slide 7

Slide 7

WHY ALL THE EXTRA LIBRARIES? MAKING THE CASE

Slide 8

Slide 8

ALGEBRAIC CODE • “Algebra” here just means “a set of rules for manipulating related objects” • You can make your own algebras • Indeed you do without thinking about it • For example, many DSLs and protocols

Slide 9

Slide 9

ALGEBRAIC CODE • High confidence • Reusable abstractions (write once, run in many contexts) • Declarative, pure/concurrent safe code • More tools in your toolbox • Convenience • Well understood, principled, functional design patterns • Lenses, free monad + interpreter, DSLs • Unify similar concepts through abstraction • +/2, ++/2, <>/2, Map.merge/2, MapSet.union/2 have a lot in common (semigroup)

Slide 10

Slide 10

PRINCIPLES DRIVING DESIGN Compatibility with Elixir ecosystem Consistency with mental models Portability from other ecosystems Pedagogy and approachability

Slide 11

Slide 11

I would like to add a slightly different perspective to functional programming in the Erlang VM: functional programming is not a goal in the Erlang VM. It is a means to an end. When designing the Erlang language and the Erlang VM, Joe, Mike and Robert did not aim to implement a functional programming language, they wanted a runtime where they could build distributed, fault-tolerant applications. It just happened that the foundation for writing such systems share many of the functional programming principles. And it reflects in both Erlang and Elixir. – J O S E VA L I M h t t p : / / b l o g . p l a t a f o r m a t e c . c o m . b r / 2 0 1 6 / 0 5 / b e y o n d - f u n c t i o n a l - p r o g r a m m i n g - w i t h - e l i x i r- a n d - e r l a n g /

Slide 12

Slide 12

How can I make this more like Haskell? (Bulb paradox) – B R O O K LY N Z E L E N K A

Slide 13

Slide 13

QUARK • TYPECLASS • ALGAE BOOTSTRAPPING

Slide 14

Slide 14

BOOTSTRAPPING QUARK TYPECLASS WITCHCRAFT ALGAE

Slide 15

Slide 15

QUARK • Classic combinators QUARK TYPECLASS • id, flip, const, and so on • Function composition WITCHCRAFT • Currying • Very important for Witchcraft! • Some constructs must be curried, and for convenience we do this dynamically ALGAE

Slide 16

Slide 16

TYPECLASS • Principled type classes QUARK TYPECLASS • “Classes” and “methods” not the same as in OO • Properties & methods WITCHCRAFT • Hierarchies • Hiding side protocols from API • Enum + Enumerable ALGAE

Slide 17

Slide 17

ALGAE QUARK TYPECLASS WITCHCRAFT • DSL for writing related structs ALGAE

Slide 18

Slide 18

ALGAE defdata All of these fields Roughly “and” defsum One of these structs Roughly “or”

Slide 19

Slide 19

ALGAE

Slide 20

Slide 20

A L G A E . M AY B E • Many uses, but can be “something or failure”

Slide 21

Slide 21

KEEPING IT ELIXIR-Y CONSISTENCY & ETHOS

Slide 22

Slide 22

CONSISTENCY & ETHOS • Introducing these concepts in other languages has been uneven • Scalaz and Swiftz famously called “Haskell fan fiction” • Some Scala looks like Java, some looks like Haskell, and hard to intermingle the two • Elixir • Borrowed the friendly community from Ruby • Data flow and function application over classical expressions and composition • Dynamically typed, or “type checked at runtime”

Slide 23

Slide 23

CONSISTENCY & ETHOS The feeling that we’re trying to avoid

Slide 24

Slide 24

D I R E C T I O N A L I T Y & D ATA F L O W • Let’s bootstrap people’s intuitions! • Elixir prefers diagrammatic ordering D ATA 2 • Important to maintain consistency with rest of language! • Pipes are generally awesome • Want to maintain this awesomeness • What if we just gave the pipe operator superpowers? |> x * 2 4 |> y + 1 5

Slide 25

Slide 25

GIVING PIPES SUPERPOWERS 💪 • Witchcraft operators follow same flow D ATA 2 D ATA [1,2,3] • Data on flows through pointed direction |> x * 2 4 ~> x * 2 [2,4,6] |> • |> becomes ~> (curried map/2) y + 1 5 ~> y + 1 [3,5,7] • Just like pipes

Slide 26

Slide 26

A S Y N C VA R I A N T S Sequential Concurrent

Slide 27

Slide 27

GIVING PIPES SUPERPOWERS 💪 • Operators follow same flow • Data on flows through arrow direction • |> (_) apply/2 • ~> <~ map/2 MORE POWER • ~>> <<~ ap/2 • >>> <<< chain/2

Slide 28

Slide 28

THESE ARE FUNCTIONAL & PRINCIPLED D E S I G N PAT T E R N S

Slide 29

Slide 29

WITCHCRAFT 1.0 HIERARCHY SEMIGROUPOID C AT E G O R Y SEMIGROUP MONOID FOLDABLE FUNCTOR T R AV E R S A B L E A P P LY BIFUNCTOR EXTEND ARROW A P P L I C AT I V E CHAIN COMONAD MONAD

Slide 30

Slide 30

FUNCTOR HIERARCHY FUNCTOR T R AV E R S A B L E A P P LY A P P L I C AT I V E BIFUNCTOR EXTEND CHAIN COMONAD MONAD

Slide 31

Slide 31

FUNCTOR • Provides map/2 (~>), but different from Enum • Always returns the same type of data • No more manual Enum.map(…)|> Enum.into(…)

Slide 32

Slide 32

A P P LY: T H I N K I N G I N S I D E T H E B O X • Provides convey/2 and ap/2 • Embellishes basic function application • Specific embellishment changes per data type

Slide 33

Slide 33

A P P L I C AT I V E : P U T I N T O C O N T E X T • Provide of/2 • Simple: lift values into a datatype • Like List.wrap/1

Slide 34

Slide 34

CHAIN: FUNCTIONS TO ACTIONS • Like Apply & Applicative, but with a special “linking” function • Take raw value • Do something to it • Put the result into the original datatype • Makes it easy to chain functions in a context

Slide 35

Slide 35

POWERING UP GRAPH Application D ATA |> FUNCTION

R E S U LT Functor D ATA ~> FUNCTION

R E S U LT ( S ) Apply D ATA ~>> FUNCTION(S)

R E S U LT ( S ) Chain D ATA

LINKING FUN

R E S U LT ( S )

Slide 36

Slide 36

C H A I N D O N O TAT I O N • Macro to “linearize” chains • Gives us back an operational feel • Great DSLs (seen shortly)

Slide 37

Slide 37

M O N A D I C D O N O TAT I O N • Need to specify the data type • Just add return (specialized Applicative.of/2)

Slide 38

Slide 38

D O N O TAT I O N I M P L E M E N TAT I O N

Slide 39

Slide 39

LET’S SEE SOME CODE! S I M P L E D O - N O TAT I O N U S E S

Slide 40

Slide 40

WRITER MONAD Need to specify more about type in this case Add one to tally Square number We know how many times this has been run, in a pure fashion Run 3x = num ^ 2 ^ 2 ^ 2

Slide 41

Slide 41

WRITER MONAD Log initial value Add a “!” to input and log Return the result Run 3 times Log of transformations

Slide 42

Slide 42

P O W E R I N G U P D ATA F L O W ARROWS

Slide 43

Slide 43

ARROWS 20 4 X / 5 20 INPUT 21 SPLIT 20 4 X + 1 “1” “21” UNSPLIT INSPECT SPLIT UNSPLIT “44121” 21 21 X2 441 OUTPUT

Slide 44

Slide 44

ARROWS

Slide 45

Slide 45

FUTURE DIRECTIONS • More ADTs, more type classes • Pretty printing ADTs • Automatic deriving • Alternate minimal definitions (ex. right_fold or fold_map) • GenArrow

Slide 46

Slide 46

• hex.pm/packages/witchcraft • hex.pm/packages/quark THANK YOU • hex.pm/packages/algae • hex.pm/packages/type_class • @expede • brooklyn@robotoverlord.io