{
    "componentChunkName": "component---src-templates-blog-post-tsx",
    "path": "/blog/2018-02-19-math-is-just-another-framework/",
    "result": {"data":{"blogPost":{"title":"Math is Just Another Framework","slug":"/blog/2018-02-19-math-is-just-another-framework/","authorNodes":[{"name":"Charles Lowell","slug":"/people/charles-lowell/"}],"markdown":{"html":"<p>Monads. Amirite?</p>\n<p style=\"clear: both\"/>\n<p style=\"clear:both;\">And Ugh... Monoids? 🙄 please 🙄</p>\n<p>What a bunch of complicated gobbledygook. I mean first off, you have\nto have like, a PhD in mathematics just in order to get started with\ncrap like that, and then if you <em>do</em> decide to put in the work, what's\nthe payoff? Look, I just make webapps here. The only return I'd\never see on that type of investment is maaaayybe the dubious honor of\nhanging out with developer cliques that fetishize abstruse words like\n\"Endofunctor\" and \"Isomorphism.\" They're so exclusive anyway, and\nthat's not what I'm about. I build <em>real</em> things, and so this isn't\nfor me.</p>\n<p>Does any of that sound like an internal dialogue you may have had with\nyourself at some point in the last few years? I know it certainly\ncaptures the color of my thinking on the subject of formal functional\nprogramming during that time. Sure, I took half-hearted swipes at\nunderstanding things like Monads here and there, but it never really\nstuck. And more often than not, I was inclined to chalk it all up to\nsour grapes... That is, of course, until I realized something\namazing. I realized that contrary to what I was brought up to believe,\nformal FP wasn't something that would forever lie just beyond my\nreach.</p>\n<p>Imagine my surprise in realizing that not only was this <em>not</em> true, but in\nrealizing that I had actually been an FP super hero all along;\ndescended from a long line of FP super heroes. And do you know what\nthe most amazing thing is? Whether you know it or not, you are\ntoo. Don't believe me? Just listen.</p>\n<h3 id=\"it-all-began-with-a-functor\" style=\"position:relative;\"><a href=\"#it-all-began-with-a-functor\" aria-label=\"it all began with a functor permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>It all began with a Functor</h3>\n<p>A Functor? Are you kidding me?</p>\n<p>I know, I know. Even now just saying it still makes me want to\ngiggle. But if you're still doubting your own powers, then Functor\nis where the journey begins. That's where it began for me. Because you\nknow what? If you code for a living, then odds are you use Functors\nevery coding minute of every coding day. You just haven't realized it\nyet.</p>\n<p>So Functor is the name, and the concept it references is\n\"mapping over a structure\". There's nothing more to it than that. Functors are things\nthat can be mapped. End of story. <a href=\"http://127.0.0.1:59477/Dash/wbiryrnu/developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Array/map.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Arrays can be mapped</a>: Arrays\nare Functors. <a href=\"http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Observables can be mapped</a>: Obvservables are\nFunctors. So guess what? Like it or not, if you are comfortable mapping Arrays,\nthen you are <em>also</em> comfortable working with Functors.</p>\n<p>Mapping an Array always returns an Array of the same length, but with\ndifferent values at every index. Mapping an Observable always\nreturns an Observable with the exact same sequence and timing of\nstates, but with different values inhabiting each state. The general\npattern is that mapping doesn't change the object's structure.</p>\n<p>At its core, an Array is nothing but a sequence of indexed placeholders\nthat contain values. <em>That</em> is its structure, and that's exactly what\ndoesn't change when you map it. The structure of observables is the timing\nand sequence of states coming through a stream, so it's the same\ntiming sequence that remains intact when you map it. So no matter the\nFunctor, when you map it, it returns a new Functor with the exact same\nstructure. In other words:  <code class=\"language-text\">S -> S</code>.</p>\n<p>But you knew already that mapping an Array of the same length always\nreturns an Array of the same length because you've been working with\nthem for as long as you've been writing code.</p>\n<h3 id=\"crouching-promise-hidden-functor\" style=\"position:relative;\"><a href=\"#crouching-promise-hidden-functor\" aria-label=\"crouching promise hidden functor permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Crouching Promise, Hidden Functor.</h3>\n<blockquote>\n<p>So yeah. I know how to map Arrays. Big deal. How does assigning some\nnew name to what I'm already doing actually help me in any\ntangible way? It seems an awful lot like some boring thing to\nremember.</p>\n</blockquote>\n<p>Well, this is where the plot takes an unexpected turn. This is the part\nin the story where a chance encounter with a secret Functor plants the\nsuspicion that perhaps you've been lied to your entire life by the\nones that raised you. Sure, they meant well, and all they ever really\nwanted to do was to save you sweat and tears, but in the end the only\nthing they actually accomplished was to delay your inevitable\nconfrontation with destiny.</p>\n<p>Here's your first clue: Have you used and/or thought about Promises\nlately?</p>\n<p>Promises don't have a <code class=\"language-text\">map</code> method, and yet they are nevertheless\nFunctors. They're the functoriest of Functors that ever were, and\ntheir functorality is as constant and sure as the sun rising in the\neast and setting in the west. But how can this be if there isn't any\nway to map them? The answer is of course that you <em>can</em> map them. You\njust have to use the <code class=\"language-text\">then</code> method to do it. It's this alternatively\nnamed mapping function that makes Promise a secret Functor.</p>\n<p>It makes sense when you think about how <code class=\"language-text\">then</code> works. You start with a\nPromise of some value that will resolve at some later time, and you\nend up with another Promise that has the exact same structure as the\noriginal in that it will <em>also</em> resolve at the exact same time as the\nfirst. The only difference is that the value has been transformed by\nthe passed in function. Once you come to recognize it, you see that\nit's a clear stamp out of the Functor pattern, and that the method\nmight as well have been called <code class=\"language-text\">map</code> instead of <code class=\"language-text\">then</code>.</p>\n<p>And that's when you begin to wonder \"what if it <em>had</em> been named <code class=\"language-text\">map</code>\ninstead of <code class=\"language-text\">then</code>, and explicitly identified as a Functor from the\nget-go?\" Learning to work with Promises was tricky enough, but what if\nyou'd been able to leverage the fact that the greater part of working\nwith them was <em>strongly analogous</em> to working with Arrays? What if\nyou'd been able to apply everything you knew about mapping Arrays and\nbring it to bear on Promises? How much time and mental exhaustion\nwould it have saved? Looking back at my own experience, it would have\nbeen extraordinarily helpful to have sidestepped the process of trial\nand error that happened as my brain settled around the semantics of\nPromise.</p>\n<p>Here's the rub. The method name <code class=\"language-text\">then</code> is a reference to the timing of\nPromise resolution, which of course seems reasonable at first. After\nall, it's a good thing for an API to be concrete and descriptive\nright? The hidden tradeoff is that the name <code class=\"language-text\">then</code> orients the\nAPI around what makes Promise unique, instead of what makes Promise\n<em>literally like every other Functor</em>. And there are thousands of\nthem.</p>\n<p>They inhabit so many of the programming structures that\nyou use every single day, that once you're aware of them, they will\nbegin to reveal themselves to you. As you start to perceive the common\nnature in things like Promise, Array, and Observable, you begin to\nre-perceive <em>all</em> of the objects in your world through this new prism. You ask\nyourself \"Is this a Functor?\" and you're shocked by how often\nthe answer is yes. Plain JS Object? Yes. DOM Element? Yes. Express\nmiddleware? Yes. React Component? Also yes.</p>\n<p>And then it hits you.</p>\n<h3 id=\"math-is-just-another-framework\" style=\"position:relative;\"><a href=\"#math-is-just-another-framework\" aria-label=\"math is just another framework permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Math is Just Another Framework</h3>\n<p>If you're using Ruby on Rails, and someone tells you about a\n<code class=\"language-text\">Controller</code>, it doesn't matter if it's a controller for products, or\nusers, or blog posts. The mere fact that it's a <code class=\"language-text\">Controller</code> gives you\nmost of what you need to know about its role and how you can set to\nwork with it to build the larger application. By the same token, if\nsomeone tells you that some object is a Functor, it doesn't matter if\nit's a list, or a tree, or a stream. The mere fact that it's a Functor\ngives you most of what you need to know about its role and how you can\nset to work with it to compose it into larger structures.</p>\n<p>I use Ruby on Rails as an example to illustrate this point because the\nframework is synonymous with the concept of <a href=\"http://rubyonrails.org/doctrine/#convention-over-configuration\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">convention over\nconfiguration</a>, and that's the fundamental dynamic at play here. But\nwhereas Ruby on Rails is a framework for web applications, formal FP\ngrounded in Category Theory is a framework for composable APIs.</p>\n<p>Like learning any new framework it's an investment. There are patterns\nto internalize and there is abitrary jargon to become acquainted with, but\ndon't be intimidated. Every framework has its concepts that\nseem opaque at first, but you can learn them all one piece at a\ntime. And once you're familiar with them, the big return is that you\ncan quickly use typeclasses like Functor to build APIs that compose\nwell with each other out-of-the-box at zero extra cost. And the best\npart is that it's a framework that's 100% portable across\nruntimes. Whether you're using JavaScript, Ruby or Python it \"just\nworks\" every time.</p>\n<p>If you do happen, however, to be working in JavaScript, you're in\nluck. I wrote a library just for you called <a href=\"https://github.com/cowboyd/funcadelic.js\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">funcadelic.js</a> that\nbrings the magic of typeclasses into the reality of everyday JavaScript\ndevelopment.</p>\n<p>Because Functor is just the beginning. Like a programmer\nlearning Ruby on Rails can start with <code class=\"language-text\">Controller</code> first, and then\nmove on to <code class=\"language-text\">Router</code>, <code class=\"language-text\">Model</code>, and <code class=\"language-text\">Middleware</code>, so you can you move on\nfrom Functor (at your very own pace) to using Applicatives, Monads, and\nMonoids.</p>\n<p>So go for it! I remember the first time I took a tree class I'd been\nworking with and started thinking of it as a Functor. All of a sudden,\nthe brain-hurty, recursive aspects of the tree were abstracted into\nthe map method and I was able to relate entire trees to each other\nwith nothing more than a simple function. I cannot describe the feeling other than\nit felt like flying. The ground below was all very familiar because I'd\nwalked it back and forth many times over the years. The only\ndifference was that now I had the perspective of ten thousand feet and\nthe airspeed of a jetliner.</p>\n<p>You know the ground too. You walk it every day, and if you're willing\nto learn the math framework, the same feeling is waiting for you.</p>\n<hr/>\n<p>I’m Charles Lowell, and I build UI for a living at <a href=\"https://frontside.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Frontside</a>. If\nyou enjoyed this post, I’d love to hear from you. You can give me a\nshout on Twitter where I'm <a href=\"https://twitter.com/cowboyd\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@cowboyd</a>, or drop me a line at\n<a href=\"mailto:cowboyd@frontside.com\">cowboyd@frontside.com</a></p>","frontmatter":{"date":"February 19, 2018","description":"Functional programming with typeclasses rooted in category theory may seem like some esoteric practice reserved for the truly pointy-haired. But guess what? You do it every day.","tags":["javascript","functional programming","typeclasses","convention over configuration"],"img":{"childImageSharp":{"fixed":{"src":"/static/c144534e4c0964a999b59b2abc61db23/a7715/2018-02-19-math-is-just-another-framework_graphs.jpg"}}}}}}},"pageContext":{"id":"2603d5dc-dd4e-5028-892a-c9fc235462f2"}},
    "staticQueryHashes": ["1241260443"]}