<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: anatdagan</title>
    <description>The latest articles on Forem by anatdagan (@anatdagan).</description>
    <link>https://forem.com/anatdagan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F197001%2Fae41079c-3b1d-4795-b179-3f28b9177e79.png</url>
      <title>Forem: anatdagan</title>
      <link>https://forem.com/anatdagan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/anatdagan"/>
    <language>en</language>
    <item>
      <title>A Usage Example for a Monad in Javascript</title>
      <dc:creator>anatdagan</dc:creator>
      <pubDate>Thu, 10 Feb 2022 13:22:23 +0000</pubDate>
      <link>https://forem.com/anatdagan/a-usage-example-for-a-monad-in-javascript-6g3</link>
      <guid>https://forem.com/anatdagan/a-usage-example-for-a-monad-in-javascript-6g3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Whenever I come across a cool concept in Computer Science, I try to think how to use it in real life scenarios.&lt;br&gt;
I've recently read Kyle Simpson's highly recommended book &lt;a href="https://github.com/getify/Functional-Light-JS"&gt;"Functional-Light JavaScript"&lt;/a&gt; that manages somehow to be thorough, innovative and fun to read at the same time.&lt;br&gt;
Near the end of the book Simpson discusses Monads, and demonstrates the concept with a cute example that is also a parable about the importance of humility and knowledge sharing.&lt;br&gt;&lt;br&gt;
While I found this lesson valuable, I tried to come up with an example that could be useful in a real project.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is a Monad
&lt;/h2&gt;

&lt;p&gt;According to Simpson, a monad is a set of behaviors that makes working with a value more predictable. &lt;br&gt;
Predictable code is easier for others (and for our future selves) to understand and predict what it will do.&lt;br&gt;
As a result, it is less probable to surprise us with unexpected results (== bugs).&lt;br&gt;
Monads help us write predictable code by enforcing functional programming principles like immutability, pure functions and composition.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Monad building blocks
&lt;/h2&gt;

&lt;p&gt;For my example I'm using the following monads as building blocks to create other monads from.&lt;/p&gt;
&lt;h3&gt;
  
  
  Just monad
&lt;/h3&gt;

&lt;p&gt;This is a basic monad that many other monads build on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Just = (val) =&amp;gt; {
    return {
        map: (fn) =&amp;gt; Just(fn(val)),
        chain: (fn) =&amp;gt; fn(val),
        ap: (monad) =&amp;gt; {monad.map(val)}
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's an object with a value and 3 methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;map&lt;/code&gt; accepts a function, calls it with the value, and creates a new Just monad that its value is the result&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chain&lt;/code&gt; accepts a function, calls it with a value and returns the result as is.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ap&lt;/code&gt; function accepts a monad and executes the other monad's map function with the value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Confused? Check the game example below to see it in action :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Nothing Monad
&lt;/h3&gt;

&lt;p&gt;This is a monad that has the same interface as Just monad, but all of the methods return a Nothing monad.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Nothing = (val) =&amp;gt; {
    return {
        map: (fn) =&amp;gt; Nothing(),
        chain: (fn) =&amp;gt; Nothing(),
        ap: (monad) =&amp;gt; Nothing()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the following example I will use a popular construct called 'Maybe' that switches between the Just monad and the Nothing monad to implement conditional behavior in a readable and reliable way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Game example
&lt;/h2&gt;

&lt;p&gt;This example simulates a game between two players.&lt;br&gt;
I'm using the Maybe construct to make sure players score does not change after they have been removed from the game.&lt;br&gt;
I add to the Just and Nothing Monads a 'get' method in order to gain access to the player's score and strikes after the game is over.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// this function is used to break down a function into successive
// chained functions that each take a single argument and return 
// another function to accept the next argument.

const curry = (f) =&amp;gt; { 
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// define the utility Monads

const Just = (val) =&amp;gt; {
    return {
      map: (fn) =&amp;gt; Just(fn(val)),
      chain: (fn) =&amp;gt; fn(val),
      ap: (monad) =&amp;gt; {monad.map(val)},
      get: () =&amp;gt; {return val}
    }
}
const Nothing = (val) =&amp;gt; {
    return {
        map: (fn) =&amp;gt; Nothing(val),
        chain: (fn) =&amp;gt; Nothing(val),
        ap: (monad) =&amp;gt; Nothing(val),
        get: () =&amp;gt; {return val}
    }
}

const Maybe = {Nothing, of: Just}; 

// logs the player's stats 
// @param {object} p - the player object
const logPlayerSummary = (player) =&amp;gt; {
console.log(`${player.name} won ${player.score} times and lost ${player.strikes} times`);
}
const logGameSummary = (player1, player2) =&amp;gt; {
    logPlayerSummary(player1);
    logPlayerSummary(player2);
    if (player1.score === player2.score) {
        console.log('the game is a draw.');
    } else {
        const winner = player1.score &amp;gt; player2.score ? player1 : player2;
        console.log(`${winner.name} won the game!`)
    }
}

// increases the player's score
// @param {object} p - the player object
// @returns {object} the updated player after the increase  
const win = (p) =&amp;gt; {
  const winner = {...p};
  winner.score +=1;
  console.log(`${winner.name} wins`);
  return winner;
}

// increases the player's strikes
// @param {object} p - the player object
// @returns {object} the updated player after the increase  
const lose = (p) =&amp;gt; {
  const loser = {...p};
  loser.strikes += 1
  return loser;
}

// checks if the player is still in the game
// @param {object} p - the player object
// @returns Just if true and Mothing if false

const isInGame = (p) =&amp;gt; {
  if (p.strikes &amp;lt; 3) {
    return Maybe.of(p);
  } else {
    return Maybe.Nothing(p);
  }
}


// @returns {number} a random number between 0 and 1
const flipCoin = () =&amp;gt; { 
   return Math.random();
}

// define the players. 
// For this example I'll use just 2 players,
// but it should work with any number.

let player1Monad = Just({
       name: 'Salvor',
       score: 0,
       strikes:0
   });

let player2Monad = Just({
      name: 'Fara',
      score: 0,
      strikes:0
   });

// In a real life scenario the game logic could be more complicated
// and have many stages
for (let i = 0; i &amp;lt; 10;  i++) {
    if (flipCoin() &amp;gt; 0.5) {
        player1Monad = player1Monad.chain(isInGame).map(win);
        player2Monad = player2Monad.chain(isInGame).map(lose);
    } else {
        player2Monad = player2Monad.chain(isInGame).map(win);
        player1Monad = player1Monad.chain(isInGame).map(lose);
     }
}

//now we are after the game, so we can "revive" the Nothing players
player1Monad = Just(player1Monad.get());
player2Monad = Just(player2Monad.get());

// Show final stats
player1Monad.map(curry(logGameSummary)).ap(player2Monad);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Game example explained
&lt;/h2&gt;

&lt;p&gt;In this example I represent a coin flip competition between two players: Salvor and Fara.&lt;br&gt;
The game has 10 rounds. In each round, if the result is greater than 0.5 Salvor wins and if lower Fara.&lt;br&gt;
Whenever one player wins, the other one loses.&lt;br&gt;
After 3 losses the player strikes out and its score and strikes no longer change.&lt;br&gt;
At the end of the game the score and strikes of both players are logged to the console.&lt;br&gt;
When a player wins or loses, there is an intermediate stage:&lt;br&gt;
&lt;code&gt;player1Monad = player1Monad.chain(isInGame).map(win);&lt;/code&gt;&lt;br&gt;
&lt;code&gt;isInGame&lt;/code&gt; function is called with player1Monad's value (using &lt;code&gt;chain&lt;/code&gt;) and if the player didn't exceed the allowed number of strikes it returns a new just monad with the same value.&lt;br&gt;
Then the function 'win' is called with player1Monad and returns a new Monad with the updated score (using 'map'). &lt;br&gt;
If the player just striked out, &lt;code&gt;isInGame&lt;/code&gt; returns a Nothing Monad, so the 'map' function also returns a nothing Monad with unchanged value.&lt;br&gt;
In future iterations, the striked out player will also get a Nothing Monad, because both 'chain' and 'map' will always return Nothing.&lt;/p&gt;

&lt;p&gt;Pay attention that while I store the number of strikes on the player object, it would work just as well if the striking out were an event that wasn't stored, e.g. the game was a dice instead of a coin flip and the first player to get one was removed from the game.&lt;br&gt;
After the player would get 1, she would have become nothing, and no further checks would have been required.&lt;br&gt;&lt;br&gt;
At the end of the game I need to extract the players stats in order to display the total score.&lt;br&gt;
This could be a problem if the players are nothing.&lt;br&gt;
In order to overcome this problem, I use the &lt;code&gt;get&lt;/code&gt; method to create new Just monads with the players' score.&lt;br&gt;
The &lt;code&gt;logGameSummary&lt;/code&gt; is a function that takes the stats of both players and displays the game summary.&lt;br&gt;
&lt;code&gt;player1Monad.map(curry(logGameSummary)).ap(player2Monad);&lt;/code&gt;&lt;br&gt;
In order to work with the values of both monads, I'm using the method &lt;code&gt;ap&lt;/code&gt; that executes the value of one monad with the value of the other monad and returns a new monad.&lt;br&gt;
For &lt;code&gt;ap&lt;/code&gt; method to work, the value of one of the monads must be a function.&lt;br&gt;
To accomplish this I'm using the &lt;code&gt;curry&lt;/code&gt; function.&lt;br&gt;
It is a very useful function in FP, and if you don't know it I recommend looking it up.&lt;br&gt;
It breaks down &lt;code&gt;logGameSummary&lt;/code&gt; into successive chained functions, that one of them takes the first player's stats and returns another function to accept the next player's stats.&lt;br&gt;
This function calls &lt;code&gt;logGameSummary&lt;/code&gt; with both players' stats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this post I've contrived a usage example of the Maybe Monad that could be integrated into a game app.&lt;br&gt;
While there are many ways to implement this simple game, this approach has some advantages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's immutable&lt;/li&gt;
&lt;li&gt;It's relatively short&lt;/li&gt;
&lt;li&gt;You don't have to maintain state of which players are active and check it all the time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've learned a lot from writing this example, and now I humbly share it with you. &lt;br&gt;
I hope you enjoy it, and will be happy to read your thoughts on the subject. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
    </item>
    <item>
      <title>Can I get a dash of regular expression in my KQL?</title>
      <dc:creator>anatdagan</dc:creator>
      <pubDate>Fri, 23 Apr 2021 11:02:34 +0000</pubDate>
      <link>https://forem.com/anatdagan/can-i-get-a-dash-of-regular-expression-in-my-kql-op8</link>
      <guid>https://forem.com/anatdagan/can-i-get-a-dash-of-regular-expression-in-my-kql-op8</guid>
      <description>&lt;p&gt;Some developers love regular expressions, some abhor them.&lt;br&gt;
I belong to the first group.&lt;br&gt;
I know that regular expressions can have a bad impact on performance, and that they are not suitable for every situation. However, every once in a while, they absolutely save the day.&lt;/p&gt;

&lt;p&gt;In one of these times I wanted to find in a Kusto table strings with characters that are not English letters, hyphen or underscore.&lt;/p&gt;

&lt;p&gt;This is the command that I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| extend IllegalChar = extract("[^a-zA-Z\-_]", 0, name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy, right?&lt;/p&gt;

&lt;p&gt;I was unpleasantly surprised when Kusto rejected the query with an obscure error message, stating that it can't parse my regular expression.&lt;/p&gt;

&lt;p&gt;Immediately I turned to regex101.com, the regular expression buff's best friend. But the regular expression seemed to be valid.&lt;/p&gt;

&lt;p&gt;I had to do some digging until I found the issue.&lt;br&gt;
Apparently in SQL the hyphen needs to be in the beginning or end of the sub pattern, and there you don't even have to escape it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| extend IllegalChar = extract("[^-a-zA-Z_]", 0, name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this could help someone....&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@eiskonen?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Hans Eiskonen&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/traffic-sign?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kusto</category>
      <category>regex</category>
      <category>sql</category>
      <category>syntax</category>
    </item>
  </channel>
</rss>
