├── java ├── verification-roadmap.png ├── verification-roadmap.graffle ├── .gitignore ├── package.yaml ├── Makefile ├── Main.hs ├── support.el ├── default.nix └── denotational-design.org /java: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec /run/current-system/sw/bin/java -Djava.awt.headless=true "$@" -------------------------------------------------------------------------------- /verification-roadmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwiegley/thinking-with-functions/HEAD/verification-roadmap.png -------------------------------------------------------------------------------- /verification-roadmap.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwiegley/thinking-with-functions/HEAD/verification-roadmap.graffle -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.cabal 2 | *.log 3 | *.nav 4 | *.out 5 | *.pdf 6 | *.snm 7 | *.svg 8 | *.tex 9 | *.toc 10 | *.upa 11 | *.vrb 12 | /.diagrams_cache/ 13 | /_minted-denotational-design/ 14 | /auto/ 15 | /dist/ 16 | /svg-inkscape/ 17 | /result 18 | -------------------------------------------------------------------------------- /package.yaml: -------------------------------------------------------------------------------- 1 | name: org-support-code 2 | version: 0.1.0 3 | synopsis: Helper code to be using with org-beamer 4 | github: jwiegley/denotational-design 5 | license: MIT 6 | author: John Wiegley 7 | maintainer: johnw@newartisans.com 8 | category: Development 9 | 10 | dependencies: 11 | - base >= 4.9.1.0 12 | - bytestring >= 0.10.8.1 13 | - containers >= 0.5.7.1 14 | - hspec >= 2.4.3 15 | - lens >= 4.15.1 16 | - lens-aeson >= 1.0.0.5 17 | - mtl >= 2.2.1 18 | - text >= 1.2.2.1 19 | - thyme >= 0.3.5.5 20 | - unordered-containers >= 0.2.8.0 21 | 22 | tests: 23 | org-support-code-tests: 24 | main: Main.hs 25 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 26 | 27 | executables: 28 | org-support-code: 29 | main: Main.hs 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME = denotational-design 2 | PYTHON = /usr/bin/python 3 | PRESENT = /Applications/Misc/Présentation.app/Contents/MacOS/presentation.py 4 | PDF = $(NAME).pdf 5 | EMACS = emacs 6 | 7 | all: $(PDF) 8 | 9 | open: $(PDF) 10 | open $< 11 | 12 | present: all 13 | $(PYTHON) $(PRESENT) $(PDF) 14 | 15 | # Ensure all examples work before building the slide deck 16 | %.tex: %.org Makefile 17 | $(EMACS) --debug-init -batch $(EMACS_ARGS) -L . -l support -f perform-extraction $< 18 | 19 | %.pdf: %.tex 20 | xelatex -8bit -shell-escape -interaction nonstopmode $< 21 | xelatex -8bit -shell-escape -interaction nonstopmode $< 22 | xelatex -8bit -shell-escape -interaction nonstopmode $< 23 | 24 | clean: 25 | rm -fr html 26 | rm -f *.tex *.pdf *.vrb *.aux *.log *.nav *.out *.snm *.toc *.upa 27 | rm -f src/*.d src/*.vo src/*.glob 28 | rm -fr _minted-* auto diagram*.svg svg-inkscape *.cabal dist 29 | 30 | watch: 31 | fswatch --batch-marker --latency 2 -m poll_monitor \ 32 | *.hs *.el *.org *.yaml Makefile \ 33 | | while read event; do \ 34 | [[ $$event == NoOp ]] && PATH=$(PWD):$(PATH) make; \ 35 | done 36 | -------------------------------------------------------------------------------- /Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE MultiWayIf #-} 2 | 3 | {-# OPTIONS_GHC -Wno-type-defaults #-} 4 | {-# OPTIONS_GHC -Wno-unused-imports #-} 5 | {-# OPTIONS_GHC -Wno-unused-top-binds #-} 6 | 7 | module Main (main) where 8 | 9 | import Control.Exception 10 | import Control.Lens 11 | import Control.Monad.State 12 | import Data.Char 13 | import Data.Data 14 | import Data.Data.Lens 15 | import Data.Function 16 | import Data.List 17 | import Data.Maybe (isJust) 18 | import Data.Map (Map) 19 | import qualified Data.Map as M 20 | import Data.Monoid 21 | import Data.Set (Set) 22 | import qualified Data.Set as S 23 | import Numeric.Natural 24 | import Test.Hspec 25 | 26 | {------------------------------------------------------------------------} 27 | 28 | infixr 0 ==> 29 | (==>) :: (HasCallStack, Show a, Eq a) => a -> a -> Expectation 30 | (==>) = shouldBe 31 | 32 | infixr 0 /=> 33 | (/=>) :: (HasCallStack, Show a, Eq a) => a -> a -> Expectation 34 | (/=>) = shouldNotBe 35 | 36 | infixr 0 !!> 37 | (!!>) :: (HasCallStack, Exception e) => a -> Selector e -> Expectation 38 | v !!> s = pure v `shouldThrow` s 39 | 40 | main :: IO () 41 | main = hspec $ parallel $ 42 | describe "Part" $ 43 | describe "Chapter" $ 44 | describe "Section" $ 45 | it "Test" $ 46 | True 47 | ==> True 48 | 49 | -- Local Variables: 50 | -- haskell-indent-spaces: 2 51 | -- haskell-indentation-ifte-offset: 2 52 | -- haskell-indentation-layout-offset: 2 53 | -- haskell-indentation-left-offset: 2 54 | -- haskell-indentation-starter-offset: 2 55 | -- haskell-indentation-where-post-offset: 2 56 | -- haskell-indentation-where-pre-offset: 2 57 | -- End: 58 | -------------------------------------------------------------------------------- /support.el: -------------------------------------------------------------------------------- 1 | (setq org-latex-default-packages-alist 2 | '(;; ("T1" "fontenc" t) 3 | ("" "fontspec" nil) 4 | ("" "xunicode" nil) 5 | ("" "graphicx" t) 6 | ("" "longtable" nil) 7 | ("" "float" nil) 8 | ("" "wrapfig" nil) 9 | ("" "rotating" nil) 10 | ("normalem" "ulem" t) 11 | ("" "amsmath" t) 12 | ("" "textcomp" t) 13 | ("" "marvosym" t) 14 | ("" "wasysym" t) 15 | ("" "amssymb" t) 16 | ("" "hyperref" nil) 17 | "\\tolerance=1000")) 18 | 19 | (require 'rx) 20 | (require 'ox-latex) 21 | (require 'ox-beamer) 22 | (require 'haskell-mode) 23 | (require 'haskell-customize) 24 | 25 | (setq org-plantuml-jar-path "/run/current-system/sw/lib/plantuml.jar") 26 | (setq org-ditaa-jar-path "/run/current-system/sw/lib/ditaa.jar") 27 | 28 | (org-babel-do-load-languages 29 | 'org-babel-load-languages 30 | '((python . t) 31 | (emacs-lisp . t) 32 | (haskell . t) 33 | (calc . t) 34 | (coq . t) 35 | (ledger . t) 36 | (ditaa . t) 37 | (plantuml . t) 38 | (sh . t) 39 | (dot . t))) 40 | 41 | (setq org-beamer-frame-default-options "fragile") 42 | 43 | (setq org-confirm-babel-evaluate nil) 44 | (setq org-export-babel-evaluate t) 45 | 46 | (setq org-latex-listings 'minted) 47 | 48 | (setq org-latex-minted-options 49 | '(("fontsize" "\\footnotesize") 50 | ("linenos" "false") 51 | ("xleftmargin" "0em"))) 52 | 53 | (setq org-export-latex-minted-options 54 | '(("fontsize" "\\small") 55 | ("linenos" "true"))) 56 | 57 | (setq org-latex-pdf-process 58 | '("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" 59 | "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" 60 | "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f")) 61 | 62 | (setq org-export-latex-classes 63 | '(("beamer" "\\documentclass{beamer}" org-beamer-sectioning))) 64 | 65 | (defun extract-code (name) 66 | "Where name has the form foo.bar.baz" 67 | (with-temp-buffer 68 | (insert-file-contents-literally "Main.hs") 69 | 70 | (let ((parts (split-string name "\\."))) 71 | (while parts 72 | (re-search-forward 73 | (rx-to-string `(: word-start ,(if (cdr parts) "describe" "it") 74 | space ?\" ,(car parts) ?\"))) 75 | (forward-line) 76 | (setq parts (cdr parts)))) 77 | 78 | (let ((beg (point))) 79 | (forward-paragraph) 80 | (let ((str (buffer-substring-no-properties beg (point)))) 81 | (with-temp-buffer 82 | (insert str) 83 | (goto-char (point-min)) 84 | (let ((width (skip-chars-forward " "))) 85 | (goto-char (point-min)) 86 | (while (not (eobp)) 87 | (delete-char width) 88 | (forward-line))) 89 | (buffer-string)))))) 90 | 91 | (defun extract-code-blocks () 92 | (goto-char (point-min)) 93 | (while (re-search-forward "^### \\(.+\\)$" nil t) 94 | (let ((name (match-string 1)) 95 | (line (line-number-at-pos (match-end 0)))) 96 | (delete-region (match-beginning 0) (match-end 0)) 97 | (insert "#+begin_src haskell" ?\n) 98 | (condition-case err 99 | (insert (extract-code name)) 100 | (error 101 | (error "Failed to locate test for %s: %s" name err))) 102 | (insert "#+end_src")))) 103 | 104 | (defun perform-extraction () 105 | (find-file (car command-line-args-left)) 106 | (extract-code-blocks) 107 | (org-beamer-export-to-latex)) 108 | 109 | (provide 'support) 110 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { rev ? "4477cf04b6779a537cdb5f0bd3dd30e75aeb4a3b" 2 | , sha256 ? "1i39wsfwkvj9yryj8di3jibpdg3b3j86ych7s9rb6z79k08yaaxc" 3 | , pkgs ? import (builtins.fetchTarball { 4 | url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; 5 | inherit sha256; }) { 6 | config.allowUnfree = true; 7 | config.allowBroken = false; 8 | } 9 | }: 10 | 11 | let 12 | org = pkgs.stdenv.mkDerivation rec { 13 | name = "emacs-org-${version}"; 14 | version = "20160421"; 15 | src = pkgs.fetchFromGitHub { 16 | owner = "jwiegley"; 17 | repo = "org-mode"; 18 | rev = "db5257389231bd49e92e2bc66713ac71b0435eec"; 19 | sha256 = "073cmwgxga14r4ykbgp8w0gjp1wqajmlk6qv9qfnrafgpxic366m"; 20 | }; 21 | preBuild = '' 22 | rm -f contrib/lisp/org-jira.el 23 | makeFlagsArray=( 24 | prefix="$out/share" 25 | ORG_ADD_CONTRIB="org* ox*" 26 | ); 27 | ''; 28 | preInstall = '' 29 | perl -i -pe "s%/usr/share%$out%;" local.mk 30 | ''; 31 | buildInputs = [ pkgs.emacs26 ] ++ (with pkgs; [ texinfo perl which ]); 32 | meta = { 33 | homepage = "https://elpa.gnu.org/packages/org.html"; 34 | license = pkgs.lib.licenses.free; 35 | }; 36 | }; 37 | 38 | texFull = pkgs.texlive.combine { 39 | inherit (pkgs.texlive) scheme-full texdoc latex2e-help-texinfo; 40 | pkgFilter = pkg: 41 | pkg.tlType == "run" 42 | || pkg.tlType == "bin" 43 | || pkg.pname == "latex2e-help-texinfo"; 44 | }; 45 | 46 | ignoredDirs = [ 47 | "html" "_minted-denotational-design" 48 | "auto" "dist" "svg-inkscape" 49 | ]; 50 | 51 | ignoredSuffixes = [ 52 | ".aux" ".cabal" ".log" ".nav" ".out" ".pdf" ".snm" ".svg" 53 | ".tex" ".toc" ".upa" ".vrb" 54 | ]; 55 | in rec { 56 | org-support-code = 57 | pkgs.haskellPackages.callCabal2nix "org-support-code" 58 | (with pkgs.lib; cleanSourceWith { 59 | src = ./.; 60 | filter = path: type: 61 | let baseName = baseNameOf path; in 62 | builtins.elem baseName [ 63 | "Main.hs" 64 | "package.yaml" 65 | ]; 66 | }) {}; 67 | 68 | denotational-design = pkgs.stdenv.mkDerivation rec { 69 | name = "denotational-design"; 70 | version = "1.0"; 71 | 72 | src = 73 | if pkgs.lib.inNixShell 74 | then null 75 | else filterSource ./.; 76 | 77 | buildInputs = [ 78 | org-support-code 79 | org 80 | texFull 81 | pkgs.fontconfig 82 | pkgs.liberation_ttf 83 | pkgs.bash 84 | pkgs.jdk8 85 | pkgs.plantuml 86 | pkgs.ditaa 87 | pkgs.emacs26 88 | pkgs.python27Packages.pygments 89 | pkgs.inkscape.out 90 | pkgs.which 91 | ]; 92 | 93 | patchPhase = '' 94 | substituteInPlace java \ 95 | --replace "/run/current-system/sw/bin/java" \ 96 | "${pkgs.jdk8}/bin/java" 97 | substituteInPlace java \ 98 | --replace "/bin/bash" \ 99 | "${pkgs.bash}/bin/bash" 100 | substituteInPlace support.el \ 101 | --replace "/run/current-system/sw/lib/plantuml.jar" \ 102 | "${pkgs.plantuml}/lib/plantuml.jar" 103 | substituteInPlace support.el \ 104 | --replace "/run/current-system/sw/lib/ditaa.jar" \ 105 | "${pkgs.ditaa}/lib/ditaa.jar" 106 | ''; 107 | 108 | preConfigure = '' 109 | export HOME=$NIX_BUILD_TOP 110 | 111 | mkdir chroot-fontconfig 112 | cat ${pkgs.fontconfig.out}/etc/fonts/fonts.conf > chroot-fontconfig/fonts.conf 113 | sed -e 's@@@' -i chroot-fontconfig/fonts.conf 114 | echo "${pkgs.liberation_ttf}" >> chroot-fontconfig/fonts.conf 115 | echo "" >> chroot-fontconfig/fonts.conf 116 | 117 | export FONTCONFIG_FILE=$(pwd)/chroot-fontconfig/fonts.conf 118 | ''; 119 | 120 | buildPhase = with pkgs.emacs26PackagesNg; '' 121 | export PATH=$PATH:${pkgs.python27Packages.pygments}/bin 122 | make EMACS_ARGS="-L ${org}/share/emacs/site-lisp/org \ 123 | -L ${haskell-mode}/share/emacs/site-lisp/elpa/$(echo ${haskell-mode.name} | sed 's/^emacs-//')" 124 | ''; 125 | installPhase = '' 126 | mkdir -p $out/share/pdf 127 | cp -p denotational-design.pdf $out/share/pdf 128 | ''; 129 | 130 | env = pkgs.buildEnv { name = name; paths = buildInputs; }; 131 | }; 132 | }.denotational-design 133 | -------------------------------------------------------------------------------- /denotational-design.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Denotational Design \\ (or: \emph{Thinking with functions}) 2 | #+AUTHOR: John Wiegley and Conal Elliott 3 | #+EMAIL: johnw@newartisans.com 4 | #+DATE: 2018-09-10 5 | 6 | #+DESCRIPTION: 7 | #+KEYWORDS: 8 | #+LANGUAGE: en 9 | 10 | \setbeamertemplate{footline}{} 11 | \setbeamerfont{block body}{size=\small} 12 | \definecolor{orchid}{RGB}{134, 134, 220} 13 | \definecolor{lightorchid}{RGB}{243, 243, 251} 14 | \setbeamercolor{block title}{fg=white,bg=orchid} 15 | \setbeamercolor{bgcolor}{fg=white,bg=blue} 16 | 17 | * Specification 18 | 19 | ** Roadmap 20 | [[file:verification-roadmap.png]] 21 | ** Denotation 22 | 23 | - Choose the simplest mathematical object that captures your intention. 24 | 25 | - Often a function or relation, though not necessarily. 26 | 27 | ** What is a Bank? 28 | *** A functional view 29 | #+begin_src coq 30 | Definition Transaction := PublicKey -> Sum Z. 31 | Definition Bank := PublicKey -> Sum N. 32 | #+end_src 33 | 34 | ** Define an algebra over that denotation 35 | 36 | #+begin_src coq 37 | Definition query (who : PublicKey) (b : Bank) : Sum N := 38 | b who. 39 | 40 | Definition exchange (f t : PublicKey) (amount : N) : 41 | Transaction a := 42 | fun owner => 43 | mkSum ( 44 | if eqPublicKey f t 45 | then mempty 46 | else if eqPublicKey f owner 47 | then mkSum (0 - NtoZ amount) 48 | else if eqPublicKey t owner 49 | then amount 50 | else mempty). 51 | #+end_src 52 | 53 | ** Determine the laws of this algebra 54 | 55 | #+begin_src coq 56 | Definition query_self_exchange := 57 | forall o n b, query o (exchange o o n) b = query o b. 58 | 59 | Definition query_exchange_all := 60 | forall o n b, query f (exchange f t (query f b)) b = 0. 61 | #+end_src 62 | 63 | ** Relating Transactions to Bank 64 | 65 | #+begin_src coq 66 | Definition ValidTransaction 67 | `(t : Transaction) (b : Bank) : Prop := 68 | forall h : PublicKey, 69 | let '(mkSum b') := b h in 70 | let '(mkSum t') := t h in 71 | 0 <= NtoZ b' + t'. 72 | 73 | Program Definition applyTransaction 74 | `(t : Transaction) (b : Bank) : 75 | ValidTransaction t b -> Bank := 76 | fun H => mappend (fmap (fmap (ZtoN _)) t) b. 77 | #+end_src 78 | 79 | ** Taking an ideal view 80 | 81 | - The domain of the denotation has no "storage" or other limits; e.g., it is 82 | infinite and may even be continuous. There are no objects to be considered, 83 | only functional relationships. Even thinking about ideas such as State or 84 | sequencing at this stage is typically unwarranted. 85 | 86 | - For example, since the "state" of the blockchain network is a product of all 87 | past actions, it need not be considered in the denotation. 88 | 89 | \vfill 90 | 91 | #+begin_quote 92 | "A mathematician, like a painter or a poet, is a maker of patterns. If his 93 | patterns are more permanent than theirs, it is because they are made with 94 | ideas."---G. H. Hardy 95 | #+end_quote 96 | 97 | ** Multiparty exchange 98 | 99 | Considering only the specification so far, the meaning of multi- party 100 | transactions is natural: 101 | 102 | \vfill 103 | 104 | \[ applyTransaction\ (t1 \otimes t2 \otimes t3 \otimes t4)\ b\ \_ \] 105 | 106 | \vfill 107 | 108 | *** Note 109 | :PROPERTIES: 110 | :BEAMER_act: <2-> 111 | :END: 112 | 113 | Individual transactions could be invalid while the aggregate remains valid. 114 | 115 | ** Where does this algebra come from? 116 | 117 | - Finding the denotation and its unique vocabulary is creative work! 118 | 119 | - Many denotations will support well known algebras: functors, monads, 120 | monoids, categories, etc. 121 | 122 | - For example, the =Bank= denotation forms a monoid, so we might expect its 123 | denotation to be a monoid homomorphism: 124 | \[ denote\ mempty = mempty \] 125 | \[ denote\ (x \otimes y) = denote\ x \otimes denote\ y \] 126 | 127 | ** Generalizing further 128 | 129 | - Once you have a denotation and an set of algebras, can they be generalized 130 | further? For example, is our bank really about coins, or just ownership in 131 | general? 132 | 133 | \vspace{0.5ex} 134 | #+begin_src coq 135 | Definition Bank (a : Type) := PublicKey -> a. 136 | #+end_src 137 | 138 | - This is now a monoid only if =a= is a monoid, but it becomes: a representable 139 | functor, an applicative, and a monad. The denotation must be a homomorphism 140 | for each algebra of significance, guiding its development. 141 | 142 | - We generalize to optimize for simplicity in the specification, and also to 143 | reveal and eliminate unnecessary limitations. 144 | 145 | \vspace{0.5ex} 146 | #+begin_src coq 147 | Definition exchange `{Eq k} `{Group v} 148 | (f t : k) (amount : v) : 149 | Transaction k v := ... 150 | #+end_src 151 | 152 | ** Over-specialization 153 | 154 | - The opposite of not generalizing enough. 155 | 156 | - For example, familiarity with monads may lend us to reach for =State= whenever 157 | it seems like a thing is being "updated" 158 | 159 | - It would be odd if addition were specified as: 160 | #+begin_src haskell 161 | (+) :: Int -> State Int () 162 | #+end_src 163 | 164 | - Monadic notation also makes it inconvenient not to single-thread things. 165 | Like imperative programming, it encourages unnecessary and unhelpful 166 | sequentiality in specification and implementation. 167 | 168 | * Representation 169 | 170 | ** Choosing a representation 171 | 172 | - With a specification in hand, we need a construction that represents a more 173 | computable form. 174 | 175 | - Where denotations optimize for reasoning (simplicity and rigor), 176 | representations optimize for operational considerations such as efficient 177 | computability. 178 | 179 | - It may still be a function, or relation, only refining the specification; or 180 | it may be something concrete, such as a data structure. 181 | 182 | ** Example: TransactionR 183 | 184 | #+begin_src coq 185 | Inductive TransactionR := 186 | | Exchange (from to : PublicKey) (amount : nat). 187 | #+end_src 188 | 189 | ** Some things to note 190 | 191 | - While the specification allows for multi-party and atomic transactions, this 192 | representation does not. 193 | 194 | - =TransactionR= is not a monoid; perhaps a list of =TransactionR= better 195 | represents what we meant? 196 | 197 | - A list representation, however, would suggest sequential transactions, which 198 | the spec does not. 199 | 200 | - It is easy to start with =TransactionR=---avoiding the exercise of working out 201 | =Transaction=---and miss such discrepancies. 202 | 203 | ** Example: BankR 204 | 205 | #+begin_src coq 206 | Definition BankR := list (PublicKey * nat). 207 | #+end_src 208 | 209 | * Implementation 210 | 211 | ** Denoting function 212 | 213 | The denotating function relates the representation to specification. 214 | 215 | ** Denoting function 216 | 217 | #+begin_src coq 218 | Definition transactionD (t : TransactionR) : 219 | Transaction := 220 | fun holder => 221 | match t with 222 | | Exchange from to amount =>< 223 | if eqPublicKey holder to 224 | then mkSum amount 225 | else if eqPublicKey holder from 226 | then mkSum (0 - amount) 227 | else mkSum 0%nat 228 | end. 229 | #+end_src 230 | 231 | ** Denoting function 232 | 233 | #+begin_src coq 234 | Program Fixpoint bankD (t : BankR) : Bank := 235 | fun holder => 236 | match t with 237 | | nil => mkSum 0%nat 238 | | (h, amount) :: xs => 239 | if eqPublicKey holder h 240 | then mkSum amount 241 | else bankD xs holder 242 | end. 243 | #+end_src 244 | 245 | ** Proving homomorphisms 246 | 247 | It must be a homomorphism, for example over the =exchange= function: 248 | 249 | #+begin_src coq 250 | Theorem TransactionR_exchange : forall f t amount, 251 | transactionD (Exchange f t amount) 252 | = exchange f t amount. 253 | Proof. 254 | unfold transactionD, exchange; intros. 255 | extensionality i. 256 | now repeat destruct (eqPublicKey _ _) in |- *. 257 | Qed. 258 | #+end_src 259 | 260 | ** Working backward 261 | 262 | - Although we can choose a representation and then prove the homomorphism 263 | equations, alternatively we could say that API design is about tasteful 264 | formulation of algebra problems, and implementation is the solving of those 265 | problems for some representation. 266 | 267 | #+begin_src coq 268 | exists x, transactionD x = exchange f t amount 269 | #+end_src 270 | 271 | - The advantage being that often, as there are many choices to be made with 272 | different trade-offs, doing the proof makes these choices apparent. 273 | 274 | * Conclusion 275 | 276 | ** Conclusion 277 | 278 | The basic idea reduces to a few steps: 279 | 280 | 1. Think of mathematical objects that model your interest. 281 | 2. Discover algebraic abstractions (monoid, group, functor, etc) your model 282 | already belongs to. 283 | 3. Determine a vocabulary to express what you want to do; known algebras 284 | take advantage of centuries of prior thought, so look for forms that rely 285 | on these. 286 | 4. Find a representation that encodes the desired capabilities. 287 | 5. Define a function from representation to denotation. 288 | 6. Prove that this function is homomorphic over all algebras. 289 | 290 | [[https://github.com/conal/talk-2014-lambdajam-denotational-design]] 291 | 292 | * Colophon 293 | 294 | #+STARTUP: beamer 295 | #+STARTUP: content fninline hidestars 296 | 297 | #+OPTIONS: H:2 298 | 299 | #+SELECT_TAGS: export 300 | #+EXCLUDE_TAGS: noexport 301 | 302 | #+COLUMNS: %20ITEM %13BEAMER_env(Env) %6BEAMER_envargs(Args) %4BEAMER_col(Col) %7BEAMER_extra(Extra) 303 | 304 | #+LaTeX_CLASS: beamer 305 | #+LaTeX_CLASS_OPTIONS: [utf8x,notes,c] 306 | 307 | #+LATEX_HEADER_EXTRA: \usepackage{fontspec} 308 | #+LATEX_HEADER_EXTRA: \usepackage{svg} 309 | #+LATEX_HEADER_EXTRA: \usepackage{export} 310 | #+LATEX_HEADER_EXTRA: \usepackage{underscore} 311 | #+LATEX_HEADER_EXTRA: \usepackage{pdfcomment} 312 | #+LATEX_HEADER_EXTRA: \usepackage{unicode-math} 313 | #+LATEX_HEADER_EXTRA: \usepackage{minted} 314 | #+LATEX_HEADER_EXTRA: \usepackage{tikz} 315 | #+LATEX_HEADER_EXTRA: \usepackage{tikz-cd} 316 | #+LATEX_HEADER_EXTRA: \setmainfont{Liberation Serif} 317 | #+LATEX_HEADER_EXTRA: \setsansfont{Liberation Sans} 318 | #+LATEX_HEADER_EXTRA: \setmonofont[SmallCapsFont={Liberation Mono}]{Liberation Mono} 319 | 320 | #+BEAMER_THEME: [height=16mm] Rochester 321 | #+BEAMER_COLOR: seahorse 322 | 323 | #+BEAMER_HEADER: \setbeamertemplate{navigation symbols}{} 324 | #+BEAMER_HEADER: \renewcommand{\note}[1]{\marginnote{\pdfcomment[icon=Note]{#1}}} 325 | #+BEAMER_HEADER: \tikzcdset{/tikz/commutative diagrams/background color=lightorchid} 326 | #+BEAMER_HEADER: \newcommand{\head}[1]{\begin{center} 327 | #+BEAMER_HEADER: \vspace{13mm}\hspace{-1mm}\Huge{{#1}} 328 | #+BEAMER_HEADER: \end{center}} 329 | --------------------------------------------------------------------------------