{"id":6582,"date":"2019-12-19T19:00:33","date_gmt":"2019-12-19T19:00:33","guid":{"rendered":"https:\/\/cheesecakelabs.com\/blog\/?p=6582\/"},"modified":"2022-07-01T17:09:28","modified_gmt":"2022-07-01T17:09:28","slug":"functional-programming-game-js","status":"publish","type":"post","link":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/","title":{"rendered":"Using functional programming to create a game in JS"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">There has been a lot of hype around the functional programming paradigm for some time and there are a lot of great books and articles about it on the internet, but it&#8217;s not so easy to find real examples with its application. So have I decided to create a game trying to follow its concepts using Javascript, <\/span><a href=\"https:\/\/insights.stackoverflow.com\/survey\/2019#technology\"><span style=\"font-weight: 400;\">which is the most popular programming language today<\/span><\/a><span style=\"font-weight: 400;\">. In this post, I will share some of this experience and tell you if it was worth it.<\/span><\/p>\n<p><!--more--><\/p>\n<h2><b>What is functional programming?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">To keep it short, functional programming (FP) is a paradigm that attempts to reproduce the concept of mathematical functions, which is a relationship between the sets of domains (valid inputs) and the codomain (valid outputs). Mathematical function outputs are always related to just one input, so whenever a mathematical function is calculated with the same input, it returns the same output. This is one of FP\u2019s most important concepts, also known as <\/span><b>determinism<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>Non-deterministic function example<\/strong>:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">let x = 1<\/span>\n\n<span style=\"font-weight: 400;\">const nonDeterministicAdd = y =&gt; x + y<\/span>\n\n<span style=\"font-weight: 400;\">nonDeterministicAdd(2) \/\/ 3<\/span>\n\n<span style=\"font-weight: 400;\">x = 2<\/span>\n\n<span style=\"font-weight: 400;\">nonDeterministicAdd(2) \/\/ 4\n\n<\/span><\/pre>\n<p><span style=\"font-weight: 400;\"><strong>Deterministic function example<\/strong>:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">const deterministicAdd = (x, y) =&gt; x + y<\/span>\n\n<span style=\"font-weight: 400;\">deterministicAdd(1, 2) \/\/ 3\n\n<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">In addition to determinism, functions in FP seek not to cause changes beyond their scope. These types of functions are called <\/span><a href=\"https:\/\/helder.dev\/what-is-a-pure-function\/\"><span style=\"font-weight: 400;\">pure<\/span><\/a><span style=\"font-weight: 400;\">. Last but not least, the data in FP must be immutable, meaning it cannot have its value changed after creation. These concepts together make testing, caching, and parallelism easier.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Beside these basic concepts, I also tried to use Point-free style during the development of the game, which aims to make the code cleaner as it omits the use of unnecessary parameters and arguments. Here<\/span><a href=\"https:\/\/jrsinclair.com\/articles\/2016\/marvellously-mysterious-javascript-maybe-monad\/#pointfreestyle\"><span style=\"font-weight: 400;\">\u00b9<\/span><\/a><a href=\"https:\/\/www.freecodecamp.org\/news\/how-point-free-composition-will-make-you-a-better-functional-programmer-33dcb910303a\/\"><span style=\"font-weight: 400;\">\u00b2<\/span><\/a><span style=\"font-weight: 400;\"> are a couple of good references about it.&nbsp;&nbsp;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Since the beginning of the project, the intention was to create a game that runs in the browser. Because Javascript (JS) is a language that I feel comfortable with and is a multi-paradigm language, it was language I chose for this project.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There are two excellent books about FP that I recommend:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/github.com\/getify\/Functional-Light-JS\"><span style=\"font-weight: 400;\">Functional Light JS<\/span><\/a><span style=\"font-weight: 400;\">&nbsp;<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><a href=\"https:\/\/github.com\/MostlyAdequate\/mo%C3%A9stly-adequate-guide\">Mostly adequate guide to FP<\/a><\/span><\/li>\n<\/ul>\n<h2><b>The Project<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The implemented project is a turn-based spaceship game. In the game, each player has 3 ships and on each turn the player must choose the place they want to move the spaceship within its reach range and in which direction they want to shoot. When the spaceship gets shot it loses part of its shield. If a spaceship has no shield left, it gets destroyed and the player who runs out of spaceships loses the game.<\/span><\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" class=\"aligncenter\" title=\"functional programming\" src=\"https:\/\/github.com\/karranb\/functional-spaceship-game\/raw\/master\/docs\/sample_initial_round.gif\" alt=\"functional programming\" width=\"684\" height=\"448\">Initial turn of a match<\/p>\n<p><span style=\"font-weight: 400;\">So far, the game only allows for one player to participate, and this person controls the 3 spaceships at the top of the screen, facing a script that controls the 3 spaceships at the bottom, which randomizes the position and the target of its spaceships. Regarding the graphic part, I used the <\/span><a href=\"https:\/\/www.pixijs.com\/\"><span style=\"font-weight: 400;\">PixiJS<\/span><\/a><span style=\"font-weight: 400;\"> package to control the rendering, which is the only production dependency of the project, and I also used spaceship sprites that were freely available from <\/span><a href=\"http:\/\/unluckystudio.com\/\"><span style=\"font-weight: 400;\">UnLucky Studio<\/span><\/a><span style=\"font-weight: 400;\"> on the <\/span><a href=\"https:\/\/opengameart.org\/content\/complete-spaceship-game-art-pack\"><span style=\"font-weight: 400;\">OpenGameart<\/span><\/a><span style=\"font-weight: 400;\"> site.<\/span><\/p>\n<h2><b>Base and Helper Functions<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In the beginning of the implementation, a file was created with base functions that were used in almost all project files. Some of these base functions exist natively in JS, such as <\/span><a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/map\"><span style=\"font-weight: 400;\">map<\/span><\/a><span style=\"font-weight: 400;\"> e <\/span><a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/reduce\"><span style=\"font-weight: 400;\">reduce<\/span><\/a><span style=\"font-weight: 400;\">. JS also has several other functions that fit the FP paradigm by not changing their input values, and which were used in the project,&nbsp;<\/span><span style=\"font-weight: 400;\">such as<\/span> <a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/filter\"><span style=\"font-weight: 400;\">filter<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/find\"><span style=\"font-weight: 400;\">find<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/some\"><span style=\"font-weight: 400;\">some<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/every\"><span style=\"font-weight: 400;\">every<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\"> A good source for discovering these functions is <\/span><a href=\"https:\/\/doesitmutate.xyz\/\"><span style=\"font-weight: 400;\">Does it mutate<\/span><\/a><span style=\"font-weight: 400;\">.&nbsp;<\/span><span style=\"font-weight: 400;\">To follow the point-free style, it was also necessary to implement the following base functions:<\/span><\/p>\n<ul>\n<li><span style=\"font-weight: 400;\">Curry:<\/span> <span style=\"font-weight: 400;\">Allows the function to receive it<\/span><span style=\"font-weight: 400;\">s arguments in separate moments<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">add<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">curry<\/span><span style=\"font-weight: 400;\">((<\/span><span style=\"font-weight: 400;\">x<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">y<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">x<\/span><span style=\"font-weight: 400;\"> + <\/span><span style=\"font-weight: 400;\">y<\/span><span style=\"font-weight: 400;\">)<\/span>\n\n<span style=\"font-weight: 400;\">add<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">1<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">2<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">\/\/ 3<\/span>\n\n<span style=\"font-weight: 400;\">add<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">1<\/span><span style=\"font-weight: 400;\">)(<\/span><span style=\"font-weight: 400;\">2<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">\/\/ 3<\/span><\/pre>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Compose: The functions are passed as arguments and are executed in reverse order. Each function consumes the return of the previous function.<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">addAndIncrement<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;<\/span><span style=\"font-weight: 400;\">add<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">1<\/span><span style=\"font-weight: 400;\">), <\/span><span style=\"font-weight: 400;\">\/\/ previous add result + 1<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;<\/span><span style=\"font-weight: 400;\">add<\/span> <span style=\"font-weight: 400;\">\/\/ arg1 + arg2<\/span>\n\n<span style=\"font-weight: 400;\">)<\/span>\n\n<span style=\"font-weight: 400;\">addAndIncrement<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">2<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">2<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">\/\/ 5<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">There are several libraries in which these functions are already implemented, such as <\/span><a href=\"https:\/\/ramdajs.com\/\"><span style=\"font-weight: 400;\">Ramda<\/span><\/a><span style=\"font-weight: 400;\">, but in this project, I decided to implement them to try to better understand how they work. This <\/span><a href=\"https:\/\/medium.com\/dailyjs\/functional-js-with-es6-recursive-patterns-b7d0813ef9e3\"><span style=\"font-weight: 400;\">article<\/span><\/a><span style=\"font-weight: 400;\"> was a great source to investigate how they might work and how you could implement these and other functions recursively.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To facilitate the composition of the native JS functions that were used, I created helpers using curry, where the entries are passed as arguments.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Example:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">filter<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">curry<\/span><span style=\"font-weight: 400;\">((<\/span><span style=\"font-weight: 400;\">fn<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">array<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">array<\/span><span style=\"font-weight: 400;\">.<\/span><span style=\"font-weight: 400;\">filter<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">fn<\/span><span style=\"font-weight: 400;\">))<\/span>\n\n<span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">getAliveSpaceships<\/span><span style=\"font-weight: 400;\"> =<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><b>filter<\/b><b>(<\/b><b>isAlive<\/b><b>),<\/b>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getSpaceships\n<\/span><\/pre>\n<h2><b>And how do we declare the models?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Regarding the models\u2019 implementations, we used the <\/span><a href=\"https:\/\/guide.freecodecamp.org\/javascript\/object-instantiation\/functional\/\"><span style=\"font-weight: 400;\">functional-shared<\/span><\/a><span style=\"font-weight: 400;\"> style, in which a model instance is an object with its properties and functions. To manage the state of models, we created the following helper, where `getState` returns the state of the instance; `assignState` returns a new instance with the old state concatenated with the new one and` getProp` returns the value of the passed property encapsulated in a monad.&nbsp; <\/span><span style=\"font-weight: 400;\">Monad is a popular construction in FP, and is a bit hard to summarize an one-line definition, so <\/span><a href=\"https:\/\/jrsinclair.com\/articles\/2016\/marvellously-mysterious-javascript-maybe-monad\/\"><span style=\"font-weight: 400;\">here<\/span><\/a><span style=\"font-weight: 400;\"> is an article that explains it in a friendly manner.<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">modelFunctions<\/span><span style=\"font-weight: 400;\"> = (<\/span><span style=\"font-weight: 400;\">model<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">state<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> ({<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getState<\/span><span style=\"font-weight: 400;\">:<\/span><span style=\"font-weight: 400;\"> () <\/span><span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">state<\/span><span style=\"font-weight: 400;\">,<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">assignState<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">newProps<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">model<\/span><span style=\"font-weight: 400;\">({ ...<\/span><span style=\"font-weight: 400;\">state<\/span><span style=\"font-weight: 400;\">, ...<\/span><span style=\"font-weight: 400;\">newProps <\/span><span style=\"font-weight: 400;\">}),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getProp<\/span><span style=\"font-weight: 400;\">:<\/span> <span style=\"font-weight: 400;\">name<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">getProp(<\/span><span style=\"font-weight: 400;\">state<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">name<\/span><span style=\"font-weight: 400;\">)<\/span><span style=\"font-weight: 400;\">,<\/span>\n\n<span style=\"font-weight: 400;\">})<\/span><\/pre>\n<p><span style=\"font-weight: 400;\"><br \/>\nWith this helper we can declare models, create instances and use their functions as follows:<\/span><\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">Engine<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">state<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span><span style=\"font-weight: 400;\"> ({ ...<\/span><span style=\"font-weight: 400;\">modelFunctions<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">Engine<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">state<\/span><span style=\"font-weight: 400;\">) })<\/span>\n\n<span style=\"font-weight: 400;\">Engine<\/span><span style=\"font-weight: 400;\">({ <\/span><span style=\"font-weight: 400;\">a:<\/span> <span style=\"font-weight: 400;\">'a'<\/span><span style=\"font-weight: 400;\"> }).<\/span><span style=\"font-weight: 400;\">assignState<\/span><span style=\"font-weight: 400;\">({ <\/span><span style=\"font-weight: 400;\">b:<\/span> <span style=\"font-weight: 400;\">'b' <\/span><span style=\"font-weight: 400;\">}).<\/span><span style=\"font-weight: 400;\">getState<\/span><span style=\"font-weight: 400;\">() <\/span><span style=\"font-weight: 400;\">\/\/ { a: 'a', b: 'b' }<\/span><\/pre>\n<h2><b>Implementing the rest<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Once you have the base functions and templates defined there is still a lot left to implement. Below are some of the project functions that give a good taste of readability and how easy it is to compose the functions.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Remove the player\u2019s destroyed spaceships<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">removeDestroyedSpaceships<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">player<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">setSpaceships(player<\/span><span style=\"font-weight: 400;\">),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getAliveSpaceships<\/span>\n\n<span style=\"font-weight: 400;\">)(<\/span><span style=\"font-weight: 400;\">player<\/span><span style=\"font-weight: 400;\">)<\/span><\/pre>\n<pre><span style=\"font-weight: 400;\">&nbsp;<\/span><\/pre>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Reduce the spaceship shield<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">export<\/span> <span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">reduceShield<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">curry<\/span><span style=\"font-weight: 400;\">((<\/span><span style=\"font-weight: 400;\">spaceship<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">damage<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">checkDestroyed<\/span><span style=\"font-weight: 400;\">,<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">shield<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">assignState<\/span><span style=\"font-weight: 400;\">({ <\/span><span style=\"font-weight: 400;\">shield<\/span><span style=\"font-weight: 400;\"> }, <\/span><span style=\"font-weight: 400;\">spaceship<\/span><span style=\"font-weight: 400;\">),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">shield<\/span> <span style=\"font-weight: 400;\">=&gt;<\/span> <span style=\"font-weight: 400;\">sub<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">shield<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">damage<\/span><span style=\"font-weight: 400;\">),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getShield<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;)(<\/span><span style=\"font-weight: 400;\">spaceship<\/span><span style=\"font-weight: 400;\">)<\/span>\n\n<span style=\"font-weight: 400;\">)<\/span><\/pre>\n<p>Implementations made through composition are often easier to understand compared to imperative functional programming. This function, for example, was analyzed by <a href=\"https:\/\/www.sonarqube.org\">SonarQube<\/a> for cognitive complexity and received the best possible score.<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Get the spaceship\u2019s bullets<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">export<\/span> <span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">getBullets<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">either<\/span><span style=\"font-weight: 400;\">([]),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">getProp<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'bullets'<\/span><span style=\"font-weight: 400;\">)<\/span>\n\n<span style=\"font-weight: 400;\">)<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Here it was possible to omit the function argument as it was only being used by one of the compound functions. There is also a guarantee that the returned value will be valid because &#8216;getProp&#8217;&nbsp; returns a monad and &#8216;either&#8217; returns the monad&#8217;s encapsulated value if it is a valid value or an empty array.<\/span><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Set a new position for the bullet<\/span><\/li>\n<\/ul>\n<pre><span style=\"font-weight: 400;\">const<\/span> <span style=\"font-weight: 400;\">setPosition<\/span><span style=\"font-weight: 400;\"> = <\/span><span style=\"font-weight: 400;\">curry<\/span><span style=\"font-weight: 400;\">((<\/span><span style=\"font-weight: 400;\">coordinate<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">bullet<\/span><span style=\"font-weight: 400;\">) <\/span><span style=\"font-weight: 400;\">=&gt;<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">compose<\/span><span style=\"font-weight: 400;\">(<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">callListenerIfExist<\/span><span style=\"font-weight: 400;\">(<\/span><span style=\"font-weight: 400;\">'onMove'<\/span><span style=\"font-weight: 400;\">),<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">assignState<\/span><span style=\"font-weight: 400;\">({ <\/span><span style=\"font-weight: 400;\">coordinate<\/span><span style=\"font-weight: 400;\"> })<\/span>\n\n<span style=\"font-weight: 400;\">&nbsp;&nbsp;)(<\/span><span style=\"font-weight: 400;\">bullet<\/span><span style=\"font-weight: 400;\">)<\/span>\n\n<span style=\"font-weight: 400;\">)\n\n\n<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">FP composition requires functions to always have a return value. If&nbsp; &#8216;callListenerIfExist&#8217; does not return any value, it would not be possible to chain other functions with it or with &#8216;setPosition&#8217; after their execution.<\/span><\/p>\n<h2><b>Was it worth it?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">This is the project <\/span><a href=\"https:\/\/github.com\/karranb\/functional-spaceship-game\"><span style=\"font-weight: 400;\">repository<\/span><\/a><span style=\"font-weight: 400;\"> and hosted on this <\/span><a href=\"https:\/\/zealous-lichterman-adc5bd.netlify.com\/\"><span style=\"font-weight: 400;\">link<\/span><\/a><span style=\"font-weight: 400;\">. Because I have not had any previous experience with FP, I had to refactor the project several times and also found FP hard to debug, because of things like stack tracing limit. But on the other hand, the functions are very readable and easy to be reused. I do not advise projects that have require ambition and short deadlines to be done using paradigms\/technologies that you are not used to, but this project has been developed with the intention of learning. Avoiding using libraries and implementing the base functions was very helpful to understand how each one of them works, and the final package size was pretty much only the size of the PixiJS modules that were used.<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">&nbsp;<\/span><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>There has been a lot of hype around the functional programming paradigm for some time and there are a lot of great books and articles about it on the internet, but it&#8217;s not so easy to find real examples with its application. So have I decided to create a game trying to follow its concepts [&hellip;]<\/p>\n","protected":false},"author":65,"featured_media":6589,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[432],"tags":[305,303],"class_list":["post-6582","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering","tag-tag-development","tag-tag-frontend"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using functional programming to create a game in JS<\/title>\n<meta name=\"description\" content=\"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using functional programming to create a game in JS\" \/>\n<meta property=\"og:description\" content=\"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Cheesecake Labs\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/cheesecakelabs\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-19T19:00:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-01T17:09:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Cheesecake Labs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:site\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\"},\"author\":{\"name\":\"Karran Besen\"},\"headline\":\"Using functional programming to create a game in JS\",\"datePublished\":\"2019-12-19T19:00:33+00:00\",\"dateModified\":\"2022-07-01T17:09:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\"},\"wordCount\":1151,\"image\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png\",\"keywords\":[\"development\",\"Front-end\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\",\"name\":\"Using functional programming to create a game in JS\",\"isPartOf\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png\",\"datePublished\":\"2019-12-19T19:00:33+00:00\",\"dateModified\":\"2022-07-01T17:09:28+00:00\",\"author\":{\"@type\":\"person\",\"name\":\"Karran Besen\"},\"description\":\"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.\",\"breadcrumb\":{\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage\",\"url\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png\",\"contentUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png\",\"width\":2000,\"height\":720,\"caption\":\"functional programming\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cheesecakelabs.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using functional programming to create a game in JS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#website\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/\",\"name\":\"Cheesecake Labs\",\"description\":\"Nearshore outsourcing company for Web and Mobile design and engineering services, and staff augmentation for startups and enterprises..\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cheesecakelabs.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"name\":\"Karran Besen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cheesecakelabs.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/karran-300x300.png\",\"contentUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/karran-300x300.png\",\"caption\":\"Karran Besen\"},\"description\":\"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.\",\"url\":\"https:\/\/cheesecakelabs.com\/blog\/autor\/karran-besen\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using functional programming to create a game in JS","description":"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/","og_locale":"en_US","og_type":"article","og_title":"Using functional programming to create a game in JS","og_description":"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.","og_url":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/","og_site_name":"Cheesecake Labs","article_publisher":"https:\/\/www.facebook.com\/cheesecakelabs","article_published_time":"2019-12-19T19:00:33+00:00","article_modified_time":"2022-07-01T17:09:28+00:00","og_image":[{"width":2000,"height":720,"url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png","type":"image\/png"}],"author":"Cheesecake Labs","twitter_card":"summary_large_image","twitter_creator":"@cheesecakelabs","twitter_site":"@cheesecakelabs","twitter_misc":{"Written by":null,"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#article","isPartOf":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/"},"author":{"name":"Karran Besen"},"headline":"Using functional programming to create a game in JS","datePublished":"2019-12-19T19:00:33+00:00","dateModified":"2022-07-01T17:09:28+00:00","mainEntityOfPage":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/"},"wordCount":1151,"image":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage"},"thumbnailUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png","keywords":["development","Front-end"],"articleSection":["Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/","url":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/","name":"Using functional programming to create a game in JS","isPartOf":{"@id":"https:\/\/cheesecakelabs.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage"},"image":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage"},"thumbnailUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png","datePublished":"2019-12-19T19:00:33+00:00","dateModified":"2022-07-01T17:09:28+00:00","author":{"@type":"person","name":"Karran Besen"},"description":"Explanation of how functional programming techniques can create a javascript game and a brief analysis of whether it was worth it or not.","breadcrumb":{"@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#primaryimage","url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png","contentUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/functional_programming.png","width":2000,"height":720,"caption":"functional programming"},{"@type":"BreadcrumbList","@id":"https:\/\/cheesecakelabs.com\/blog\/functional-programming-game-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cheesecakelabs.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using functional programming to create a game in JS"}]},{"@type":"WebSite","@id":"https:\/\/cheesecakelabs.com\/blog\/#website","url":"https:\/\/cheesecakelabs.com\/blog\/","name":"Cheesecake Labs","description":"Nearshore outsourcing company for Web and Mobile design and engineering services, and staff augmentation for startups and enterprises..","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cheesecakelabs.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","name":"Karran Besen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cheesecakelabs.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/karran-300x300.png","contentUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/12\/karran-300x300.png","caption":"Karran Besen"},"description":"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.","url":"https:\/\/cheesecakelabs.com\/blog\/autor\/karran-besen\/"}]}},"_links":{"self":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6582","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/comments?post=6582"}],"version-history":[{"count":1,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6582\/revisions"}],"predecessor-version":[{"id":10179,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/posts\/6582\/revisions\/10179"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/media\/6589"}],"wp:attachment":[{"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/media?parent=6582"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/categories?post=6582"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cheesecakelabs.com\/blog\/wp-json\/wp\/v2\/tags?post=6582"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}