talk.tex 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. % Copyright (C) 2017 Koz Ross <koz.ross@retro-freedom.nz>
  2. % This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
  3. % International License. To view a copy of this license, visit
  4. % http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative
  5. % Commons, PO Box 1866, Mountain View, CA 94042, USA.
  6. \documentclass{beamer}
  7. \usepackage[utf8]{inputenc}
  8. \usecolortheme{seahorse}
  9. \usefonttheme{professionalfonts}
  10. \usepackage{fontspec}
  11. \setmainfont{DejaVu Sans}
  12. \setbeamertemplate{navigation symbols}{}
  13. \usepackage{caption}
  14. \usepackage[font=itshape, begintext=``, endtext='']{quoting}
  15. \usepackage{fancyvrb}
  16. \usepackage{color}
  17. \title{Functors}
  18. \subtitle{Or: why your abstractions are weak}
  19. \titlegraphic{\includegraphics[scale=0.8]{img/logo.pdf}}
  20. \author{Koz Ross}
  21. \date{18th May, 2017}
  22. \begin{document}
  23. \begin{frame}[c]
  24. \titlepage{}
  25. \end{frame}
  26. \begin{frame}[c]
  27. \frametitle{Outline}
  28. \tableofcontents
  29. \end{frame}
  30. \section{Introduction}
  31. \begin{frame}
  32. \frametitle{Things we want to have when programming}
  33. When we write code, all the following are pretty vital:\pause{}
  34. \bigskip
  35. \begin{itemize}
  36. \item Error handling (unlabelled and labelled)\pause{}
  37. \item Nondeterminism (multiple answers)\pause{}
  38. \item Side effects (file handling, GUIs, database operations,\ldots)\pause{}
  39. \item Metadata handling (information about data)\pause{}
  40. \item Containers (lists, dictionaries, trees,\ldots)\pause{}
  41. \end{itemize}
  42. \bigskip
  43. These things are very different, aren't they?\pause{} Your programming
  44. languages sure seem to think so\ldots
  45. \end{frame}
  46. \begin{frame}[c,fragile]
  47. \frametitle{The truth}
  48. \begin{center}
  49. \includegraphics[scale=0.65]{img/morpheus.pdf}
  50. \pause{}
  51. \bigskip
  52. Yes, your languages have been \alert{{\em lying\/}} to you.
  53. \end{center}
  54. \end{frame}
  55. \begin{frame}
  56. \frametitle{The fantastic functor}
  57. The {\em functor\/} is an abstraction which unifies {\em all\/} of the above:
  58. we can code to functors, and that code will {\em provably\/} work
  59. \alert{for every single one of those cases}.\pause{} Well, and plenty more
  60. besides\ldots\pause{}
  61. \bigskip
  62. Functors have been known about for {\em over forty years},
  63. and have been implemented in programming languages {\em since 1990}.\pause{}
  64. They are easy to understand, easy to use, and generally awesome.\pause{}
  65. \bigskip
  66. \alert{If your `high-level' language doesn't have them, your language is {\em weak}.}\pause{}
  67. If you haven't been {\em taught\/} them, \alert{your {\em instructors\/}
  68. are weak} (pointing no fingers, of course).\pause{}
  69. \bigskip
  70. \begin{center}
  71. \Large Let's fix this, shall we?
  72. \end{center}
  73. \end{frame}
  74. \section{Some formalisms}
  75. \begin{frame}[fragile]
  76. \frametitle{Types}
  77. A {\em type\/} is a set of rules.\pause{} {\em Values\/} can have types (which
  78. indicate what we can do with them), but {\em variables\/} can have them too
  79. (and that tells us what values they can hold).\pause{}
  80. \bigskip
  81. \begin{Verbatim}[commandchars=\\\{\}]
  82. \color{gray}-- I'm a comment!
  83. 1 :: Int \color{gray}-- we're asserting that 1 is an Int
  84. 1 :: Real \color{gray}-- same look, different meaning
  85. (3, 2.5) :: (Int, Real) \color{gray}-- a pair
  86. ["foo", "bar", "baz"] :: [String] \color{gray}--a list\pause{}
  87. x :: Int \color{gray}-- the variable x holds ints (declaration)
  88. x = 10 \color{gray}-- specifically this one (definition)\pause{}
  89. plus :: Int -> Int -> Int \color{gray}-- functions have types too!
  90. plus x y = x + y \color{gray}-- and definitions
  91. \end{Verbatim}
  92. \end{frame}
  93. \begin{frame}[fragile]
  94. \frametitle{Type parameterization}
  95. Instead of giving a type, we can use a {\em type parameter\/}:\pause{}
  96. \bigskip
  97. \begin{Verbatim}[commandchars=\\\{\}]
  98. \color{gray}-- take a value of any type, return one of the same
  99. id :: a -> a
  100. id x = x \color{gray}-- we're gonna see this one too!\pause{}
  101. \color{gray}-- we can have as many type parameters as we want!
  102. swap :: (a, b) -> (b, a)
  103. swap (x,y) = (y,x) \color{gray}-- just like you expected
  104. \end{Verbatim}
  105. \pause{}
  106. \bigskip
  107. We will typically use \verb+a,b+ for type parameters.
  108. \end{frame}
  109. \begin{frame}[fragile]
  110. \frametitle{Our own types}
  111. We can define our own types by putting together descriptions of what they
  112. contain, based on existing types:\pause{}
  113. \bigskip
  114. \begin{Verbatim}[commandchars=\\\{\}]
  115. \color{gray}-- similar to a struct
  116. \color{gray}-- type name on left, constructor name on right
  117. data Name = Name \{ first :: String, last :: String \}\pause{}
  118. \color{gray}-- similar to an enum
  119. data Colour = Red | Green | Blue\pause{}
  120. \color{gray}-- we can mix these two forms
  121. \color{gray}-- can be parametrized by type(s) if we wish
  122. data Maybe a = Nothing | Just a
  123. data Either a b = Left a | Right b\pause{}
  124. \end{Verbatim}
  125. \end{frame}
  126. \begin{frame}[fragile]
  127. \frametitle{Type classes}
  128. Similar to interfaces or protocols --- define some operations which might
  129. exist on different types, but should behave similarly.\pause{} Like
  130. interfaces, also tend to have additional rules about what they should do which
  131. the compiler cannot check:\pause{}
  132. \bigskip
  133. \begin{Verbatim}[commandchars=\\\{\}]
  134. \color{gray}-- a type class for things which can be compared
  135. class Eq a where
  136. \color{gray}-- instances must have these defined for them
  137. == :: a -> a -> Bool
  138. /= :: a -> a -> Bool\pause{}
  139. instance Eq Int where
  140. == x y = \color{gray}-- fill in whatever
  141. /= x y = \color{gray}-- same here\pause{}
  142. \end{Verbatim}
  143. \end{frame}
  144. \begin{frame}[fragile]
  145. \frametitle{Pure and impure code}
  146. Code is {\em pure\/} if it {\em always\/} returns the same result when given
  147. the same arguments, {\em and\/} has no side effects.\pause{} For example, the
  148. {\tt +} function is pure, but something like {\tt print} or {\tt random} aren't.
  149. \pause{} Code which is not pure is {\em impure\/} (or {\em
  150. side-effecting\/}).\pause{}
  151. \bigskip
  152. Most languages default to {\em everything\/} being as impure as possible ---
  153. any line of code can do anything at all, and it's up to {\em us\/} to make
  154. sure they all behave.\pause{} This is a huge pain:\pause{}
  155. \begin{itemize}
  156. \item We have to keep it straight in our heads\pause{}
  157. \item No telling what an arbitrary function will do\pause{}
  158. \item No guarantees that our impurity is limited in any way!\pause{}
  159. \end{itemize}
  160. This seems rather strange --- why not have {\em pure\/} code be the default,
  161. and then use the type system to {\em state\/} what other behaviour we want to
  162. have?
  163. \end{frame}
  164. \begin{frame}[fragile]
  165. \frametitle{Marking impurity using the type system}
  166. \pause{}
  167. \begin{Verbatim}[commandchars=\\\{\}]
  168. \color{gray}-- unlabelled error (divide by zero)
  169. divide :: Real -> Real -> Maybe Real\pause{}
  170. \color{gray}-- labelled error (lots can go wrong)
  171. parseInt :: String -> Either ParseError Int\pause{}
  172. \color{gray}-- nondeterminism (from zero to two roots)
  173. sqrt :: Real -> [Real]\pause{}
  174. \color{gray}-- or whatever the hell (probably web-based here...)
  175. getMeme :: URL -> MemeType -> IO Meme\pause{}
  176. \color{gray}-- we know these functions' side effects\pause{}
  177. \color{gray}-- and we *didn't even have to read them*!
  178. \end{Verbatim}
  179. \end{frame}
  180. \begin{frame}[fragile]
  181. \frametitle{A problem}
  182. \pause{}
  183. \begin{Verbatim}[commandchars=\\\{\}]
  184. \color{gray}-- suppose we have this eminently-sensible function
  185. square :: Real -> Real
  186. square x = x * x\pause{}
  187. \color{gray}-- we want to do this, but it won't work
  188. lifeTheUniverseAndEverything = square(sqrt(42))\pause{}
  189. \color{gray}-- this is because sqrt gives us a [Real]
  190. \color{gray}-- but square wants a plain Real\pause{}
  191. \end{Verbatim}
  192. \bigskip
  193. It seems all we can do is re-write every single thing to handle every single
  194. condition possible, which is ridiculous and impossible.\pause{} We
  195. \alert{deserve} better from our languages!
  196. \end{frame}
  197. \begin{frame}[fragile, c]
  198. \frametitle{What you're probably thinking now}
  199. \includegraphics[scale=0.125]{img/get-on-with-it.pdf}
  200. \end{frame}
  201. \section{The functor revealed}
  202. \begin{frame}[fragile]
  203. \frametitle{What a functor really is}
  204. \pause{}
  205. \begin{Verbatim}[commandchars=\\\{\}]
  206. class Functor f where
  207. map :: a -> b -> f a -> f b
  208. \end{Verbatim}
  209. \pause{}
  210. \bigskip
  211. Furthermore, we require that the following hold for any functor:\pause{}
  212. \begin{Verbatim}[commandchars=\\\{\}]
  213. \color{gray}--compiler can't check this, sadly, so we must
  214. map id == id
  215. \end{Verbatim}
  216. \pause{}
  217. \bigskip
  218. We call this the {\em functor law}.
  219. \end{frame}
  220. \begin{frame}[fragile]
  221. \frametitle{Wait, what?}
  222. \pause{}
  223. Maybe this will help (it's the same thing really):
  224. \bigskip
  225. \begin{Verbatim}[commandchars=\\\{\}]
  226. class Functor f where
  227. map :: (a -> b) -> (f a -> f b)
  228. \end{Verbatim}
  229. \pause{}
  230. \bigskip
  231. \verb+map+ transforms a pure function into a function with a side effect
  232. described by the type of the functor.\pause{} So as long as our type has a
  233. functor definition, we can use {\em any\/} pure function with it.\pause{}
  234. \bigskip
  235. We can define (correct) functor instances for \verb+Maybe+,\pause{}
  236. \verb+Either+,\pause{} \verb+[]+,\pause{} \verb+(,)+,\pause{}
  237. \verb+IO+,\pause{} most container types,\ldots
  238. \end{frame}
  239. \begin{frame}[fragile]
  240. \frametitle{Solving both our problems}
  241. Because of \verb+map+, our original problems of `type incompatibility' no
  242. longer exist:\pause{}
  243. \bigskip
  244. \begin{Verbatim}[commandchars=\\\{\}]
  245. \color{gray}-- this now works!
  246. lifeTheUniverseAndEverything = map square (sqrt 42)
  247. \color{gray}-- what do you think its type would be?\pause{}
  248. lifeTheUniverseAndEverything :: [Real]
  249. \end{Verbatim}
  250. \pause{}
  251. \bigskip
  252. Furthermore, we can define (correct) functors for {\em all\/} the types which
  253. describe all the effects we mentioned earlier. Now, we can treat them all the
  254. same, just by writing functions against \verb+Functor+ instead.\pause{} What's
  255. more, this requires {\em no special support from the language\/} --- if we can
  256. define the functor, we can do this!
  257. \end{frame}
  258. \begin{frame}[fragile]
  259. \frametitle{An example functor: Maybe}
  260. \pause{}
  261. \begin{Verbatim}[commandchars=\\\{\}]
  262. instance Functor Maybe where\pause{}
  263. map :: (a -> b) -> (Maybe a -> Maybe b)\pause{}
  264. map g Nothing = \pause{}Nothing \color{gray}-- no other choice\pause{}
  265. map g (Just x) = \pause{}Just (g x) \color{gray}-- apply and rewrap\pause{}
  266. \end{Verbatim}
  267. \bigskip
  268. Of course, we now need to check that the functor law is obeyed.\pause{} We can {\em
  269. prove\/} that this is the case (and pretty easily too).
  270. \end{frame}
  271. \begin{frame}[fragile]
  272. \frametitle{Proving the functor law for Maybe}
  273. \begin{lemma}
  274. Our definition of \verb+Maybe+ follows the functor law.
  275. \end{lemma}\pause{}
  276. \bigskip
  277. \begin{proof}
  278. We must show that, for our definition of \verb+Maybe+, we have:
  279. \begin{Verbatim}[commandchars=\\\{\}]
  280. map id == id
  281. \end{Verbatim}
  282. \pause{}
  283. If \verb+Maybe a == Nothing+, we have:\pause{}
  284. \begin{Verbatim}[commandchars=\\\{\}]
  285. map id Nothing == id Nothing\pause{}
  286. => Nothing == Nothing\pause{}
  287. \end{Verbatim}
  288. Otherwise, \verb+Maybe a == Just x+, and we have:\pause{}
  289. \begin{Verbatim}[commandchars=\\\{\}]
  290. map id (Just x) == id (Just x)\pause{}
  291. => Just (id x) == Just x\pause{}
  292. => Just x == Just x\pause{}
  293. \end{Verbatim}
  294. Thus, our definition of \verb+Maybe+ follows the functor law.
  295. \end{proof}
  296. \end{frame}
  297. \section{Limitations of functors}
  298. \begin{frame}[fragile]
  299. \frametitle{What functors {\em can't\/} do}
  300. \pause{}
  301. \begin{itemize}
  302. \item Can't apply functions with side-effect markers. If we want to apply a
  303. \verb+Maybe (Int -> Int)+ to a \verb+Maybe Int+, functors are of no
  304. help.\pause{}
  305. \item `Chaining together' functors stacks markers instead of collapsing
  306. them. If we tried do \verb+map sqrt (sqrt 42)+, we probably want a
  307. \verb+[Real]+, but what we actually get is \verb+[[Real]]+.\pause{}
  308. \end{itemize}
  309. \bigskip
  310. Luckily for us, there are other, more powerful abstractions built on the
  311. functor which solve {\em both\/} of these problems.
  312. \end{frame}
  313. \section{Questions}
  314. \begin{frame}[fragile, c]
  315. \frametitle{Questions?}
  316. \begin{center}
  317. \includegraphics[scale=0.27]{img/questions.pdf}
  318. \end{center}
  319. \end{frame}
  320. \end{document}