<?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>DEV Community: Christian Neumanns</title>
    <description>The latest articles on DEV Community by Christian Neumanns (@practicalprogramming).</description>
    <link>https://dev.to/practicalprogramming</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%2F142560%2F6cbc4715-0d92-45cd-9e20-822ed8588518.jpg</url>
      <title>DEV Community: Christian Neumanns</title>
      <link>https://dev.to/practicalprogramming</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/practicalprogramming"/>
    <language>en</language>
    <item>
      <title>Simple Introduction to Monads - With Java Examples</title>
      <dc:creator>Christian Neumanns</dc:creator>
      <pubDate>Thu, 02 Apr 2020 13:49:49 +0000</pubDate>
      <link>https://dev.to/practicalprogramming/simple-introduction-to-monads-with-java-examples-2aio</link>
      <guid>https://dev.to/practicalprogramming/simple-introduction-to-monads-with-java-examples-2aio</guid>
      <description>&lt;h1&gt;
  
  
  Simple Introduction to Monads - With Java Examples
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C66GqFz7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C66GqFz7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png" alt="Function Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Far more than 100 articles about monads have been written! There is even a &lt;a href="https://wiki.haskell.org/Monad_tutorials_timeline" class="pml-link"&gt;Monad tutorials timeline&lt;/a&gt; (from 1992 to 2015).&lt;/p&gt;

&lt;p&gt;Why, then, yet another monad article?&lt;/p&gt;

&lt;p&gt;Many people (me included) are intrigued and perplexed by the plethora of exotic, long-winded, or simplistic attempts to explain monads. Explanations like "A monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor." don't help. They boost the already prevalent impostor syndrome. When I started my endeavor to 'get it' I often wondered if monads are indeed incomprehensible for normal humans, or if I was just a stupid noob.&lt;/p&gt;

&lt;p&gt;On the other hand, some people seem to believe that understanding monads is as easy as understanding burritos - an idea to which user molemind &lt;a href="https://www.reddit.com/r/haskell/comments/6bxk1v/why_monads_always_get_compared_to_burritos/" class="pml-link"&gt;comments&lt;/a&gt; on Reddit: "Ah cool now I understand what Burritos are!".&lt;/p&gt;

&lt;p&gt;Anyway, I couldn't find an introduction to monads that was easy to understand for beginners with a good background in popular, but non-pure-functional programming languages, such as C#, Java, Javascript, Python, etc. If you are in the same boat then this article hopefully fills this gap and helps to answer the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What is a monad?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why would I use a monad? What's in it for me?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is it true that "Once you understand monads, you lose the ability to explain them to others"?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  A Simple Problem
&lt;/h1&gt;

&lt;p&gt;Suppose we have to write a simple function to 'enthuse' a sentence. The function should do this by transforming an input string as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;remove leading and trailing spaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;convert all letters to uppercase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;append an exclamation point&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, feeding the function with &lt;code&gt;" Hello bob "&lt;/code&gt; should return &lt;code&gt;"HELLO BOB!"&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Simple Solution in Java
&lt;/h1&gt;

&lt;p&gt;In most programming languages this is trivial to do. Here is a solution in Java:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String enthuse ( String sentence ) {
    return sentence.trim().toUpperCase().concat ( "!" );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: Examples in this article are shown in Java. But readers are not required to be Java experts. Only basic Java is used, and the examples could easily be rewritten in C#, and in other languages that support generic types and higher order functions (functions that can take a function as input argument). The full source code is available on &lt;a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/Java_examples/monadtests" class="pml-link"&gt;Gitlab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To write a complete Java 'application' including a rudimentary test, we can put the code below in file &lt;code&gt;MonadTest_01.java&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MonadTest_01 {

    static String enthuse ( String sentence ) {
        return sentence.trim().toUpperCase().concat ( "!" );
    }

    public static void main ( String[] args ) {
        System.out.println ( enthuse ( "  Hello bob  " ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then we can compile and run the program with the following commands:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javac MonadTest_01.java
java MonadTest_01
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output looks as expected:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HELLO BOB!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So far so good.&lt;/p&gt;

&lt;h1&gt;
  
  
  Only Functions!
&lt;/h1&gt;

&lt;p&gt;In the previous Java example we used &lt;em&gt;object methods&lt;/em&gt; (e.g. &lt;code&gt;sentence.trim()&lt;/code&gt;). However, as this article is about monads, we have to be aware that pure functional programming languages don't have methods (functions) executed on objects. A pure functional programming language (based on the lambda calculus) has only side-effect-free functions that take an input and return a result.&lt;/p&gt;

&lt;p&gt;Let us therefore rewrite the previous code (still in Java) by using only pure functions. This is important, because we have to use functions in order to finally understand why monads have been invented.&lt;/p&gt;

&lt;p&gt;Here is the new code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String trim ( String string ) {
    return string.trim();
}

static String toUpperCase ( String string ) {
    return string.toUpperCase();
}

static String appendExclam ( String string ) {
    return string.concat ( "!" );
}

static String enthuse ( String sentence ) {
    return appendExclam ( toUpperCase ( trim ( sentence ) ) );
}

public static void test() {
    System.out.println ( enthuse ( "  Hello bob  " ) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The code starts with three pure functions (&lt;code&gt;trim&lt;/code&gt;, &lt;code&gt;toUpperCase&lt;/code&gt;, and &lt;code&gt;appendExclam&lt;/code&gt;) that take a string as input, and return a string as result. Note that I cheated a bit, because I still use object methods in the function's bodies (e.g. &lt;code&gt;string.trim()&lt;/code&gt;). But that doesn't matter here, because in this exercise we don't care about the &lt;em&gt;implementations&lt;/em&gt; of these three functions - we care about their &lt;em&gt;signatures&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The interesting part is the body of function &lt;code&gt;enthuse&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return appendExclam ( toUpperCase ( trim ( sentence ) ) );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can see that there are only function calls (as in functional programming languages). The calls are nested, and executed like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;step 1: &lt;code&gt;trim ( sentence )&lt;/code&gt; is executed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;step 2: the result of step 1 is fed into &lt;code&gt;toUpperCase&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;step 3: the result of step 2 is fed into &lt;code&gt;appendExclam&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;finally the result of step 3 is returned as the result of function &lt;code&gt;enthuse&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following picture illustres how the initial input is transformed by chaining three functions:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LjdWpOfK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qcuo2m3gj79dkv8h5vuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LjdWpOfK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qcuo2m3gj79dkv8h5vuu.png" alt="Hello Bob Functions Chain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see if everything still works fine we can execute function &lt;code&gt;test&lt;/code&gt;. The result remains the same:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HELLO BOB!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;
  
  
  Function Composition
&lt;/h1&gt;

&lt;p&gt;In functional programming languages, nested function calls (like our &lt;code&gt;appendExclam ( toUpperCase ( trim ( sentence ) ) )&lt;/code&gt;) are called &lt;em&gt;function composition&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Function &lt;em&gt;composition&lt;/em&gt; is the bread and butter of functional programming languages. In the lambda calculus, the body of a function is a single expression. Complex expressions can be created by composing functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C66GqFz7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C66GqFz7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png" alt="Function Composition"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;As we will see later, monads provide a solution to a problem that can arise when we compose functions. Before going on, let us therefore see variations of using function composition in different environments. Readers familiar with this important concept can jump to the next chapter.&lt;/p&gt;
&lt;h2&gt;
  
  
  Unix Pipes
&lt;/h2&gt;

&lt;p&gt;First, it is interesting to note that the idea of function composition is similar to &lt;a href="https://www.geeksforgeeks.org/piping-in-unix-or-linux/" class="pml-link"&gt;pipes in Unix/Linux&lt;/a&gt;. The output of a first command is fed as input into a second command. Then the output of the second command is fed as input into a third command, and so on. In Unix/Linux the symbol &lt;code&gt;|&lt;/code&gt; is used to pipe commands. Here is an example of a pipe that counts the number of files containing &lt;code&gt;"page"&lt;/code&gt; in their name (example borrowed from &lt;a href="https://www.howtogeek.com/438882/how-to-use-pipes-on-linux/" class="pml-link"&gt;How to Use Pipes on Linux&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls - | grep "page" | wc -l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Pipe Operator
&lt;/h2&gt;

&lt;p&gt;Because pipes are useful in many contexts, some programming languages have a specific &lt;em&gt;pipe operator&lt;/em&gt;. For example, F# uses &lt;code&gt;|&amp;gt;&lt;/code&gt; to chain function calls. If Java had this operator, then function &lt;code&gt;enthuse&lt;/code&gt; could be written as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String enthuse ( String sentence ) {
    return trim ( sentence ) |&amp;gt; toUpperCase |&amp;gt; appendExclam;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... which would semantically be the same, but a bit more readable than real Java that uses nested function calls:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String enthuse ( String sentence ) {
    return appendExclam ( toUpperCase ( trim ( sentence ) ) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Function Composition Operator
&lt;/h2&gt;

&lt;p&gt;As function composition is essential, most functional programming languages have a dedicated &lt;em&gt;function composition operator&lt;/em&gt; that makes it trivial to compose functions.&lt;/p&gt;

&lt;p&gt;For example, in Haskell a dot (&lt;code&gt;.&lt;/code&gt;) is used to compose functions (derived from the ring operator symbol ∘ used in maths). The dot is itself a function whose signature is defined as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(.) :: (b -&amp;gt; c) -&amp;gt; (a -&amp;gt; b) -&amp;gt; a -&amp;gt; c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells us that the function takes two functions as input (&lt;code&gt;b -&amp;gt; c&lt;/code&gt; and &lt;code&gt;a -&amp;gt; b&lt;/code&gt;), and returns another function (&lt;code&gt;a -&amp;gt; c&lt;/code&gt;), which is the composition of the two input functions.&lt;/p&gt;

&lt;p&gt;Hence, to state that function &lt;code&gt;h&lt;/code&gt; is the composition of functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;, in Haskell you can simply write:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h = f . g
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the totally different semantics of the dot operator in Haskell and object oriented languages like C#, Java, etc. In Java, &lt;code&gt;f.g&lt;/code&gt; means applying &lt;code&gt;g&lt;/code&gt; on object &lt;code&gt;f&lt;/code&gt; (e.g. &lt;code&gt;person.name&lt;/code&gt;). In Haskell it means composing functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;F# uses &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; to compose functions. It is defined like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let (&amp;gt;&amp;gt;) f g x = g(f(x))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it is used as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let h = f &amp;gt;&amp;gt; g
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: F#'s &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; operator must not be confused with the &lt;em&gt;Monad sequencing operator&lt;/em&gt; in Haskell, which also uses the symbol &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If Java had a syntax similar to F# for function composition, then function &lt;code&gt;enthuse&lt;/code&gt; could be written as:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String enthuse ( String sentence ) = trim &amp;gt;&amp;gt; toUpperCase &amp;gt;&amp;gt; appendExclam;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;
  
  
  Errors, But No Exceptions
&lt;/h1&gt;

&lt;p&gt;For the sake of this tutorial, suppose that our functions can fail in the following ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Function &lt;code&gt;trim&lt;/code&gt; fails if the input string is empty or contains only spaces (i.e. the result cannot be an empty string).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Function &lt;code&gt;toUpperCase&lt;/code&gt; fails if the input string is empty or contains characters others than letters or spaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Function &lt;code&gt;appendExclam&lt;/code&gt; fails if the input string is more than 20 characters long.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In idiomatic Java an exception is thrown to indicate an error. But pure functional programming languages don't support exceptions, because a function cannot have a side-effect. A function that can fail must return error information as part of the result returned by the function. For example, the function returns a string in case of success, or error data in case of an error.&lt;/p&gt;

&lt;p&gt;So let's do that in Java.&lt;/p&gt;

&lt;p&gt;First we define a simple error class with an &lt;code&gt;info&lt;/code&gt; field that describes the error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class SimpleError {

    private final String info;

    public SimpleError ( String info ) {
        this.info = info;
    }

    public String getInfo() { return info; }

    public String toString() { return info; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As said already, the functions must be able to return a string in case of success, or else an error object. To achieve this we can define class &lt;code&gt;ResultOrError&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ResultOrError {

    private final String result;
    private final SimpleError error;

    public ResultOrError ( String result ) {
        this.result = result;
        this.error = null;
    }

    public ResultOrError ( SimpleError error ) {
        this.result = null;
        this.error = error;
    }

    public String getResult() { return result; }

    public SimpleError getError() { return error; }

    public boolean isResult() { return error == null; }

    public boolean isError() { return error != null; }

    public String toString() {
        if ( isResult() ) {
            return "Result: " + result; 
        } else {
            return "Error: " + error.getInfo(); 
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As we can see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The class has two immutable fields to hold either a result or an error&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are two constructors.&lt;/p&gt;

&lt;p&gt;The first one is used in case of success (e.g. &lt;code&gt;return new ResultOrError ( "hello");&lt;/code&gt; ).&lt;/p&gt;

&lt;p&gt;The second constructor is used in case of failure (e.g. &lt;code&gt;return new ResultOrError ( new Error ( "Something went wrong") );&lt;/code&gt; ).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;isResult&lt;/code&gt; and &lt;code&gt;isError&lt;/code&gt; are utility functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;toString&lt;/code&gt; is overridden for debugging purposes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we can rewrite the three utility functions to include error handling:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StringFunctions {

    public static ResultOrError trim ( String string ) {

        String result = string.trim();
        if ( result.isEmpty() ) {
            return new ResultOrError ( new SimpleError (
                "String must contain non-space characters." ) );
        }

        return new ResultOrError ( result );
    }

    public static ResultOrError toUpperCase ( String string ) {

        if ( ! string.matches ( "[a-zA-Z ]+" ) ) {
            return new ResultOrError ( new SimpleError (
                "String must contain only letters and spaces." ) );
        }

        return new ResultOrError ( string.toUpperCase() );
    }

    public static ResultOrError appendExclam ( String string ) {

        if ( string.length() &amp;gt; 20 ) {
            return new ResultOrError ( new SimpleError (
                "String must not exceed 20 characters." ) );
        }

        return new ResultOrError ( string.concat ( "!" ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: To keep this exercise code simple, we don't check and handle &lt;code&gt;null&lt;/code&gt; values (as we would do in production code). For example, if a function is called with &lt;code&gt;null&lt;/code&gt; as input we simply accept that a &lt;code&gt;NullPointerException&lt;/code&gt; is thrown.&lt;/p&gt;

&lt;p&gt;What matters is that the three functions who previously returned a string, now return a &lt;code&gt;ResultOrError&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;As a consequence, function &lt;code&gt;enthuse&lt;/code&gt; that was defined as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String enthuse ( String sentence ) {
    return appendExclam ( toUpperCase ( trim ( sentence ) ) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... doesn't work anymore.&lt;/p&gt;

&lt;p&gt;Unfortunately, function composition is now invalid, because the functions now return a &lt;code&gt;ResultOrError&lt;/code&gt; object, but require a &lt;code&gt;string&lt;/code&gt; as input. The output/input types don't match anymore. The functions can't be chained anymore.&lt;/p&gt;

&lt;p&gt;In the previous version, when the functions returned strings, the output of a function could be fed as input to the next function:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--basFHgHk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ct5zkasgr4tlp2c6b3ol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--basFHgHk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ct5zkasgr4tlp2c6b3ol.png" alt="Chained String Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now this can't be done anymore:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6x8BGQXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2vq4tbvn459ykozjx82r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6x8BGQXF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2vq4tbvn459ykozjx82r.png" alt="String/ROE Functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, we can still implement &lt;code&gt;enthuse&lt;/code&gt; &lt;em&gt;in Java&lt;/em&gt; like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse ( String sentence ) {

    ResultOrError trimmed = trim ( sentence );
    if ( trimmed.isResult() ) {
        ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
        if ( upperCased.isResult() ) {
            return appendExclam ( upperCased.getResult() );
        } else {
            return upperCased;
        }
    } else {
        return trimmed;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Not good! The initial simple one-liner has turned into an ugly monster.&lt;/p&gt;

&lt;p&gt;We can improve a bit:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse_2 ( String sentence ) {

    ResultOrError trimmed = trim ( sentence );
    if ( trimmed.isError() ) return trimmed;

    ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
    if ( upperCased.isError() ) return upperCased;

    return appendExclam ( upperCased.getResult() );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This kind of code works in Java and many other programming languages. But it's certainly not the code we want to write over and over again. Error handling code intermixed with normal flow makes code difficult to read, write, and maintain.&lt;/p&gt;

&lt;p&gt;More importantly, we simply can't write code like this in pure functional programming languages. Remember: An expression returned by a function is made up of &lt;em&gt;function composition&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It's easy to image other cases that lead to the same dilemma. And what should we do in situations where the same problem appears in many variations? Yes, we should try to find a general solution that can be used in a maximum of cases.&lt;/p&gt;

&lt;p&gt;Monads to the rescue!&lt;/p&gt;

&lt;p&gt;Monads provide a general solution for this kind of problem, and they have other benefits as well. As we will see later, monads enable function composition for so-called monadic functions that cannot be composed directly because their types are incompatible.&lt;/p&gt;

&lt;p&gt;Some people say: "You could have invented monads if they didn't exist." (for example Brian Beckman in his excellent presentation &lt;a href="https://www.youtube.com/watch?v=ZhuHCtR3xq8" class="pml-link"&gt;Don't fear the Monad&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;That's true!&lt;/p&gt;

&lt;p&gt;So let's try to find a solution ourselves, ignoring the fact that a monad would solve our problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  The 'bind' Function
&lt;/h1&gt;

&lt;p&gt;In functional programming languages, everything is done with functions. So we know already that we have to create a function to solve our problem.&lt;/p&gt;

&lt;p&gt;Let's call this function &lt;code&gt;bind&lt;/code&gt;, because it's role is to bind two functions that cannot be composed directly.&lt;/p&gt;

&lt;p&gt;Next we have to decide what should be the input of &lt;code&gt;bind&lt;/code&gt;, and what should it return. Let's consider the case of chaining functions &lt;code&gt;trim&lt;/code&gt; and &lt;code&gt;toUppercase&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fH6Vno5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zyst2wk2bgjt7js17na5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fH6Vno5f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zyst2wk2bgjt7js17na5.png" alt="trim/toUppercase functions chain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logic to implement must work as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If &lt;code&gt;trim&lt;/code&gt; returns a string, then &lt;code&gt;toUppercase&lt;/code&gt; can be called, because it takes a string as input. So the final output will be the output of &lt;code&gt;toUppercase&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;code&gt;trim&lt;/code&gt; returns an error, then &lt;code&gt;toUppercase&lt;/code&gt; cannot be called, and the error must simply be forwarded. So the final output will be the output of &lt;code&gt;trim&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can deduce that &lt;code&gt;bind&lt;/code&gt; needs two input arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the result of &lt;code&gt;trim&lt;/code&gt;, which is of type &lt;code&gt;ResultOrError&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;function &lt;code&gt;toUppercase&lt;/code&gt;, because if &lt;code&gt;trim&lt;/code&gt; returns a string then &lt;code&gt;bind&lt;/code&gt; must call &lt;code&gt;toUppercase&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output type of &lt;code&gt;bind&lt;/code&gt; is easy to determine. If &lt;code&gt;trim&lt;/code&gt; returns a string then the output of &lt;code&gt;bind&lt;/code&gt; is the output of &lt;code&gt;toUppercase&lt;/code&gt;, which is of type &lt;code&gt;ResultOrError&lt;/code&gt;. If &lt;code&gt;trim&lt;/code&gt; fails then the output of &lt;code&gt;bind&lt;/code&gt; is the output of &lt;code&gt;trim&lt;/code&gt;, which is also of type &lt;code&gt;ResultOrError&lt;/code&gt;. As the output type is &lt;code&gt;ResultOrError&lt;/code&gt; in both cases, the output type of &lt;code&gt;bind&lt;/code&gt; must be &lt;code&gt;ResultOrError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So now we know the signature of &lt;code&gt;bind&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SE2s6iUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mt87v6q3yazml6zq04zb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SE2s6iUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mt87v6q3yazml6zq04zb.png" alt="string/ROE bind function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Java this is written as:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ResultOrError bind ( ResultOrError value, Function&amp;lt;String, ResultOrError&amp;gt; function )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Implementing &lt;code&gt;bind&lt;/code&gt; is easy, because we know exactly what needs to be done:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError bind ( ResultOrError value, Function&amp;lt;String, ResultOrError&amp;gt; function ) {

    if ( value.isResult() ) {
        return function.apply ( value.getResult() );
    } else {
        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Function &lt;code&gt;enthuse&lt;/code&gt; can now be rewritten as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse ( String sentence ) {

    ResultOrError trimmed = trim ( sentence );

    ResultOrError upperCased = bind ( trimmed, StringFunctions::toUpperCase );
    // alternative:
    // ResultOrError upperCased = bind ( trimmed, string -&amp;gt; toUpperCase(string) );

    ResultOrError result = bind ( upperCased, StringFunctions::appendExclam );
    return result;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But this is still imperative code (a sequence of statements). If we did a good job, then we must be able to rewrite &lt;code&gt;enthuse&lt;/code&gt; by just using function composition. And indeed, we can do it like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse_2 ( String sentence ) {

    return bind ( bind ( trim ( sentence ), StringFunctions::toUpperCase ), StringFunctions::appendExclam );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At first sight the body of &lt;code&gt;bind&lt;/code&gt; might be a bit confusing. We will change that later. The point is that we use only function composition in the body of &lt;code&gt;enthuse&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: If you never saw this kind of code before, then please take your time to digest and fully understand what's going on here. Understanding &lt;code&gt;bind&lt;/code&gt; is the key to understanding monads! &lt;code&gt;bind&lt;/code&gt; is the function name used in Haskell. There are alternative names, such as: &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;chain&lt;/code&gt;, &lt;code&gt;andThen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Does it work correctly? Let's test it. Here is a class containing &lt;code&gt;bind&lt;/code&gt;, the two variations of &lt;code&gt;enthuse&lt;/code&gt;, and some simplistic tests that cover the success and all error paths:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MonadTest_04 {

    // start bind
    static ResultOrError bind ( ResultOrError value, Function&amp;lt;String, ResultOrError&amp;gt; function ) {

        if ( value.isResult() ) {
            return function.apply ( value.getResult() );
        } else {
            return value;
        }
    }
    // end bind

    // start enthuse_1
    static ResultOrError enthuse ( String sentence ) {

        ResultOrError trimmed = trim ( sentence );

        ResultOrError upperCased = bind ( trimmed, StringFunctions::toUpperCase );
        // alternative:
        // ResultOrError upperCased = bind ( trimmed, string -&amp;gt; toUpperCase(string) );

        ResultOrError result = bind ( upperCased, StringFunctions::appendExclam );
        return result;
    }
    // end enthuse_1

    // start enthuse_2
    static ResultOrError enthuse_2 ( String sentence ) {

        return bind ( bind ( trim ( sentence ), StringFunctions::toUpperCase ), StringFunctions::appendExclam );
    }
    // end enthuse_2

    private static void test ( String sentence ) {

        System.out.println ( enthuse ( sentence ) );
        System.out.println ( enthuse_2 ( sentence ) );
    }

    public static void tests() {

        test ( "  Hello bob  " );
        test ( "   " );
        test ( "hello 123" );
        test ( "Krungthepmahanakhon is the capital of Thailand" );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running function &lt;code&gt;tests&lt;/code&gt; outputs:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: HELLO BOB!
Result: HELLO BOB!
Error: String must contain non-space characters.
Error: String must contain non-space characters.
Error: String must contain only letters and spaces.
Error: String must contain only letters and spaces.
Error: String must not exceed 20 characters.
Error: String must not exceed 20 characters.    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;bind&lt;/code&gt; function defined above serves our specific problem. But to make it part of a monad we will have to make it more general. We will do that soon.&lt;/p&gt;

&lt;p&gt;Note: Using &lt;code&gt;bind&lt;/code&gt; as shown above, is the common way to solve our problem of function composition. But it's not the only way. An alternative is called &lt;em&gt;Kleisli composition&lt;/em&gt; (out of the scope of this article).&lt;/p&gt;

&lt;h1&gt;
  
  
  A Monad, Finally!
&lt;/h1&gt;

&lt;p&gt;Now that we have &lt;code&gt;bind&lt;/code&gt;, the remaining steps to get to the monad are easy. We just need to make some improvements in order to have a more general solution that can be applied in other cases too.&lt;/p&gt;

&lt;p&gt;Our goal in this chapter is clear: See the pattern and improve &lt;code&gt;ResultOrError&lt;/code&gt;, so that we can finally enthuse:&lt;/p&gt;

&lt;p&gt;"A MONAD!"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First improvement:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter we defined &lt;code&gt;bind&lt;/code&gt; as an isolated function that fulfilled our specific needs. A first improvement is to move &lt;code&gt;bind&lt;/code&gt; into the &lt;code&gt;ResultOrError&lt;/code&gt; class. Function &lt;code&gt;bind&lt;/code&gt; must be part of our monad class. The reason is that the implementation of &lt;code&gt;bind&lt;/code&gt; depends on the monad that uses &lt;code&gt;bind&lt;/code&gt;. While the &lt;em&gt;signature&lt;/em&gt; of &lt;code&gt;bind&lt;/code&gt; is always the same, different kinds of monads use different &lt;em&gt;implementations&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second Improvement:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In our example code, the composed functions all take a string as input, and return either a string or an error. What if we have to compose functions that take an integer, and return an integer or error? Can we improve &lt;code&gt;ResultOrError&lt;/code&gt; so that it works with &lt;em&gt;any&lt;/em&gt; type of result? Yes, we can. We just have to add a type parameter to &lt;code&gt;ResultOrError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After moving &lt;code&gt;bind&lt;/code&gt; into the class and adding a type parameter, the new version now becomes:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ResultOrErrorMona&amp;lt;R&amp;gt; {

    private final R result;
    private final SimpleError error;

    public ResultOrErrorMona ( R result ) {
        this.result = result;
        this.error = null;
    }

    public ResultOrErrorMona ( SimpleError error ) {
        this.result = null;
        this.error = error;
    }

    public R getResult() { return result; }

    public SimpleError getError() { return error; }

    public boolean isResult() { return error == null; }

    public boolean isError() { return error != null; }

    static &amp;lt;R&amp;gt; ResultOrErrorMona&amp;lt;R&amp;gt; bind ( ResultOrErrorMona&amp;lt;R&amp;gt; value, Function&amp;lt;R, ResultOrErrorMona&amp;lt;R&amp;gt;&amp;gt; function ) {

        if ( value.isResult() ) {
            return function.apply ( value.getResult() );
        } else {
            return value;
        }
    }

    public String toString() {

        if ( isResult() ) {
            return "Result: " + result; 
        } else {
            return "Error: " + error.getInfo(); 
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the class name: &lt;code&gt;ResultOrErrorMona&lt;/code&gt;. This is not a typo. The class isn't a monad yet, so I call it a mona (just for fun).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third Improvement:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose we have to chain the following two functions:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ResultOrError&amp;lt;Integer&amp;gt; f1 ( Integer value )
ResultOrError&amp;lt;String&amp;gt;  f2 ( Integer value )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here is a picture to illustrate this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qpnEz46F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f35o9wxurc74admnqtxh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qpnEz46F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f35o9wxurc74admnqtxh.png" alt="integer/string functions chain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our current &lt;code&gt;bind&lt;/code&gt; function is not able to handle this case, because the output types of the two functions are different (&lt;code&gt;ResultOrError&amp;lt;Integer&amp;gt;&lt;/code&gt; and &lt;code&gt;ResultOrError&amp;lt;String&amp;gt;&lt;/code&gt;). We have to make &lt;code&gt;bind&lt;/code&gt; more general, so that functions of different value types can be chained. The signature of &lt;code&gt;bind&lt;/code&gt; must be changed from&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static &amp;lt;R&amp;gt; Monad&amp;lt;R&amp;gt; bind ( Monad&amp;lt;R&amp;gt; monad, Function&amp;lt;R, Monad&amp;lt;R&amp;gt;&amp;gt; function )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... to&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static &amp;lt;R1, R2&amp;gt; Monad&amp;lt;R2&amp;gt; bind ( Monad&amp;lt;R1&amp;gt; monad, Function&amp;lt;R1, Monad&amp;lt;R2&amp;gt;&amp;gt; function )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The implementation of &lt;code&gt;bind&lt;/code&gt; must be adapted too. Here is the new class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ResultOrErrorMonad&amp;lt;R&amp;gt; {

    private final R result;
    private final SimpleError error;

    public ResultOrErrorMonad ( R result ) {
        this.result = result;
        this.error = null;
    }

    public ResultOrErrorMonad( SimpleError error ) {
        this.result = null;
        this.error = error;
    }

    public R getResult() { return result; }

    public SimpleError getError() { return error; }

    public boolean isResult() { return error == null; }

    public boolean isError() { return error != null; }

    static &amp;lt;R1, R2&amp;gt; ResultOrErrorMonad&amp;lt;R2&amp;gt; bind ( ResultOrErrorMonad&amp;lt;R1&amp;gt; value, Function&amp;lt;R1, ResultOrErrorMonad&amp;lt;R2&amp;gt;&amp;gt; function ) {

        if ( value.isResult() ) {
            return function.apply ( value.result );
        } else {
            return new ResultOrErrorMonad&amp;lt;R2&amp;gt; ( value.error );
        }
    }

    public String toString() {

        if ( isResult() ) {
            return "Result: " + result.toString(); 
        } else {
            return "Error: " + error.toString(); 
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the class name again: &lt;code&gt;ResultOrErrorMonad&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Yes, now it's a monad.&lt;/p&gt;

&lt;p&gt;Note: In the real world we don't add a "monad" suffix for types that are monads. I called the class &lt;code&gt;ResultOrErrorMonad&lt;/code&gt; (instead of simply &lt;code&gt;ResultOrError&lt;/code&gt;) to make it clear that the class is a monad.&lt;/p&gt;

&lt;p&gt;How can we be sure the class is indeed a monad?&lt;/p&gt;

&lt;p&gt;While the term 'monad' has a very precise definition in mathematics (as everything in maths), the term isn't yet unequivocally defined in the world of programming languages. However, Wikipedia states a &lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)#Definition" class="pml-link"&gt;common definition&lt;/a&gt;. A monad consists of three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A type constructor M that builds up a monadic type M T.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In other words, there is a type parameter for the value contained in the monad.&lt;/p&gt;

&lt;p&gt;In our case it's type parameter &lt;code&gt;R&lt;/code&gt; in the class declaration:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ResultOrErrorMonad&amp;lt;R&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A type converter, often called unit or return, that embeds an object x in the monad: &lt;code&gt;unit(x) : T → M T&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Haskell, the type converter is defined as: &lt;code&gt;return :: a -&amp;gt; m a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Java-like languages, this means there must be a constructor that takes a value of type &lt;code&gt;R&lt;/code&gt;, and returns a monad &lt;code&gt;M&amp;lt;R&amp;gt;&lt;/code&gt; that contains this value.&lt;/p&gt;

&lt;p&gt;In our specific case it's the constructor of class &lt;code&gt;ResultOrErrorMonad&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ResultOrErrorMonad ( R result ) 
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A combinator, typically called bind (as in binding a variable) and represented with an infix operator &amp;gt;&amp;gt;=, that unwraps a monadic variable, then inserts it into a monadic function/expression, resulting in a new monadic value: &lt;code&gt;(mx &amp;gt;&amp;gt;= f) : (M T, T → M U) → M U&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Haskell, bind is defined as: &lt;code&gt;(&amp;gt;&amp;gt;=) :: m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In our example it's the &lt;code&gt;bind&lt;/code&gt; function:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;R1, R2&amp;gt; ResultOrErrorMonad&amp;lt;R2&amp;gt; bind ( ResultOrErrorMonad&amp;lt;R1&amp;gt; value, Function&amp;lt;R1, ResultOrErrorMonad&amp;lt;R2&amp;gt;&amp;gt; function )
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wikipedia then states: "To fully qualify as a monad though, these three parts must also respect a few laws: ..."&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad.html#t:Monad" class="pml-link"&gt;Haskell&lt;/a&gt; the three laws as defined as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;return a &amp;gt;&amp;gt;= k = k a&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;m &amp;gt;&amp;gt;= return = m&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;m &amp;gt;&amp;gt;= (\x -&amp;gt; k x &amp;gt;&amp;gt;= h) = (m &amp;gt;&amp;gt;= k) &amp;gt;&amp;gt;= h&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Discussing these laws is out of scope of this article (this is an &lt;em&gt;introduction&lt;/em&gt; to monads). The laws ensure that monads behave well in all situations. Violating them can lead to subtle and painful bugs as explained &lt;a href="https://www.reddit.com/r/haskell/comments/16iakr/what_happens_when_a_monad_violates_monadic_laws/" class="pml-link"&gt;here&lt;/a&gt;, &lt;a href="https://stackoverflow.com/questions/12617664/a-simple-example-showing-that-io-doesnt-satisfy-the-monad-laws" class="pml-link"&gt;here&lt;/a&gt;, and &lt;a href="https://www.quora.com/What-would-be-the-practical-implications-if-an-implementation-of-Haskells-Monad-typeclass-didnt-satisfy-the-monadic-laws" class="pml-link"&gt;here&lt;/a&gt;. As far as I know, there is currently no compiler able to enforce the monad laws. Hence, it's the developer's responsibility to verify that the monad laws are respected. Suffice to say that the above &lt;code&gt;ResultOrErrorMonad&lt;/code&gt; fulfills the monad laws.&lt;/p&gt;

&lt;p&gt;Although we are done, there is still room for improvement.&lt;/p&gt;

&lt;h1&gt;
  
  
  Maximizing Reusability
&lt;/h1&gt;

&lt;p&gt;Besides having a type parameter for the result value, we could also add a type parameter for the error value. This makes the monad more reusable, because users of the monad are now free to decide which type of error they want to use. For an example you can look at F#'s &lt;a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/results" class="pml-link"&gt;Result&lt;/a&gt; type.&lt;/p&gt;

&lt;p&gt;Finally we could make the monad even more reusable by letting the user define the meaning of the two values. In our example, one value represents a result, and the other one represents an error. But we can abstract more. We can create a monad that simply holds one of two possible values - either value_1 or value_2. And the type of each value can be freely defined by a type parameter. This is indeed a standard monad supported by some functional programming languages. In Haskell it's called &lt;code&gt;Either&lt;/code&gt;. It's constructor is defined as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Either a b = Left a | Right b
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using our &lt;code&gt;ResultOrErrorMonad&lt;/code&gt; class as a starting point, it would be easy to create an &lt;code&gt;Either&lt;/code&gt; monad in Java.&lt;/p&gt;

&lt;p&gt;Note: Some projects use an &lt;code&gt;Either&lt;/code&gt; monad for functions that might fail. Im my opinion, using a more specific &lt;code&gt;ResultOrError&lt;/code&gt; type is a better, less error-prone option (for reasons not explained here).&lt;/p&gt;

&lt;h1&gt;
  
  
  An OO Bind
&lt;/h1&gt;

&lt;p&gt;Now that we know how a monad works in functional programming languages, let's go back to the world of OOP (object-oriented programming). Could we create something like an OO-monad?&lt;/p&gt;

&lt;p&gt;If we look at class ResultOrErrorMonad, we can see that everything in this class is already standard Java, with one exception: Function &lt;code&gt;bind&lt;/code&gt; is a static member of the class. This means we can't use the dot-syntax of object methods for &lt;code&gt;bind&lt;/code&gt;. Currently the syntax for calling &lt;code&gt;bind&lt;/code&gt; is &lt;code&gt;bind ( v, f )&lt;/code&gt;. But if &lt;code&gt;bind&lt;/code&gt; was a non-static member of the class, we could write &lt;code&gt;v.bind ( f )&lt;/code&gt;. This would make the syntax more readable in the case of nested function calls.&lt;/p&gt;

&lt;p&gt;Luckily, it's easy to make &lt;code&gt;bind&lt;/code&gt; non-static.&lt;/p&gt;

&lt;p&gt;To make the monad a bit more versatile, let's also introduce a second type parameter for error values. Then the users are not required to use &lt;code&gt;SimpleError&lt;/code&gt; - they can use their own error class.&lt;/p&gt;

&lt;p&gt;Here is the code of a &lt;code&gt;ResultOrError&lt;/code&gt; monad, OO-style:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ResultOrError&amp;lt;R, E&amp;gt; {

    private final R result;
    private final E error;

    private ResultOrError ( R result, E error ) {
        this.result = result;
        this.error = error;
    }

    public static &amp;lt;R, E&amp;gt; ResultOrError&amp;lt;R, E&amp;gt; createResult ( R result ) {
        return new ResultOrError&amp;lt;R, E&amp;gt; ( result, null );
    }

    public static &amp;lt;R, E&amp;gt; ResultOrError&amp;lt;R, E&amp;gt; createError ( E error ) {
        return new ResultOrError&amp;lt;R, E&amp;gt; ( null, error );
    }

    public R getResult() { return result; }

    public E getError() { return error; }

    public boolean isResult() { return error == null; }

    public boolean isError() { return error != null; }

    public &amp;lt;R2&amp;gt; ResultOrError&amp;lt;R2,E&amp;gt; bind ( Function&amp;lt;R, ResultOrError&amp;lt;R2,E&amp;gt;&amp;gt; function ) {

        if ( isResult() ) {
            return function.apply ( result );
        } else {
            return createError ( error );
        }
    }

    public String toString() {

        if ( isResult() ) {
            return "Result: " + result.toString(); 
        } else {
            return "Error: " + error.toString(); 
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the code for using bind in the body of function &lt;code&gt;enthuse&lt;/code&gt; becomes more readable. Instead of writing:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return bind ( bind ( trim ( sentence ), v -&amp;gt; toUpperCase(v) ), v -&amp;gt; appendExclam(v) );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... we can avoid the nesting and write:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return trim ( sentence ).bind ( v -&amp;gt; toUpperCase(v) ).bind ( v -&amp;gt; appendExclam(v) );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, can monads be useful in real-world OOP environments?&lt;/p&gt;

&lt;p&gt;Yes, they &lt;em&gt;can&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But the word "can" needs to be stressed, because it depends (as so often) on what we want to achieve. Let's say, for instance, that we have some good reasons to 'not use exceptions' for error handling.&lt;/p&gt;

&lt;p&gt;Remember the error-handling code we had to write in chapter Errors, But No Exceptions:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse ( String sentence ) {

    ResultOrError trimmed = trim ( sentence );
    if ( trimmed.isResult() ) {
        ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
        if ( upperCased.isResult() ) {
            return appendExclam ( upperCased.getResult() );
        } else {
            return upperCased;
        }
    } else {
        return trimmed;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using a monad removes the boilerplate:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static ResultOrError enthuse ( String sentence ) {
    return trim ( sentence ).bind ( v -&amp;gt; toUpperCase(v) ).bind ( v -&amp;gt; appendExclam(v) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Nice!&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The key to understanding monads is to understand &lt;code&gt;bind&lt;/code&gt; (also called &lt;code&gt;chain&lt;/code&gt;, &lt;code&gt;andThen&lt;/code&gt;, etc.). Function &lt;code&gt;bind&lt;/code&gt; is used to compose two monadic functions. A monadic function is a function that takes a value of type T and returns an object that contains the value (&lt;code&gt;a -&amp;gt; m a&lt;/code&gt;). Monadic functions cannot be directly composed because the output type of the first function called is not compatible to the input type of the second function. &lt;code&gt;bind&lt;/code&gt; solves this problem.&lt;/p&gt;

&lt;p&gt;Function &lt;code&gt;bind&lt;/code&gt; is useful on its own. But it's just one part of a monad.&lt;/p&gt;

&lt;p&gt;In Java-like world, a monad is a class (type) &lt;code&gt;M&lt;/code&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;a type parameter &lt;code&gt;T&lt;/code&gt; tat defines the type of the value stored in the monad (e.g. &lt;code&gt;M&amp;lt;T&amp;gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a constructor that takes a value of type &lt;code&gt;T&lt;/code&gt; and returns a monad &lt;code&gt;M&amp;lt;T&amp;gt;&lt;/code&gt; containing the value&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java-like languages: &lt;code&gt;M&amp;lt;T&amp;gt; create ( T value )&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Al4lxIfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vcfpfe3vrdhf5bg9w7xe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Al4lxIfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vcfpfe3vrdhf5bg9w7xe.png" alt="Function create"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Haskell: &lt;code&gt;return :: a -&amp;gt; m a&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;a &lt;code&gt;bind&lt;/code&gt; function used to compose two monadic functions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java-like languages: &lt;code&gt;M&amp;lt;T2&amp;gt; bind ( M&amp;lt;T1&amp;gt; monad, Function&amp;lt;T1, M&amp;lt;T2&amp;gt;&amp;gt; function )&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tTGCGz5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9krgtzzu5ni1b54gw3g5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tTGCGz5_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9krgtzzu5ni1b54gw3g5.png" alt="Generic bind function"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Haskell: &lt;code&gt;(&amp;gt;&amp;gt;=) :: m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A monad must respect three monad laws. These laws ensure that the monad behaves well in all situations.&lt;/p&gt;

&lt;p&gt;Monads are primarily used in functional programming languages, because these languages rely on function composition. But they can also be useful in the context of other paradigms, such as object-oriented programming languages that support generic types and higher order functions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Words
&lt;/h1&gt;

&lt;p&gt;As hinted in it's title, this article is an &lt;em&gt;introduction&lt;/em&gt; to monads. It doesn't cover the full spectrum of monads, it doesn't show other useful examples of monads (Maybe monad, IO monad, state monad, etc) and it completely ignores 'category theory', the mathematical background for monads. For those who want to know more, an abundance of information is already available on the net.&lt;/p&gt;

&lt;p&gt;Hopefully this article helps to get the gist of monads, see their beauty, and understand how they can improve code and simplify life.&lt;/p&gt;

&lt;p&gt;"HAPPY MONADING!"&lt;/p&gt;

&lt;p&gt;Note: The &lt;a href="https://www.ppl-lang.dev/blog/introduction-to-monads-with-java"&gt;original&lt;/a&gt; version of this article was written in &lt;a href="https://www.pml-lang.dev" class="pml-link"&gt;PML&lt;/a&gt; (Practical Markup Language). You can look at the PML code on &lt;a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/PML_source" class="pml-link"&gt;Gitlab&lt;/a&gt;. The source code examples used in this article are stored on &lt;a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/Java_examples/monadtests" class="pml-link"&gt;Gitlab&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>monad</category>
      <category>bind</category>
      <category>java</category>
      <category>functional</category>
    </item>
    <item>
      <title>Null-Safety vs Maybe/Option - A Thorough Comparison (Part 2/2)</title>
      <dc:creator>Christian Neumanns</dc:creator>
      <pubDate>Fri, 18 Oct 2019 13:28:09 +0000</pubDate>
      <link>https://dev.to/practicalprogramming/null-safety-vs-maybe-option-a-thorough-comparison-part-2-2-237n</link>
      <guid>https://dev.to/practicalprogramming/null-safety-vs-maybe-option-a-thorough-comparison-part-2-2-237n</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/practicalprogramming/null-safety-vs-maybe-option-a-thorough-comparison-part-1-jlk"&gt;part 1&lt;/a&gt; of this article we saw how the null pointer error can be eliminated with null-safety or with the Maybe/Option type.&lt;/p&gt;

&lt;p&gt;In this part we'll have a closer look at code snippets that illustrate frequent use cases of handling the 'absence of a value'.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Null-Handling Features
&lt;/h2&gt;

&lt;p&gt;Besides null-safety, a language should also provide specific support for common null handling operations. Let's have a look at some examples.&lt;/p&gt;

&lt;p&gt;Note: The additional support for null-handling presented in the following chapters is typically found only in null-safe languages. However, other languages can also provide these features, even if they are not null-safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Searching the First Non-Null Value
&lt;/h3&gt;

&lt;p&gt;Suppose we want to look up a discount for a customer. First we try to retrieve the value from a web-service. If the value is not available (i.e. the result is &lt;code&gt;null&lt;/code&gt;), we try to retrieve it from a database, then from a local cache. If the value is still &lt;code&gt;null&lt;/code&gt; we use a default value of 0.0.&lt;/p&gt;

&lt;p&gt;Now we want to write a function that provides the discount for a given customer. To keep the example simple, we ignore error-handling. Moreover, we don't use asynchronous functions to make the lookup process faster.&lt;/p&gt;

&lt;h4&gt;
  
  
  Java
&lt;/h4&gt;

&lt;p&gt;First attempt:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static Double customerDiscount ( String customerID ) {

    Double result = discountFromNet ( customerID );
    if ( result != null ) {
        return result;
    } else {
        result = discountFromDB ( customerID );
        if ( result != null ) {
            return result;
        } else {
            result = discountFromCache ( customerID );
            if ( result != null ) {
                return result;
            } else {
                return 0.0; // default value
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What an ugly monstrosity! Let's quickly rewrite it:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static Double customerDiscount ( String customerID ) {

    Double result = discountFromNet ( customerID );
    if ( result != null ) return result;

    result = discountFromDB ( customerID );
    if ( result != null ) return result;

    result = discountFromCache ( customerID );
    if ( result != null ) return result;

    return 0.0; // default value
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: There's nothing wrong with using several &lt;code&gt;return&lt;/code&gt; statement, as in the code above (although some people might disagree).&lt;/p&gt;

&lt;p&gt;The complete Java source code for a test application is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_first_non_null/Java/SearchFirstNonNullTest.java" class="pml-link"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Haskell
&lt;/h4&gt;

&lt;p&gt;Let's start again with the straightforward, but ugly version:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerDiscount :: String -&amp;gt; Float
customerDiscount customerID =
    case (discountFromNet customerID) of
    Just d -&amp;gt; d
    Nothing -&amp;gt; case (discountFromDB customerID) of
               Just d -&amp;gt; d
               Nothing -&amp;gt; case (discountFromCache customerID) of
                          Just d -&amp;gt; d
                          Nothing -&amp;gt; 0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are different ways to write better code. Here is one way:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerDiscount :: String -&amp;gt; Float
customerDiscount customerID =
    let discountMaybe = discountFromNet customerID
                        &amp;lt;|&amp;gt; discountFromDB customerID
                        &amp;lt;|&amp;gt; discountFromCache customerID
    in fromMaybe 0.0 discountMaybe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The complete Haskell source code for a test application, including alternative ways to write the above function, is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_first_non_null/Haskell/SearchFirstNonNullTest.hs" class="pml-link"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More information (and even more alternatives) can be found in the Stackoverflow question &lt;a href="https://stackoverflow.com/questions/5606228/using-the-maybe-monad-in-reverse" class="pml-link"&gt;Using the Maybe Monad in reverse&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  PPL
&lt;/h4&gt;

&lt;p&gt;Again, first the ugly version, written in &lt;a href="http://www.practical-programming.org"&gt;PPL&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_discount ( customer_id string ) -&amp;gt; float_64
    if discount_from_net ( customer_id ) as net_result is not null then
        return net_result
    else
        if discount_from_DB ( customer_id ) as DB_result is not null then
            return DB_result
        else
            if discount_from_cache ( customer_id ) as cache_result is not null then
                return cache_result
            else
                return 0.0
            .
        .
    .
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The code becomes a one-liner and more readable with the practical &lt;code&gt;if_null:&lt;/code&gt; operator designed for this common use case:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_discount ( customer_id string ) -&amp;gt; float_64 = \
    discount_from_net ( customer_id ) \
    if_null: discount_from_DB ( customer_id ) \
    if_null: discount_from_cache ( customer_id ) \
    if_null: 0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;if_null:&lt;/code&gt; operator works like this: It evaluates the expression on the left. If the result is non-null, it returns that result. Else it returns the expression on the right.&lt;/p&gt;

&lt;p&gt;In our example we use a chain of &lt;code&gt;if_null:&lt;/code&gt; operators to find the first non-null value. If the three functions called in the expression return &lt;code&gt;null&lt;/code&gt;, we return the default value &lt;code&gt;0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The complete PPL source code for a test application is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_first_non_null/PPL/search_first_non_null_test.ppl" class="pml-link"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting a Value in a Path With Nulls
&lt;/h3&gt;

&lt;p&gt;Sometimes we need to do the opposite of what we did in the previous chapter. Instead of stopping at the first non-null value, we continue until we've found the last non-null value.&lt;/p&gt;

&lt;p&gt;For example, suppose a &lt;code&gt;customer&lt;/code&gt; record type with two attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;name&lt;/code&gt;: a non-null string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;address&lt;/code&gt;: a nullable address&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Record type &lt;code&gt;address&lt;/code&gt; is defined as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;city&lt;/code&gt;: a nullable string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;country&lt;/code&gt;: a non-null string&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we want to create a function that takes a customer as input, and returns the number of characters in the customer's city. If the customer's address attribute is &lt;code&gt;null&lt;/code&gt;, or if the address's &lt;code&gt;city&lt;/code&gt; attribute is &lt;code&gt;null&lt;/code&gt; then the function should return 0.&lt;/p&gt;

&lt;h4&gt;
  
  
  Java
&lt;/h4&gt;

&lt;p&gt;These are the record types written in idiomatic Java:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static class Customer {

    private final String name;
    private final Address address;

    public Customer ( String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public String getName() { return name; }
    public Address getAddress() { return address; }
}

static class Address {

    private final String city;
    private final String country;

    public Address ( String city, String country) {
        this.city = city;
        this.country = country;
    }

    public String getCity() { return city; }
    public String getCountry() { return country; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: We don't use setters because we want our types to be immutable.&lt;/p&gt;

&lt;p&gt;As seen already, all types are nullable in Java. We cannot explicitly specify if &lt;code&gt;null&lt;/code&gt; is allowed for class fields.&lt;/p&gt;

&lt;p&gt;Function (method) &lt;code&gt;customerCitySize&lt;/code&gt; can be implemented as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static Integer customerCitySize ( Customer customer ) {

    Address address = customer.getAddress();
    if ( address == null ) return 0;

    String city = address.getCity();
    if ( city == null ) return 0;

    return city.length();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternatively we could have used nested if statements, but the above version is more readable and avoids the complexity of nested statements.&lt;/p&gt;

&lt;p&gt;We can write a simplistic test:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main ( String[] args ) {

    // city is non-null
    Address address = new Address ( "Orlando", "USA" );
    Customer customer = new Customer ( "Foo", address );
    System.out.println ( customerCitySize ( customer ) );

    // city is null
    address = new Address ( null, "USA" );
    customer = new Customer ( "Foo", address );
    System.out.println ( customerCitySize ( customer ) );

    // address is null
    customer = new Customer ( "Foo", null );
    System.out.println ( customerCitySize ( customer ) );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7
0
0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The whole Java source code is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_last_non_null/Java/SearchLastNonNullTest.java" class="pml-link"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Haskell
&lt;/h4&gt;

&lt;p&gt;Defining the record types is easy:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Customer = Customer {
    name :: String,
    address :: Maybe Address
}

data Address = Address { 
    city :: Maybe String,
    country :: String 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are several ways to write function &lt;code&gt;customerCitySize&lt;/code&gt; in Haskell. Here is, I think, the most readable one for people more familiar with imperative programming. It uses the do notation:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Data.Maybe (fromMaybe)

customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    let sizeMaybe = do
        address &amp;lt;- address customer        -- type Address
        city &amp;lt;- city address               -- type String
        return $ length city               -- type Maybe Int
    in fromMaybe 0 sizeMaybe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here is a version that doesn't use the do notation:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    let addressMaybe = address customer    -- type Maybe Address
        cityMaybe = addressMaybe &amp;gt;&amp;gt;= city  -- type Maybe String
        sizeMaybe = length &amp;lt;$&amp;gt; cityMaybe   -- type Maybe Int
    in fromMaybe 0 sizeMaybe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If we are careful with operator precedence, we can shorten the code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    fromMaybe 0 $ length &amp;lt;$&amp;gt; (address customer &amp;gt;&amp;gt;= city)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Instead of using &lt;code&gt;fromMaybe&lt;/code&gt; we can use &lt;code&gt;maybe&lt;/code&gt; to provide the default value:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    maybe 0 length $ address customer &amp;gt;&amp;gt;= city
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Yes, this code is concise. But there is a lot going on behind the scenes. &lt;em&gt;A looooot!&lt;/em&gt;. To really understand the above code one has to understand Haskell. And yes, we use a monad, indicated by the bind operator &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; in the code. For more information please refer to Haskell's documentation.&lt;/p&gt;

&lt;p&gt;We can write a quick test:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main :: IO ()
main = do

    -- city is defined
    let address1 = Address {city = Just "Orlando", country = "USA"}
    let customer1 = Customer {name = "Foo", address = Just address1}
    putStrLn $ show $ customerCitySize customer1

    -- city is not defined
    let address2 = Address {city = Nothing, country = "USA"}
    let customer2 = Customer {name = "Foo", address = Just address2}
    putStrLn $ show $ customerCitySize customer2

    -- address is not defined
    let customer3 = Customer {name = "Foo", address = Nothing}
    putStrLn $ show $ customerCitySize customer3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, the output is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7
0
0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The whole Haskell source code is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_last_non_null/Haskell/SearchLastNonNullTest.hs" class="pml-link"&gt;here&lt;/a&gt;. There are also two examples of &lt;code&gt;customerCitySize&lt;/code&gt; implementations that compile without errors, but produce wrong results.&lt;/p&gt;

&lt;h4&gt;
  
  
  PPL
&lt;/h4&gt;

&lt;p&gt;First, the record types:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record type customer
    attributes
        name string
        address address or null
    .
.

record type address
    attributes
        city string or null
        country string
    .
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Function &lt;code&gt;customerCitySize&lt;/code&gt; is written like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_city_size ( customer ) -&amp;gt; zero_pos_32 =
    customer.address.null?.city.null?.size if_null: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the embedded &lt;code&gt;null?&lt;/code&gt; checks. The evaluation of &lt;code&gt;customer.address.null?.city.null?.size&lt;/code&gt; stops as soon as a &lt;code&gt;null&lt;/code&gt; is detected in the chain. In that case, the whole expression evaluates to &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;if_null:&lt;/code&gt; operator is used to return the default value &lt;code&gt;0&lt;/code&gt; if the expression on the left evaluates to &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;.null?.&lt;/code&gt; we can also simply write &lt;code&gt;?.&lt;/code&gt;. Hence the function can be shortened to:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_city_size ( customer ) -&amp;gt; zero_pos_32 =
    customer.address?.city?.size if_null: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Simple test code looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function start

    // city is non-null
    const address1 = address.create ( city = "Orlando", country = "USA" )
    const customer1 = customer.create ( name = "Foo", address = address1 )
    write_line ( customer_city_size ( customer1 ).to_string )

    // city is null
    const address2 = address.create ( city = null, country = "USA" )
    const customer2 = customer.create ( name = "Foo", address = address2 )
    write_line ( customer_city_size ( customer2 ).to_string )

    // address is null
    const customer3 = customer.create ( name = "Foo", address = null )
    write_line ( customer_city_size ( customer3 ).to_string )
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7
0
0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The whole PPL source code is available &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/search_last_non_null/PPL/search_last_non_null_test.ppl" class="pml-link"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Comparison
&lt;/h4&gt;

&lt;p&gt;Here is a copy of the three implementations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static Integer customerCitySize ( Customer customer ) {

    Address address = customer.getAddress();
    if ( address == null ) return 0;

    String city = address.getCity();
    if ( city == null ) return 0;

    return city.length();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Haskell&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    maybe 0 length $ address customer &amp;gt;&amp;gt;= city
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PPL&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_city_size ( customer ) -&amp;gt; zero_pos_32 =
    customer.address?.city?.size if_null: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Comparisons
&lt;/h1&gt;

&lt;p&gt;Now that we know how the null pointer error is eliminated, let us look at some differences between using the &lt;code&gt;Maybe&lt;/code&gt; monad in Haskell and null-safety in PPL.&lt;/p&gt;

&lt;p&gt;Note: The following discussion is based on the Haskell and PPL examples shown in the previous chapters. Hence, some of the following observations are not valid in other languages that work in a similar way. For example, F#'s &lt;code&gt;Option&lt;/code&gt; type is very similar to Haskell's &lt;code&gt;Maybe&lt;/code&gt; type, but these two languages are far from being the same. Reader comments about other languages are of course very welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;Here is a summary of the differences we saw in the source code examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Declaring the type of a nullable reference
&lt;/h3&gt;

&lt;p&gt;Haskell: &lt;code&gt;Maybe string&lt;/code&gt; (other languages use &lt;code&gt;Option&lt;/code&gt; or &lt;code&gt;Optional&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;PPL: &lt;code&gt;string or null&lt;/code&gt; (other languages use &lt;code&gt;string?&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;As seen already, the difference between Haskell and PPL is not just syntax. Both use different concepts.&lt;/p&gt;

&lt;p&gt;Haskell uses the &lt;code&gt;Maybe&lt;/code&gt; type with a generic type parameter. Form the Haskell doc.: "A value of type Maybe a either contains a value of type a (represented as Just a), or it is empty (represented as Nothing). The Maybe type is also a monad."&lt;/p&gt;

&lt;p&gt;On the other hand, PPL uses union types to state that a value is either a specific type, or &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A non-null value used for a nullable type
&lt;/h3&gt;

&lt;p&gt;Haskell: &lt;code&gt;Just "qwe"&lt;/code&gt; (other languages: &lt;code&gt;Some "qwe"&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;PPL: &lt;code&gt;"qwe"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This difference is important!&lt;/p&gt;

&lt;p&gt;In Haskell &lt;code&gt;"qwe"&lt;/code&gt; is not type compatible to &lt;code&gt;Just "qwe"&lt;/code&gt;. Suppose the following function signature:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo :: Maybe String -&amp;gt; String
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function can be called as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo $ Just "qwe"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But a compiler error arises if we try to call it like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo "qwe"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are a few consequences to be aware of.&lt;/p&gt;

&lt;p&gt;First, if a type changes from &lt;code&gt;Maybe T&lt;/code&gt; to &lt;code&gt;T&lt;/code&gt;, then all occurrences of &lt;code&gt;Just expression&lt;/code&gt; must be changed to &lt;code&gt;expression&lt;/code&gt;. The inverse is true too. A change from type &lt;code&gt;T&lt;/code&gt; to &lt;code&gt;Maybe T&lt;/code&gt; requires all occurrences of &lt;code&gt;expression&lt;/code&gt; to be refactored to &lt;code&gt;Just expression&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is not the case in PPL. An expression of type &lt;code&gt;string&lt;/code&gt; is type-compatible to an expression of &lt;code&gt;string or null&lt;/code&gt; (but the inverse is not true). For example, the function ...&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo ( s string or null ) -&amp;gt; string
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... can be called like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo ( "qwe" )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the function is later refactored to ...&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo ( s string ) -&amp;gt; string
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... then it can still be called with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foo ( "qwe" )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Secondly, in Haskell some functions with the same name might exist for input type &lt;code&gt;Maybe T&lt;/code&gt;, as well as for input &lt;code&gt;T&lt;/code&gt;. But the semantics are different. For example, &lt;code&gt;length "qwe"&lt;/code&gt; returns 3 in Haskell, while &lt;code&gt;length $ Just "qwe"&lt;/code&gt; returns 1. It is important to be aware of this, because there is no compile-time error if function &lt;code&gt;length&lt;/code&gt; is used for an expression whose type changes from &lt;code&gt;Maybe T&lt;/code&gt; to &lt;code&gt;T&lt;/code&gt; or vice-versa.&lt;/p&gt;

&lt;p&gt;Thirdly, one has to be aware of the possibility of nested &lt;code&gt;Maybe&lt;/code&gt;s in Haskell. For example, suppose again we declare:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Customer = Customer {
    name :: String,
    address :: Maybe Address
}

data Address = Address { 
    city :: Maybe String,
    country :: String 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What is the return type of the following function?&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCity customer = city &amp;lt;$&amp;gt; address customer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Is it &lt;code&gt;Maybe string&lt;/code&gt;. No, it's &lt;code&gt;Maybe ( Maybe string )&lt;/code&gt; - a nested &lt;code&gt;Maybe&lt;/code&gt;. Ignoring this can lead to subtle bugs. For an interesting discussion see the Stackoverflow question &lt;a href="https://stackoverflow.com/questions/19655870/simplifying-nested-maybe-pattern-matching" class="pml-link"&gt;Simplifying nested Maybe pattern matching&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  'No value' symbol
&lt;/h3&gt;

&lt;p&gt;Haskell: &lt;code&gt;Nothing&lt;/code&gt; (other languages: &lt;code&gt;None&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;PPL: &lt;code&gt;null&lt;/code&gt; (other languages: &lt;code&gt;nil&lt;/code&gt;, &lt;code&gt;void&lt;/code&gt;, ...)&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking for null
&lt;/h3&gt;

&lt;p&gt;Haskell (one way to do it):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Maybe Integer -&amp;gt; Maybe String
intToString i = case i of
    Just 1  -&amp;gt; Just "one"
    Nothing -&amp;gt; Nothing
    _       -&amp;gt; Just "not one"            
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: Omitting the &lt;code&gt;Nothing&lt;/code&gt; case does not produce a compiler error. Instead, the function returns &lt;code&gt;Just "not one"&lt;/code&gt; if it is called with &lt;code&gt;Nothing&lt;/code&gt; as input.&lt;/p&gt;

&lt;p&gt;PPL (new version):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null = \
    case value of i
        when null: null
        when 1   : "one"
        otherwise: "not one"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: Omitting the &lt;code&gt;when null&lt;/code&gt; case results in the following compiler error:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clause 'when null' is required because the case expression might be null at run-time.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Providing a default non-null value
&lt;/h3&gt;

&lt;p&gt;Haskell: &lt;code&gt;fromMaybe 0 size&lt;/code&gt; (requires Data.Maybe; F#: &lt;code&gt;defaultArg 0 size&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;PPL: &lt;code&gt;size if_null: 0&lt;/code&gt; (other languages: &lt;code&gt;size ?: 0&lt;/code&gt;, ( &lt;code&gt;?:&lt;/code&gt; is sometimes called 'Elvis operator')&lt;/p&gt;
&lt;h3&gt;
  
  
  Getting the first non-null value in a chain, or else a default value
&lt;/h3&gt;

&lt;p&gt;Haskell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerDiscount :: String -&amp;gt; Float
customerDiscount customerID =
    let discountMaybe = discountFromNet customerID
                        &amp;lt;|&amp;gt; discountFromDB customerID
                        &amp;lt;|&amp;gt; discountFromCache customerID
    in fromMaybe 0.0 discountMaybe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;PPL:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_discount ( customer_id string ) -&amp;gt; float_64 = \
    discount_from_net ( customer_id ) \
    if_null: discount_from_DB ( customer_id ) \
    if_null: discount_from_cache ( customer_id ) \
    if_null: 0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Getting the last value in a chain, or else a default value
&lt;/h3&gt;

&lt;p&gt;Haskell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customerCitySize :: Customer -&amp;gt; Int
customerCitySize customer =
    maybe 0 length $ address customer &amp;gt;&amp;gt;= city
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;PPL:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function customer_city_size ( customer ) -&amp;gt; zero_pos_32 =&lt;br&gt;
    customer.address?.city?.size if_null: 0&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Implementation&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Back in 1965, Tony Hoare introduced &lt;code&gt;null&lt;/code&gt; in ALGOL "simply because it was so easy to implement", as he said.&lt;/p&gt;

&lt;p&gt;In Java, and probably most other programming languages, &lt;code&gt;null&lt;/code&gt; is implemented by simply using the value &lt;code&gt;0&lt;/code&gt; for a reference. That is to say, if we write something like &lt;code&gt;name = "Bob"&lt;/code&gt;, then the memory address used for variable &lt;code&gt;name&lt;/code&gt; contains the starting address of the memory block that stores the string value &lt;code&gt;"Bob"&lt;/code&gt;. On the other hand, when &lt;code&gt;name = null&lt;/code&gt; is executed, then the content of the memory address used for variable &lt;code&gt;name&lt;/code&gt; is set to &lt;code&gt;0&lt;/code&gt; (i.e. all bits set to zero). Easy and efficient, indeed!&lt;/p&gt;

&lt;p&gt;A more thorough explanation is available in chapter &lt;em&gt;Run-time Implementation&lt;/em&gt; of my article &lt;a href="http://www.practical-programming.org/blog/meaning-of-null/index.html" class="pml-link"&gt;A quick and thorough guide to 'null'&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, implementing &lt;code&gt;null&lt;/code&gt; is easy. However, adding null-&lt;em&gt;safety&lt;/em&gt; to a language is a totally different story. Implementing compile-time-null-safety in a practical way is far from being easy. Adding good support to simplify null-handling as far as possible is a challenge. Adding null-safety and good support for null-handling makes life more difficult for language &lt;em&gt;creators&lt;/em&gt;, but much easier for language &lt;em&gt;users&lt;/em&gt; (i.e. software developers). This doesn't come as a surprise, though. It's just a frequently observed fact of life:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is easy to make it difficult to use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is difficult to make it easy to use.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, a type like &lt;code&gt;Maybe&lt;/code&gt; can simply be added to the language's standard library, without the need for special support in the language.&lt;/p&gt;

&lt;p&gt;In he case of Haskell, &lt;code&gt;Maybe&lt;/code&gt; is a monad in the standard prelude, and Haskell's standard functional programming features are used to handle &lt;code&gt;Maybe&lt;/code&gt; values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Space and Time
&lt;/h2&gt;

&lt;p&gt;Let's starts with &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are just two kinds of basic operations needed at run-time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Assign &lt;code&gt;null&lt;/code&gt; to a reference (e.g. &lt;code&gt;name = null&lt;/code&gt;): this is typically done by just writing &lt;code&gt;0&lt;/code&gt; to a memory cell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if a reference points to &lt;code&gt;null&lt;/code&gt; (e.g. &lt;code&gt;if name is null&lt;/code&gt;): this is very quickly done by just comparing the content of a memory cell with &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The conclusion is obvious: &lt;code&gt;null&lt;/code&gt; operations are extremely space- and time-efficient.&lt;/p&gt;

&lt;p&gt;On the other hand, using a wrapper type is probably less efficient, unless the compiler uses very clever optimizations.&lt;/p&gt;

&lt;p&gt;As a general observation, it is probably fair to say that, for a given language, using a wrapper type cannot be made &lt;em&gt;faster&lt;/em&gt; than using 0 for a &lt;code&gt;null&lt;/code&gt; reference.&lt;/p&gt;

&lt;p&gt;In practice, however, the performance difference might not be an issue in many kinds of applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Note On The "Billion Dollar Mistake"
&lt;/h1&gt;

&lt;p&gt;Yes, Tony Hoare stated that &lt;code&gt;null&lt;/code&gt; has "probably caused a billion dollars of pain and damage in the last forty years".&lt;/p&gt;

&lt;p&gt;However, a few seconds later he &lt;a href="https://everythingsysadmin.com/2009/01/tony-hoare-apologizes-for-inve.html" class="pml-link"&gt;said&lt;/a&gt; the following, which is really important, but often ignored:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;More recent programming languages like Spec# have introduced declarations for non-null references. This is the solution, which I rejected in 1965.&lt;/p&gt;

&lt;p&gt;-- Tony Hoare&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The mistake was not the invention of null per se. The mistake was the &lt;em&gt;lack of compile-time-null-safety and good support for null-handling&lt;/em&gt; in programming languages.&lt;/p&gt;

&lt;p&gt;As seen in this article it &lt;em&gt;is&lt;/em&gt; possible to eliminate the null pointer error in languages that use &lt;code&gt;null&lt;/code&gt;. No "billion-dollar mistake" anymore!&lt;/p&gt;

&lt;p&gt;Isn't it amazing that it took the software development industry over 40 years to recognize this and start creating null-safe languages?&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Here is a summary of the key points:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java (and most other popular programming languages)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All reference types are nullable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;null&lt;/code&gt; can be assigned to any reference (variable, input argument, function return value, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no protection against null pointer errors. They occur frequently and are the reason for the &lt;em&gt;billion-dollar mistake&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Haskell (and some other programming languages using Maybe/Option)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;null&lt;/code&gt; is not supported. Hence null pointer errors cannot occur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Maybe&lt;/code&gt; type (a monad with a type parameter) is used to manage the 'absence of a value'.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pattern matching is used to test for &lt;code&gt;Nothing&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Standard language features are used to handle &lt;code&gt;Maybe&lt;/code&gt; values (e.g. the monad's &lt;code&gt;bind&lt;/code&gt; operator &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PPL (and some other null-safe programming languages)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;By default all reference types are non-nullable and &lt;code&gt;null&lt;/code&gt; cannot be assigned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;null&lt;/code&gt; is an ordinary type with the single value &lt;code&gt;null&lt;/code&gt;. Union types are used to handle the 'absence of a value' (e.g. &lt;code&gt;string or null&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The compiler ensures a &lt;code&gt;null&lt;/code&gt;-check is done before executing an operation on a nullable type. Thus null pointer errors cannot occur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The language provides specific support to simplify &lt;code&gt;null&lt;/code&gt;-handling as far as possible. Null-handling code is concise, and easy to read and write.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The aim of this article was to compare null-safety in PPL with the &lt;code&gt;Maybe&lt;/code&gt; type in Haskell. We did this by looking at a number of representative source code examples.&lt;/p&gt;

&lt;p&gt;By comparing two languages, we must of course be careful not to generalize our observations to all other languages.&lt;/p&gt;

&lt;p&gt;However, in the context of this article we saw that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Null-safety, as well as the &lt;code&gt;Maybe&lt;/code&gt; type eliminate the null pointer error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using the &lt;code&gt;Maybe/Optional&lt;/code&gt; type is easier to implement in a language than null-safety. It &lt;em&gt;simplifies life for language designers and implementers&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Providing good support for null-safety is a challenge for language creators. However, it &lt;em&gt;simplifies life for developers&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Header image by &lt;a href="https://pixabay.com/users/dailyprinciples-3836461/"&gt;dailyprinciples&lt;/a&gt; from &lt;a href="https://pixabay.com"&gt;Pixabay&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>null</category>
      <category>maybe</category>
      <category>option</category>
    </item>
    <item>
      <title>Null-Safety vs Maybe/Option - A Thorough Comparison (Part 1/2)</title>
      <dc:creator>Christian Neumanns</dc:creator>
      <pubDate>Wed, 02 Oct 2019 12:15:53 +0000</pubDate>
      <link>https://dev.to/practicalprogramming/null-safety-vs-maybe-option-a-thorough-comparison-part-1-jlk</link>
      <guid>https://dev.to/practicalprogramming/null-safety-vs-maybe-option-a-thorough-comparison-part-1-jlk</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;There are two effective approaches to eliminate the daunting null pointer error:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Maybe/Option pattern - mostly used in functional programming languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compile-time null-safety - used in some modern programming languages.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article aims to answer the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How does it work? How do these two approaches eliminate the null pointer error?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How are they used in practice?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do they differ?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Readers not familiar with the concept of &lt;code&gt;null&lt;/code&gt; might want to read first: &lt;a href="http://www.practical-programming.org/blog/meaning-of-null/index.html" class="pml-link"&gt;A quick and thorough guide to 'null'&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For an introduction to &lt;code&gt;Maybe / Option&lt;/code&gt; I recommend: &lt;a href="https://fsharpforfunandprofit.com/posts/the-option-type/" class="pml-link"&gt;F#: The Option type&lt;/a&gt;. You can also search the net for "haskell maybe" or "f# option".&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Why Should We Care?
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;"I call it my billion-dollar mistake. It was the invention of the null reference in 1965. ... This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. ..."&lt;/p&gt;

&lt;p&gt;-- Tony Hoare&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the context of Java, Professor John Sargeant from the Manchester school of computer science puts it like &lt;a href="http://www.cs.man.ac.uk/~johns/npe.html" class="pml-link"&gt;this&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Of the things which can go wrong at runtime in Java programs, null pointer exceptions are by far the most common."&lt;/p&gt;

&lt;p&gt;-- John Sargeant&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can easily deduce:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"By eliminating the infamous null pointer error, we &lt;strong&gt;eliminate one of the most frequent reasons for software failures&lt;/strong&gt;."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a big deal!&lt;/p&gt;

&lt;p&gt;We should care about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Three Approaches
&lt;/h1&gt;

&lt;p&gt;Besides showing the &lt;em&gt;reason&lt;/em&gt; for the null pointer error, this article also aims to demonstrate how the null pointer error can be &lt;em&gt;eliminated&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We will therefore compare three different approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The language uses &lt;code&gt;null&lt;/code&gt;, but doesn't provide null-safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In these languages null pointer errors occur frequently.&lt;/p&gt;

&lt;p&gt;Most popular languages fall into this category. For example: C, C++, Java, Javascript, PHP, Python, Ruby, Visual Basic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The language doesn't support &lt;code&gt;null&lt;/code&gt;, but uses &lt;code&gt;Maybe&lt;/code&gt; (also called &lt;code&gt;Option&lt;/code&gt; or &lt;code&gt;Optional&lt;/code&gt;) to represent the 'absence of a value'&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;null&lt;/code&gt; is not supported, there are no null pointer errors.&lt;/p&gt;

&lt;p&gt;This approach is mostly used in some functional programming languages. But it can as well be used in non-functional languages.&lt;/p&gt;

&lt;p&gt;At the time of writing, the most prominent languages using this approach are probably Haskell, F#, and Swift.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The language uses null and provides compile-time-null-safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Null pointer errors cannot occur.&lt;/p&gt;

&lt;p&gt;Some modern languages support this approach.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Source Code Examples
&lt;/h1&gt;

&lt;p&gt;In this chapter we'll look at some source code examples of common use cases involving 'the absence of a value'. We will compare the code written in the three following languages representing the three approaches mentioned in the previous chapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java (supports null, but not null-safe)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Java_(programming_language)" class="pml-link"&gt;Java&lt;/a&gt; is one of the industry's leading languages, and one of the most successful ones in the history of programming languages. But it isn't null-safe. Hence, it is well suited to demonstrate the problem of the null pointer error.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Haskell (Maybe type)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Haskell_(programming_language)" class="pml-link"&gt;Haskell&lt;/a&gt; is the most famous one in the category of pure functional languages. It doesn't support &lt;code&gt;null&lt;/code&gt;. Instead it uses the &lt;code&gt;Maybe&lt;/code&gt; monad to represent the 'absence of a value'.&lt;/p&gt;

&lt;p&gt;Note: I am by no means a Haskell expert. If you see any mistake or need for improvement in the following examples, then please leave a comment so that the article can be updated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PPL (supports null and is null-safe)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.practical-programming.org/" class="pml-link"&gt;Practical Programming Language&lt;/a&gt; (PPL) supports &lt;code&gt;null&lt;/code&gt; and has been designed with full support for compile-time-null-safety from the ground up. However, be warned! PPL is just a &lt;em&gt;work in progress&lt;/em&gt;, not ready yet to write mission-critical enterprise applications. I use it in this article because (full disclosure!) I am the creator of PPL, and I want to initiate some interest for it. I hope you don't mind - after reading this article.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All source code examples are available on &lt;a href="https://github.com/pp-articles/null_vs_maybe/tree/master/examples/" class="pml-link"&gt;Github&lt;/a&gt;. The Github source code files contain alternative solutions for some examples, not shown in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Null-Safety
&lt;/h2&gt;

&lt;p&gt;How does null-safety work in practice? Let's see.&lt;/p&gt;

&lt;h3&gt;
  
  
  Null Not Allowed
&lt;/h3&gt;

&lt;p&gt;We start with an example of code where &lt;code&gt;null&lt;/code&gt; is &lt;em&gt;not allowed&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Say we want to write a very simple function that takes a positive integer and returns a string. Neither the input nor the output can be &lt;code&gt;null&lt;/code&gt;. If the input value is 1, we return "one". If it is not 1, we return "not one". How does the code look like in the three languages? And, more importantly, how safe is it?&lt;/p&gt;

&lt;h4&gt;
  
  
  Java
&lt;/h4&gt;

&lt;p&gt;This is the function written in Java:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    if ( i == 1 ) {
        return "one";
    } else {
        return "not one";
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can use the ternary operator and shorten the code a bit:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    return i == 1 ? "one" : "not one";
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: I am using type &lt;code&gt;Integer&lt;/code&gt;, which is a &lt;em&gt;reference&lt;/em&gt; type. I am not using type &lt;code&gt;int&lt;/code&gt;, which is a &lt;em&gt;value&lt;/em&gt; type. The reason is that &lt;code&gt;null&lt;/code&gt; works only with reference types.&lt;/p&gt;

&lt;p&gt;To test the code, we can write a simple Java application like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class NullNotAllowedTest {

    static String intToString ( Integer i ) {
        return i == 1 ? "one" : "not one";
    }

    public static void main ( String[] args ) {
        System.out.println ( intToString ( 1 ) );
        System.out.println ( intToString ( 2 ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to try out this code you can use an online Java Executor like &lt;a href="https://www.tutorialspoint.com/compile_java_online.php" class="pml-link"&gt;this one&lt;/a&gt;. Just copy/paste the above code in the &lt;code&gt;Source File&lt;/code&gt; tab, and click &lt;code&gt;Execute&lt;/code&gt;. It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zxqVpc8L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4pirh5nujw6mevx1t5tp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zxqVpc8L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4pirh5nujw6mevx1t5tp.png" alt="Java null not allowed test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have Java installed on your system, you can also proceed like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Save the above code in file &lt;code&gt;NullNotAllowedTest.java&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compile and run it by typing the following two commands in a terminal:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javac NullNotAllowedTest.java
java NullNotAllowedTest
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output written to the OS out device is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one
not one
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So far so good.&lt;/p&gt;

&lt;h4&gt;
  
  
  Haskell
&lt;/h4&gt;

&lt;p&gt;In Haskell, there are a few ways to write the function. For example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Integer -&amp;gt; String
intToString i = case i of
    1 -&amp;gt; "one"
    _ -&amp;gt; "not one"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: The first line in the above code could be omitted, because Haskell supports type inference for function arguments. However, it's considered &lt;a href="https://wiki.haskell.org/Type_signatures_as_good_style" class="pml-link"&gt;good style&lt;/a&gt; to include the type signature, because it makes the code more readable. Hence, we will always include the type signature in the upcoming Haskell examples.&lt;/p&gt;

&lt;p&gt;The above code uses pattern matching, which is the idiomatic way to write code in Haskell.&lt;/p&gt;

&lt;p&gt;We can write a simple Haskell application to test the code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Integer -&amp;gt; String
intToString i = case i of
    1 -&amp;gt; "one"
    _ -&amp;gt; "not one"

main :: IO ()
main = do
    putStrLn $ intToString 1
    putStrLn $ intToString 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As for Java, you can use an &lt;a href="https://www.tutorialspoint.com/compile_haskell_online.php" class="pml-link"&gt;online Haskell executor&lt;/a&gt; to try out the code. Here is a screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zrK4N1cO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tjle5ac1tpvcv02jrwov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zrK4N1cO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tjle5ac1tpvcv02jrwov.png" alt="Haskell nothing not allowed test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, if Haskell is installed on your system, you can save the above code in file &lt;code&gt;NothingNotAllowedTest.hs&lt;/code&gt;. Then you can compile and run it with these two commands:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ghc -o NothingNotAllowedTest NothingNotAllowedTest.hs
NothingNotAllowedTest.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output is the same as in the Java version:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one
not one
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  PPL
&lt;/h4&gt;

&lt;p&gt;In PPL the function can be written like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 ) -&amp;gt; string
    if i =v 1 then
        return "one"
    else
        return "not one"
    .
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: The comparison operator &lt;code&gt;=v&lt;/code&gt; in the above code is suffixed with a &lt;code&gt;v&lt;/code&gt; to make it clear we are comparing &lt;strong&gt;v&lt;/strong&gt;alues. If we wanted to compare references, we would use operator &lt;code&gt;=r&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can shorten the code by using an if-then-else &lt;em&gt;expression&lt;/em&gt; (instead of an if-then-else &lt;em&gt;statement&lt;/em&gt;):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 ) -&amp;gt; string = \
    if i =v 1 then "one" else "not one"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A simple PPL application to test the code looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 ) -&amp;gt; string = \
    if i =v 1 then "one" else "not one"

function start
    write_line ( int_to_string ( 1 ) )
    write_line ( int_to_string ( 2 ) )
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At the time of writing there is no online PPL executor available. To try out code you have to &lt;a href="http://www.practical-programming.org/ppl/downloads/install_PPL.html" class="pml-link"&gt;install PPL&lt;/a&gt; and then proceed like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Save the above code in file &lt;code&gt;null_not_allowed_test.ppl&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compile and run the code in a terminal by typing:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ppl null_not_allowed_test.ppl
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, the output is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;one
not one
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  Discussion
&lt;/h4&gt;

&lt;p&gt;As we have seen (and expected), the three languages allow us to write 'code that works correctly'. Here is a reprint of the three versions, so that you can easily compare the three versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    return i == 1 ? "one" : "not one";
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Haskell&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Integer -&amp;gt; String
intToString i = case i of
    1 -&amp;gt; "one"
    _ -&amp;gt; "not one"
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PPL&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 ) -&amp;gt; string = \
    if i =v 1 then "one" else "not one"
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A pivotal question remains unanswered:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What happens in case of a bug in the source code?"&lt;/p&gt;

&lt;p&gt;-- The Crucial Question&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the context of this article we want to know: What happens if the function is called with &lt;code&gt;null&lt;/code&gt; as input? And what if the function returns &lt;code&gt;null&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;This question is easy to answer in the Haskell world. &lt;code&gt;null&lt;/code&gt; doesn't exist in Haskell. Haskell uses the &lt;code&gt;Maybe&lt;/code&gt; monad to represent the 'absence of a value'. We will soon see how this works. Hence, in Haskell it is not possible to call &lt;code&gt;intToString&lt;/code&gt; with a &lt;code&gt;null&lt;/code&gt; as input. And we can't write code that returns &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;PPL supports &lt;code&gt;null&lt;/code&gt;, unlike Haskell. However, all types are &lt;em&gt;non-null by default&lt;/em&gt;. This is a fundamental rule in all effective null-safe languages. A PPL function with the type signature &lt;code&gt;pos_32 -&amp;gt; string&lt;/code&gt; states that the function cannot be called with &lt;code&gt;null&lt;/code&gt; as input, and it cannot return &lt;code&gt;null&lt;/code&gt;. This is enforced at &lt;code&gt;compile-time&lt;/code&gt;, so we are on the safe side. Code like &lt;code&gt;int_to_string ( null )&lt;/code&gt; simply doesn't compile.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"By default all types are &lt;em&gt;non-null&lt;/em&gt; in a null-safe language."&lt;/p&gt;

&lt;p&gt;"By default it is illegal to assign &lt;code&gt;null&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;-- The 'non-null by default' rule&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What about Java?&lt;/p&gt;

&lt;p&gt;Java is not null-safe. Every type is &lt;em&gt;nullable&lt;/em&gt;, and there is no way to specify a non-null type for a reference. This means that &lt;code&gt;intToString&lt;/code&gt; can be called with &lt;code&gt;null&lt;/code&gt; as input. Moreover, nothing prevents us from writing code that returns &lt;code&gt;null&lt;/code&gt; from &lt;code&gt;intToString&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, what happens if we make a function call like &lt;code&gt;intToString ( null )&lt;/code&gt;? The program compiles, but the disreputable &lt;code&gt;NullPointerException&lt;/code&gt; is thrown at run-time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.lang.NullPointerException
    at NullNotAllowedTest.intToString(NullNotAllowedTest.java:4)
    at NullNotAllowedTest.main(NullNotAllowedTest.java:10)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Why? The test &lt;code&gt;i == 1&lt;/code&gt; is equivalent to &lt;code&gt;i.compareTo​ ( new Integer​(1) )&lt;/code&gt;. But &lt;code&gt;i&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; in our case. And executing a method on a &lt;code&gt;null&lt;/code&gt; object is impossible and generates a &lt;code&gt;NullPointerException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the well-known reason for the infamous &lt;em&gt;billion-dollar mistake&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What if &lt;code&gt;intToString&lt;/code&gt; accidentally returns &lt;code&gt;null&lt;/code&gt;, as in the following code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class NullNotAllowedTest {

    static String intToString ( Integer i ) {
        return null;
    }

    public static void main ( String[] args ) {
        System.out.println ( intToString ( 1 ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, no compiler error. But a runtime error occurs, right? Wrong, the output is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;The reason is that &lt;code&gt;System.out.println&lt;/code&gt; has been programmed to write the string &lt;code&gt;"null"&lt;/code&gt; if it is called with &lt;code&gt;null&lt;/code&gt; as input. The method signature doesn't show this, but it is clearly stated in the Java API documentation: "If the argument is null then the string 'null' is printed.".&lt;/p&gt;

&lt;p&gt;What if instead of printing the string returned by &lt;code&gt;intToString&lt;/code&gt;, we want to print the string's size (i.e. the number of characters). Let's try it by replacing ...&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.println ( intToString ( 1 ) );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;... with this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.out.println ( intToString ( 1 ).length() );
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the program doesn't continue silently. A &lt;code&gt;NullPointerException&lt;/code&gt; is thrown again, because the program tries to execute &lt;code&gt;length()&lt;/code&gt; on a &lt;code&gt;null&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;As we can see from this simple example, the result of misusing &lt;code&gt;null&lt;/code&gt; is inconsistent.&lt;/p&gt;

&lt;p&gt;In the real world, the final outcome of incorrect &lt;code&gt;null&lt;/code&gt; handling ranges from totally harmless to totally harmful, and is often unpredictable. This is a general, and frustrating property of all programming languages that support &lt;code&gt;null&lt;/code&gt;, but don't provide &lt;code&gt;compile-time-null-safety&lt;/code&gt;. Imagine a big application with thousands of functions, most of them much more complex than our simple toy code. None of these functions are implicitly protected against misuses of &lt;code&gt;null&lt;/code&gt;. It is understandable why &lt;code&gt;null&lt;/code&gt; and the "billion dollar mistake" have become synonyms for many software developers.&lt;/p&gt;

&lt;p&gt;We can of course try to improve the Java code and make it a bit more robust. For example, we could explicitly check for a &lt;code&gt;null&lt;/code&gt; input in method &lt;code&gt;intToString&lt;/code&gt; and throw an &lt;code&gt;IllegalArgumentException&lt;/code&gt;. We could also add a &lt;code&gt;NonNull&lt;/code&gt; annotation that can be used by some static code analyzers or super-sophisticated IDEs. But all these improvements require manual work, might depend on additional tools and libraries, and don't lead to a satisfactory and reliable solution. Therefore, we will not discuss them. We are not interested in &lt;em&gt;mitigating&lt;/em&gt; the problem of the null pointer error, we want to &lt;em&gt;eliminate&lt;/em&gt; it. Completely!&lt;/p&gt;

&lt;h3&gt;
  
  
  Null Allowed
&lt;/h3&gt;

&lt;p&gt;Let's slightly change the specification of function &lt;code&gt;int_to_string&lt;/code&gt;. We want it to accept &lt;code&gt;null&lt;/code&gt; as input and return:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"one"&lt;/code&gt; if the input is 1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"not one"&lt;/code&gt; if the input is not 1 and not &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;null&lt;/code&gt; if the input is &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How does this affect the code in the three languages?&lt;/p&gt;

&lt;h4&gt;
  
  
  Java
&lt;/h4&gt;

&lt;p&gt;This is the new code written in Java:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    if ( i == null ) {
        return null;
    } else {
        return i == 1 ? "one" : "not one";
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We could again use the ternary operator and write more succinct code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    return i == null ? null : i == 1 ? "one" : "not one";
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Whether to chose the first or second version is a matter of debate. As a general rule, we should value readability more than terseness of code. So, let's stick with version 1.&lt;/p&gt;

&lt;p&gt;The crucial point here is that the function's signature has &lt;em&gt;not changed&lt;/em&gt;, although the function's specification is now different. Whether the function accepts and returns &lt;code&gt;null&lt;/code&gt; or not, the signature is the same:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String intToString ( Integer i ) {
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This doesn't come as a surprise. As we saw already in the previous example, Java (and other languages without null-safety) doesn't make a difference between nullable and non-nullable types. All types are always nullable. Hence by just looking at a function signature we don't know if the function accepts &lt;code&gt;null&lt;/code&gt; as input, and we don't know if it might return &lt;code&gt;null&lt;/code&gt;. The best we can do is to document nullability for each input/output argument. But there is no compile-time protection against misuses.&lt;/p&gt;

&lt;p&gt;To check if it works, we can write a simplistic test application:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class NullAllowedTest {

    static String intToString ( Integer i ) {
        if ( i == null ) {
            return null;
        } else {
            return i == 1 ? "one" : "not one";
        }
    }

    static void displayResult ( String s ) {
        String result = s == null ? "null" : s;
        System.out.println ( "Result: " + result );
    }

    public static void main ( String[] args ) {
        displayResult ( intToString ( 1 ) );
        displayResult ( intToString ( 2 ) );
        displayResult ( intToString ( null ) );
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: one
Result: not one
Result: null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  Haskell
&lt;/h4&gt;

&lt;p&gt;This is the code in Haskell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Maybe Integer -&amp;gt; Maybe String
intToString i = case i of
    Just 1  -&amp;gt; Just "one"
    Nothing -&amp;gt; Nothing
    _       -&amp;gt; Just "not one"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Haskell doesn't support &lt;code&gt;null&lt;/code&gt;. It uses the &lt;code&gt;Maybe&lt;/code&gt; monad.&lt;/p&gt;

&lt;p&gt;The Maybe type is defined as follows:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Maybe a = Just a | Nothing
    deriving (Eq, Ord)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Maybe.html" class="pml-link"&gt;Haskell doc&lt;/a&gt; states: "The &lt;code&gt;Maybe&lt;/code&gt; type encapsulates an optional value. A value of type &lt;code&gt;Maybe a&lt;/code&gt; either contains a value of type &lt;code&gt;a&lt;/code&gt; (represented as &lt;code&gt;Just a&lt;/code&gt;), or it is empty (represented as &lt;code&gt;Nothing&lt;/code&gt;). The &lt;code&gt;Maybe&lt;/code&gt; type is also a monad."&lt;/p&gt;

&lt;p&gt;Note: More information can be found &lt;a href="https://stackoverflow.com/questions/29456824/what-is-the-maybe-type-and-how-does-it-work" class="pml-link"&gt;here&lt;/a&gt; and &lt;a href="https://wiki.haskell.org/Maybe" class="pml-link"&gt;here&lt;/a&gt;. Or you can read about the &lt;a href="https://fsharpforfunandprofit.com/posts/the-option-type/" class="pml-link"&gt;Option type in F#&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The function signature clearly states that calling the function with no integer (i.e. the value &lt;code&gt;Nothing&lt;/code&gt; in Haskell) is allowed, and the function might or might not return a string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For string values the syntax &lt;code&gt;Just "string"&lt;/code&gt; is used to denote a string, and &lt;code&gt;Nothing&lt;/code&gt; is used to denote 'the absence of a value'. Analogously, the syntax &lt;code&gt;Just 1&lt;/code&gt; and &lt;code&gt;Nothing&lt;/code&gt; is used for integers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Haskell uses pattern matching to check for 'the absence of a value' (e.g. &lt;code&gt;Nothing -&amp;gt;&lt;/code&gt;). The symbol &lt;code&gt;_&lt;/code&gt; is used to denote 'any other case'. Note that the &lt;code&gt;_&lt;/code&gt; case includes the &lt;code&gt;Nothing&lt;/code&gt; case. Hence if we forget the explicit check for &lt;code&gt;Nothing&lt;/code&gt; there will be no compiler error, and &lt;code&gt;"not one"&lt;/code&gt; will be returned if the function is called with &lt;code&gt;Nothing&lt;/code&gt; as input.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a simple test application:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Data.Maybe (fromMaybe)

intToString :: Maybe Integer -&amp;gt; Maybe String
intToString i = case i of
    Just 1  -&amp;gt; Just "one"
    Nothing -&amp;gt; Nothing
    _       -&amp;gt; Just "not one"

displayResult :: Maybe String -&amp;gt; IO()
displayResult s = 
    putStrLn $ "Result: " ++ fromMaybe "null" s

main :: IO ()
main = do
    displayResult $ intToString (Just 1)
    displayResult $ intToString (Just 2)
    displayResult $ intToString (Nothing)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: one
Result: not one
Result: null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the &lt;code&gt;fromMaybe "null" s&lt;/code&gt; expression in the above code. In Haskell this is a way to provide a default value in case of &lt;code&gt;Nothing&lt;/code&gt;. It's conceptually similar to the expression &lt;code&gt;s == null ? "null" : s&lt;/code&gt; in Java.&lt;/p&gt;

&lt;h4&gt;
  
  
  PPL
&lt;/h4&gt;

&lt;p&gt;In PPL the code looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null
    case value of i
        when null
            return null
        when 1
            return "one"
        otherwise
            return "not one"
    .
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note: A case &lt;em&gt;expression&lt;/em&gt; will be available in a future version of PPL (besides the case &lt;em&gt;statement&lt;/em&gt; shown above). Then the code can be written more concisely as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null = \
    case value of i
        when null: null
        when 1   : "one"
        otherwise: "not one"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In PPL &lt;code&gt;null&lt;/code&gt; is a regular type (like &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;pos_32&lt;/code&gt;, etc.) that has one possible value: &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It appears as follows in the top of PPL's type hierarchy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ayU5TOd1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2nfbod6rzrmi5t595ut6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ayU5TOd1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2nfbod6rzrmi5t595ut6.png" alt="PPL top type hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PPL supports union types (also called sum types, or choice types). For example, if a reference can be a string or a number, the type is &lt;code&gt;string or number&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's why we use the syntax &lt;code&gt;pos_32 or null&lt;/code&gt; and &lt;code&gt;string or null&lt;/code&gt; to denote nullable types. The type &lt;code&gt;string or null&lt;/code&gt; simply means that the value can be any string &lt;em&gt;or&lt;/em&gt; &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The function clearly states that it accepts &lt;code&gt;null&lt;/code&gt; as input, and that it might return &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We use a &lt;code&gt;case&lt;/code&gt; instruction to check the input and return an appropriate string. The compiler ensures that each case is covered in the &lt;code&gt;when&lt;/code&gt; clauses. It is not possible to accidentally forget to check for &lt;code&gt;null&lt;/code&gt;, because (in contrats to Haskell) the &lt;code&gt;otherwise&lt;/code&gt; clause doesn't cover the &lt;code&gt;null&lt;/code&gt; clause.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple test application looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null
    case value of i
        when null
            return null
        when 1
            return "one"
        otherwise
            return "not one"
    .
.

function display_result ( s string or null )
    write_line ( """Result: {{s if_null: "null"}}""" )
.

function start
    display_result ( int_to_string ( 1 ) )
    display_result ( int_to_string ( 2 ) )
    display_result ( int_to_string ( null ) )
.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Result: one
Result: not one
Result: null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note the &lt;code&gt;"""Result: {{s if_null: "null"}}"""&lt;/code&gt; expression used in function &lt;code&gt;display_result&lt;/code&gt;. We use string interpolation: an expression embedded between a &lt;code&gt;{{&lt;/code&gt; and &lt;code&gt;}}&lt;/code&gt; pair. And we use the &lt;code&gt;if_null:&lt;/code&gt; operator to provide a string that represents &lt;code&gt;null&lt;/code&gt;. Writing &lt;code&gt;s if_null: "null"&lt;/code&gt; is similar to &lt;code&gt;s == null ? "null" : s&lt;/code&gt; in Java.&lt;/p&gt;

&lt;p&gt;If we wanted to print nothing in case of &lt;code&gt;null&lt;/code&gt;, we could code &lt;code&gt;"""Result: {{? s}}"""&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Discussion
&lt;/h4&gt;

&lt;p&gt;Again, the three languages allow us to write code that works correctly.&lt;/p&gt;

&lt;p&gt;But there are some notable differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In Haskell and PPL, the functions clearly state that 'the absence of a value' is allowed (i.e. &lt;code&gt;Nothing&lt;/code&gt; in Haskell, or &lt;code&gt;null&lt;/code&gt; in PPL). In Java, there is no way to make a difference between nullable and non-nullable arguments (except via comments or annotations, of course).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Haskell and PPL, the compiler ensures we don't forget to check for 'the absence of a value'. Executing an operation on a possibly &lt;code&gt;Nothing&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; value is not allowed. In Java we are left on our own.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a comparison of the three versions of function &lt;code&gt;int_to_string&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static String intToString ( Integer i ) {
    if ( i == null ) {
        return null;
    } else {
        return i == 1 ? "one" : "not one";
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Haskell&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intToString :: Maybe Integer -&amp;gt; Maybe String
intToString i = case i of
    Just 1 -&amp;gt; Just "one"
    Nothing -&amp;gt; Nothing
    _ -&amp;gt; Just "not one"
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PPL&lt;/p&gt;

&lt;p&gt;New version (not available yet):&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null = \
    case value of i
        when null: null
        when 1   : "one"
        otherwise: "not one"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Current version:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function int_to_string ( i pos_32 or null ) -&amp;gt; string or null
    case value of i
        when null
            return null
        when 1
            return "one"
        otherwise
            return "not one"
    .
.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here is the function used to display the result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static void displayResult ( String s ) {
    String result = s == null ? "null" : s;
    System.out.println ( "Result: " + result );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Haskell&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Data.Maybe (fromMaybe)

displayResult :: Maybe String -&amp;gt; IO()
displayResult s = 
    putStrLn $ "Result: " ++ fromMaybe "null" s
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PPL&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        function display_result ( s string or null )
            write_line ( """Result: {{s if_null: "null"}}""" )
        .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it for part 1. In part 2 (to be published soon) we'll have a look at some useful null-handling features used frequently in practice.&lt;/p&gt;

&lt;p&gt;Header image by &lt;a href="https://pixabay.com/users/dailyprinciples-3836461/"&gt;dailyprinciples&lt;/a&gt; from &lt;a href="https://pixabay.com"&gt;Pixabay&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>null</category>
      <category>maybe</category>
      <category>option</category>
    </item>
    <item>
      <title>We Need a New Document Markup Language - Here is Why</title>
      <dc:creator>Christian Neumanns</dc:creator>
      <pubDate>Wed, 20 Mar 2019 11:55:56 +0000</pubDate>
      <link>https://dev.to/practicalprogramming/we-need-a-new-document-markup-language---here-is-why-5d4c</link>
      <guid>https://dev.to/practicalprogramming/we-need-a-new-document-markup-language---here-is-why-5d4c</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fozidoodxl9gqoc2qak0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fozidoodxl9gqoc2qak0i.png" alt="markup code" width="700" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction: What's the Problem?
&lt;/h1&gt;

&lt;p&gt;There are many document markup languages available already. Wikipedia lists over 70 variations in its &lt;a href="https://en.wikipedia.org/wiki/List_of_document_markup_languages" rel="noopener noreferrer"&gt;List of document markup languages&lt;/a&gt; - among them HTML, Markdown, Docbook, Asciidoctor, reStructuredText, etc.&lt;/p&gt;

&lt;p&gt;Why, then, does the title of this article suggest we need &lt;em&gt;yet another one&lt;/em&gt; ???&lt;/p&gt;

&lt;p&gt;What's the problem?&lt;/p&gt;

&lt;p&gt;There are two fundamental problems with the existing document markup languages: Either they are not easy to use, or they are not well suited to write complex documents, such as technical articles, user manuals, or books. An example of "not easy to use, but suited for complex documents" would be Docbook. An example of "easy to use, but not suited for complex documents" would be Markdown.&lt;/p&gt;

&lt;p&gt;Of course, the above categorization is simplistic. But it should serve as a good starting point to get the gist of this article which aims to delineate the kind of problems that occur in practice. You'll see many representative examples of markup code that illustrates what's wrong, complemented by links to more information.&lt;/p&gt;

&lt;p&gt;You'll also discover a &lt;em&gt;new&lt;/em&gt; markup language. Lots of examples will demonstrate how a new syntax can lead to a language that is "easy to use and suited for complex documents". A &lt;em&gt;proof-of-concept&lt;/em&gt; implementation is already available. More on this later.&lt;/p&gt;

&lt;h1&gt;
  
  
  Preliminary Remarks
&lt;/h1&gt;

&lt;p&gt;Please note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This article is about document markup languages used to write &lt;em&gt;text documents&lt;/em&gt;, such as books and articles published on the net. There are other markup languages used to describe specific data, such as mathematical formulas, images, and geographic information, but these are out of scope of this article. However, some ideas presented in this article might be applied to other kinds of markup languages as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This article focuses solely on the &lt;em&gt;syntax&lt;/em&gt; of markup languages. We will not discuss other aspects that are also important in the choice of a suitable markup language, such as: support on your OS, ease of installation and dependencies, the tool chain available to create final documents, the quality of documentation, price, customer/user support, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Readers of this article should have some basic experience with a markup language like HTML, Markdown, Asciidoctor, or similar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Readers not aware of the &lt;em&gt;many&lt;/em&gt; advantages of document markup languages might first want to read: &lt;a href="https://dev.to/practicalprogramming/advantages-of-document-markup-languages-vs-wysiwyg-editors-9f6"&gt;Advantages of Document Markup Languages vs WYSIWYG Editors (Word Processors)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Inconveniences / Part 1
&lt;/h1&gt;

&lt;p&gt;Let us first consider some well-known markup languages and show some inconveniences.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;HTML is the language of the web. So, why not write everything in HTML? The reasons to discard this option are well known. Let's quickly recapitulate them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HTML is cumbersome to write. Nobody wants to write XML code by hand, although editors with HTML/XML support might help.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some frequent writing tasks require non-trivial HTML code.&lt;/p&gt;

&lt;p&gt;Suppose we want to display a horizontally centered image with a simple black border and a link. The HTML code an unexperienced user would expect to write could look like this:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="ball.png" align="center" border="yes" link="http://www.example.com/ball"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the code he or she actually has to write is cumbersome and there are different ways to do it. Here is one way:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div style="text-align: center"&amp;gt;
    &amp;lt;a href="http://www.example.com/ball"&amp;gt;
        &amp;lt;img src="ball.png" style="border:1px solid black;"&amp;gt;
    &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTML lacks "productivity features for writers", such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Automatic generation of a table of contents, index, glossary, etc.&lt;/li&gt;
&lt;li&gt;  Variables used to hold recurring values&lt;/li&gt;
&lt;li&gt;  Splitting a document into different files&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Other inconveniences will be shown later.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Markdown
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Markdown" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt; is a very popular, lightweight markup languages. It is easy to learn and use, and well suited for short and simple texts, such as comments in forums, readme files, etc.&lt;/p&gt;

&lt;p&gt;However, it suffers from the following problems that make it unsuitable for complex or big documents (e.g. technical articles, user manuals, and books):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The original Markdown defined by John Gruber lacks many features expected by writers, such as tables (only embedded HTML tables are supported), automatic generation of table of contents, syntax highlighting, file splitting, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no unique, unambiguous specification for Markdown. Many flavors of Markdown exists, with different rules and different features supported. This leads to incompatibility issues when markup code is shared. &lt;a href="https://commonmark.org/" rel="noopener noreferrer"&gt;CommonMarkdown&lt;/a&gt; is an attempt to solve this problem. However, the specification is huge and not completed yet (at the time of writing (February 2019) version 0.28, dated 2017-08-01, is the latest one).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Markdown has similar problems and limitations to those shown in chapter Inconveniences / Part 2. These flaws can quickly become an annoyance when you use Markdown for anything else than short, simple texts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a list of articles with more information about Markdown's shortcomings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.ericholscher.com/blog/2016/mar/15/dont-use-markdown-for-technical-docs/" rel="noopener noreferrer"&gt;Why You Shouldn’t Use “Markdown” for Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.red-gate.com/simple-talk/blogs/sundown-on-markdown/" rel="noopener noreferrer"&gt;Sundown on Markdown?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.wilfred.me.uk/blog/2012/07/30/why-markdown-is-not-my-favourite-language/" rel="noopener noreferrer"&gt;Why Markdown Is Not My Favourite Language&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Docbook
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docbook.org/" rel="noopener noreferrer"&gt;Docbook&lt;/a&gt; is an XML-based markup language that uses semantic tags to describe documents.&lt;/p&gt;

&lt;p&gt;It has probably the most complete set of features among all markup languages. It has been used by many authors, is pre-installed on some Linux distributions, and is supported by many organizations and publishers. Docbook has been successfully used to create, publish, and print lots of big documents of all kinds.&lt;/p&gt;

&lt;p&gt;But it has the following drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It uses XML and a verbose syntax.&lt;/p&gt;

&lt;p&gt;Look at the following example, borrowed from &lt;a href="https://en.wikipedia.org/wiki/DocBook" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;book xml:id="simple_book" xmlns="http://docbook.org/ns/docbook" version="5.0"&amp;gt;
    &amp;lt;title&amp;gt;Very simple book&amp;lt;/title&amp;gt;
    &amp;lt;chapter xml:id="chapter_1"&amp;gt;
        &amp;lt;title&amp;gt;Chapter 1&amp;lt;/title&amp;gt;
        &amp;lt;para&amp;gt;Hello world!&amp;lt;/para&amp;gt;
        &amp;lt;para&amp;gt;I hope that your day is proceeding &amp;lt;emphasis&amp;gt;splendidly&amp;lt;/emphasis&amp;gt;!&amp;lt;/para&amp;gt;
    &amp;lt;/chapter&amp;gt;
    &amp;lt;chapter xml:id="chapter_2"&amp;gt;
        &amp;lt;title&amp;gt;Chapter 2&amp;lt;/title&amp;gt;
        &amp;lt;para&amp;gt;Hello again, world!&amp;lt;/para&amp;gt;
    &amp;lt;/chapter&amp;gt;
&amp;lt;/book&amp;gt;        
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Would you enjoy writing and maintaining such code?&lt;/p&gt;

&lt;p&gt;Compare the above code with the following one, written in a modern markup language like Asciidoctor:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;= Very simple book

== Chapter 1

Hello world!

I hope that your day is proceeding _splendidly_!

== Chapter 2

Hello again, world!
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docbook is complex, and therefore hard to learn and use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Output produced by Docbook, especially HTML, looks old-fashioned (see examples on its website). Of course, presentation can be customized, but this is not an easy task.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  LaTeX
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/LaTeX" rel="noopener noreferrer"&gt;LaTeX&lt;/a&gt; is a high-quality typesetting system. It is widely used in academia to create scientific documents. It is considered to be the best option for writing PDF documents containing lots of mathematic formulas and equations.&lt;/p&gt;

&lt;p&gt;I never used LaTeX myself, because I don't write scientific documents - just articles and books to be published on the web. Therefore, I don't want to comment on it too much. However, it is important to mention it because of its popularity in academia.&lt;/p&gt;

&lt;p&gt;LaTeX's unique syntax seems verbose to me, and a bit complex. Here is an abbreviated example from &lt;a href="https://en.wikipedia.org/wiki/LaTeX#Example" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\documentclass{article}
\usepackage{amsmath}
\title{\LaTeX}

\begin{document}
    \maketitle
    \LaTeX{} is a document preparation system ...

    % This is a comment
    \begin{align}
        E_0 &amp;amp;= mc^2 \\
        E &amp;amp;= \frac{mc^2}{\sqrt{1-\frac{v^2}{c^2}}}
    \end{align}  
\end{document}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The article &lt;a href="https://texfaq.org/FAQ-LaTeX2HTML" rel="noopener noreferrer"&gt;Conversion from (La)TeX to HTML&lt;/a&gt; states that converting LaTeX math to HTML is "a challenge".&lt;/p&gt;

&lt;p&gt;Some markup languages allow LaTeX snippets to be embedded in their markup code, which can be very useful if you need the power of LaTeX for maths. There are other options to display maths on the web, such as &lt;a href="https://www.mathjax.org/" rel="noopener noreferrer"&gt;Mathjax&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/MathML" rel="noopener noreferrer"&gt;MathML&lt;/a&gt; (an ISO standard and part of HTML5).&lt;/p&gt;

&lt;h2&gt;
  
  
  Popular for Big Documents
&lt;/h2&gt;

&lt;p&gt;A impressive number of markup languages have emerged. Many of them use a syntax similar to Markup, and are therefore easy to learn and use. Some have more features than Markdown and are even extensible. However, as soon as we start writing complex documents, corner-cases and limits diminish the initial joy of using them.&lt;/p&gt;

&lt;p&gt;Two popular markup languages used for big documents are Asciidoctor (an improved version of &lt;a href="https://en.wikipedia.org/wiki/AsciiDoc" rel="noopener noreferrer"&gt;Asciidoc&lt;/a&gt;), and &lt;a href="https://en.wikipedia.org/wiki/ReStructuredText" rel="noopener noreferrer"&gt;reStructuredText&lt;/a&gt; (an improved version of StructuredText). We will have a look at them soon.&lt;/p&gt;

&lt;h1&gt;
  
  
  Practical Markup Language (PML)
&lt;/h1&gt;

&lt;p&gt;Before moving on to the most interesting part of this article, let me briefly introduce the new markup language I mentioned already in the introduction.&lt;/p&gt;

&lt;p&gt;The language is called &lt;em&gt;Practical Markup Language (PML)&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"fitting the needs of a particular situation in a helpful way; helping to solve a problem or difficulty; effective or suitable"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- definition of 'practical' in the Cambridge Dictionary&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started the &lt;a href="http://www.practical-programming.org/pml/index.html" rel="noopener noreferrer"&gt;PML project&lt;/a&gt; a few months ago because I couldn't find a markup language that was easy to use &lt;em&gt;and&lt;/em&gt; well suited for big, complex documents.&lt;/p&gt;

&lt;p&gt;In the next chapter we'll look at examples of markup code written in PML, compared to code written in other languages. So let's first mention two basic PML syntax rules needed to understand the upcoming examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A PML document is a tree of nodes (similar to an XML/XHTML document). Each node starts with a &lt;code&gt;{&lt;/code&gt;, followed by a tag name. Each node ends with a &lt;code&gt;}&lt;/code&gt;. A node can contain text or child nodes.&lt;/p&gt;

&lt;p&gt;For example, here is a node containing text that will be rendered in italics:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{i bright}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This node starts with &lt;code&gt;{i&lt;/code&gt;, and ends with &lt;code&gt;}&lt;/code&gt;. &lt;code&gt;i&lt;/code&gt; is the tag name. In this case &lt;code&gt;i&lt;/code&gt; is an abbreviation for &lt;code&gt;italic&lt;/code&gt;, which means that the node's content will be rendered in &lt;em&gt;italics&lt;/em&gt;. The content of this node is the text &lt;code&gt;bright&lt;/code&gt;. The above PML markup code will be rendered as: &lt;em&gt;bright&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some nodes have attributes, used to specify additional properties of the node (besides its tag name).&lt;/p&gt;

&lt;p&gt;For example, the title of a chapter is defined with attribute &lt;code&gt;title&lt;/code&gt;, as follows:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{chapter title=A Nice Surprise
    Once upon a time ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is not much more to say about the basic concept of PML syntax. For more insight, and a description of features not used in this article, please consult the &lt;a href="http://www.practical-programming.org/pml/docs/User_Manual/PML_User_Manual.html" rel="noopener noreferrer"&gt;PML User Manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can download and play around with a free implementation of PML. But please note:&lt;/p&gt;

&lt;p&gt;IMPORTANT: PML is a &lt;em&gt;work in progress&lt;/em&gt;. There are missing features, you might encounter bugs, and backwards compatibility is currently not guaranteed.&lt;/p&gt;

&lt;p&gt;I use PML myself to write all my web documents, such as this article. For links to more real-life examples please visit the &lt;a href="http://www.practical-programming.org/pml/about/faq.html#examples" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Inconveniences / Part 2
&lt;/h1&gt;

&lt;p&gt;I this chapter we'll look at examples that reveal &lt;em&gt;some&lt;/em&gt; problems encountered with markup languages. This is by no means an exhaustive enumeration of all troubles and corner cases. The aim is to just show a few examples that demonstrate the kind of inconveniences and limits encountered in the real world.&lt;/p&gt;

&lt;p&gt;For each example the markup code will be shown in &lt;a href="https://www.w3.org/TR/html/" rel="noopener noreferrer"&gt;HTML&lt;/a&gt;, &lt;a href="https://asciidoctor.org/" rel="noopener noreferrer"&gt;Asciidoctor&lt;/a&gt;, &lt;a href="http://docutils.sourceforge.net/rst.html" rel="noopener noreferrer"&gt;reStructuredText&lt;/a&gt;, and &lt;a href="http://www.practical-programming.org/pml/" rel="noopener noreferrer"&gt;PML&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to try out some code, you can use the following online testers (no need to install anything on your PC):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3schools.com/tryit/" rel="noopener noreferrer"&gt;HTML&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://asciidoclive.com" rel="noopener noreferrer"&gt;Asciidoctor&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://rst.ninjs.org" rel="noopener noreferrer"&gt;reStructuredText&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An online tester for PML is not yet available. You have to install PML on a Windows PC if you want to try it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Font Styles
&lt;/h2&gt;

&lt;p&gt;Font styles (&lt;em&gt;italic&lt;/em&gt;, &lt;strong&gt;bold&lt;/strong&gt;, &lt;code&gt;monospace&lt;/code&gt;, etc.) are often used in all kinds of documents, so good support is essential.&lt;/p&gt;

&lt;p&gt;But as we will see, surprises and limits can emerge, as soon as we have to deal with non-trivial cases. Let's look at &lt;em&gt;some&lt;/em&gt; examples to illustrate this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part of a Sentence in Italics
&lt;/h3&gt;

&lt;p&gt;Suppose we want to write:&lt;br&gt;&lt;br&gt;
They called it &lt;em&gt;Harmonic States&lt;/em&gt;, a good name.&lt;/p&gt;

&lt;p&gt;This is a trivial case, and all languages support it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They called it &amp;lt;i&amp;gt;Harmonic States&amp;lt;/i&amp;gt;, a good name.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They called it _Harmonic States_, a good name.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They called it *Harmonic States*, a good name.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They called it {i Harmonic States}, a good name.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Part of a Word in Italics
&lt;/h3&gt;

&lt;p&gt;We want to write:&lt;br&gt;&lt;br&gt;
She unwrapped the challenge first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;She &amp;lt;i&amp;gt;un&amp;lt;/i&amp;gt;wrapped the challenge first.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;She __un__wrapped the challenge first.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we have to use two underscores. Using a single underscore (as in the first example), would result in:&lt;br&gt;&lt;br&gt;
She _un_wrapped the challenge first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;She *un*\wrapped the challenge first.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the letter w has to be escaped (preceded by a backslash) for reasons explained &lt;a href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#character-level-inline-markup" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If the letter is not escaped then a warning is displayed and the result is:&lt;br&gt;&lt;br&gt;
She *un*wrapped the challenge first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;She {i un}wrapped the challenge first.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Text in Bold And Italic
&lt;/h3&gt;

&lt;p&gt;We want to write:&lt;br&gt;&lt;br&gt;
They were all &lt;strong&gt;&lt;em&gt;totally flabbergasted&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They were all &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;totally flabbergasted&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They were all *_totally flabbergasted_*.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;Combining bold and italic is not supported in reStructuredText, but there are some &lt;a href="https://stackoverflow.com/questions/11984652/bold-italic-in-restructuredtext" rel="noopener noreferrer"&gt;complicated workarounds&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;They were all {b {i totally flabbergasted}}.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-Life Example
&lt;/h3&gt;

&lt;p&gt;Here is an example inspired by an Asciidoctor user who &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/2020" rel="noopener noreferrer"&gt;asked&lt;/a&gt; how to display:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;_id&lt;/strong&gt; &lt;em&gt;optional&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's make the exercise a little bit more interesting by also displaying:&lt;br&gt;&lt;br&gt;
&lt;em&gt;_id&lt;/em&gt; &lt;strong&gt;optional&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;b&amp;gt;_id&amp;lt;/b&amp;gt; &amp;lt;i&amp;gt;optional&amp;lt;/i&amp;gt;
&amp;lt;i&amp;gt;_id&amp;lt;/i&amp;gt; &amp;lt;b&amp;gt;optional&amp;lt;/b&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No surprise here. It just works as expected.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;Intuitive attempt:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*_id* _optional_
__id_ *optional*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first line doesn't work, it produces:&lt;br&gt;&lt;br&gt;
&lt;b&gt;id&lt;/b&gt; _optional&lt;/p&gt;

&lt;p&gt;However, the second line works, which is a bit counterintuitive.&lt;/p&gt;

&lt;p&gt;If normal text includes a character that is also used for markup (in our case the &lt;code&gt;_&lt;/code&gt; preceding &lt;code&gt;id&lt;/code&gt;), then the character must be escaped. This is a fundamental rule in pretty much all markup languages. For example in HTML a &lt;code&gt;&amp;lt;&lt;/code&gt; must be escaped with &lt;code&gt;&amp;amp;lt;&lt;/code&gt;. Many languages (including Asciidoctor and PML) use a backslash prefix (e.g. &lt;code&gt;\r&lt;/code&gt;) to escape. So let's rewrite the code:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*\_id* _optional_
_\_id_ *optional*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This doesn't work in Asciidoctor. It produces&lt;br&gt;&lt;br&gt;
&lt;b&gt;_id&lt;/b&gt; _optional_&lt;br&gt;
and&lt;br&gt;&lt;br&gt;
\_id &lt;b&gt;optional&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Here is a correct version, as suggested in an answer to the user's question:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*pass:[_]id* _optional_
_pass:[_]id_ *optional*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another answer suggests this solution:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*_id* __optional__
___id__ *optional*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More edge case are documented in chapters &lt;a href="https://asciidoctor.org/docs/user-manual/#unconstrained-formatting-edge-cases" rel="noopener noreferrer"&gt;Unconstrained formatting edge cases&lt;/a&gt; and &lt;a href="https://asciidoctor.org/docs/user-manual/#escaping-unconstrained-quotes" rel="noopener noreferrer"&gt;Escaping unconstrained quotes&lt;/a&gt; of the Asciidoctor User Manual.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**_id** *optional*
*_id* **optional**
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no problem here, because the character &lt;code&gt;_&lt;/code&gt; is not used in reStructuredText to define markup.&lt;/p&gt;

&lt;p&gt;However, suppose we wanted to write:&lt;br&gt;&lt;br&gt;
&lt;em&gt;*id*&lt;/em&gt; &lt;strong&gt;*optional*&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the code:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*\*id\** ***optional***
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;code&gt;*&lt;/code&gt;s in &lt;code&gt;id&lt;/code&gt; must be escaped, but the &lt;code&gt;*&lt;/code&gt;s in &lt;code&gt;optional&lt;/code&gt; don't need to be escaped.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{b _id} {i optional}
{i _id} {b optional}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Nested Font Styles
&lt;/h3&gt;

&lt;p&gt;Nested font styles of the same kind (e.g. &lt;code&gt;&amp;lt;i&amp;gt;...&amp;lt;i&amp;gt;...&amp;lt;/i&amp;gt;...&amp;lt;/i&amp;gt;&lt;/code&gt;) occur rarely in text written by humans, but they could be more or less frequent in auto-generated markup code. If they are not supported then the tool that generates the markup code becomes more complicated to implement, because it must track the font styles that are active already, in order to avoid nesting them.&lt;/p&gt;

&lt;p&gt;So, how is this supported in the different languages?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;i&amp;gt;This is &amp;lt;i&amp;gt;excellent&amp;lt;/i&amp;gt;, isn't it?&amp;lt;/i&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No problem, it produces&lt;br&gt;&lt;br&gt;
&lt;em&gt;This is excellent, isn't it?&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_This is _excellent_, isn't it?_
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code is obviously ambiguous: Are the italics nested or do we want to italicize "This is " and ", isn't it?". When I tested it, the result was neither of it:&lt;br&gt;&lt;br&gt;
&lt;em&gt;This is _excellent&lt;/em&gt;, isn’t it?_&lt;/p&gt;

&lt;p&gt;As far as I now, Asciidoctor doesn't support nested font styles of the same kind.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;The reStructuredText specification &lt;a href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup" rel="noopener noreferrer"&gt;states&lt;/a&gt;: "Inline markup cannot be nested." However, no error is displayed if it &lt;em&gt;is&lt;/em&gt; nested, and the result is unspecified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{i This is {i excellent}, isn't it?}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Font styles of the same kind can be nested in PML. The above code results in:&lt;br&gt;&lt;br&gt;
&lt;em&gt;This is excellent, isn't it?&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nested Chapters
&lt;/h2&gt;

&lt;p&gt;Suppose we are writing an article titled "New Awesome Product" that contains four chapters. The structure looks as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Awesome Product
    Introduction
    More features
    Faster
    Less resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Later on we decide to insert chapter "Advantages" as a parent of the three last chapters. The structure now becomes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Awesome Product
    Introduction
    Advantages
        More features
        Faster
        Less resources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What are the &lt;em&gt;changes&lt;/em&gt; required in the markup code to pass from version 1 to version 2? Can you simply insert the code for a new chapter? Let's see.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmalii6uk7sjqbmxxxpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmalii6uk7sjqbmxxxpe.png" alt="HTML chapters" width="594" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Code &lt;em&gt;changes&lt;/em&gt; are displayed in bold.&lt;/p&gt;

&lt;p&gt;As shown above, besides inserting the new chapter, we have to change the markup for the three child chapters: &lt;code&gt;h2&lt;/code&gt; must be changed to &lt;code&gt;h3&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Asciidoctor
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfabchw8lwzur0b52ap8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfabchw8lwzur0b52ap8.png" alt="Asciidoctor chapters" width="474" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, we have to change the markup for the three child chapters: &lt;code&gt;==&lt;/code&gt; must be changed to &lt;code&gt;===&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: The blank lines between the chapters are required, otherwise the document is not rendered correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  reStructuredText
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fynfr0cziz60foieci5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fynfr0cziz60foieci5.png" alt="reStructuredText chapters" width="438" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The markup for the three child chapters must be changed: All occurrences of &lt;code&gt;=&lt;/code&gt; must be changed to &lt;code&gt;-&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The non-trivial rules for reStructuredText's sections can be looked up &lt;a href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  PML
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1rx4dl4t6wr2ary5cs1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1rx4dl4t6wr2ary5cs1.png" alt="PML chapters" width="656" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In PML, there is no need to change the code of the three child chapters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bottom Line
&lt;/h3&gt;

&lt;p&gt;In all languages, except PML, the markup code of all child chapters must be adapted if a parent chapter is inserted.&lt;/p&gt;

&lt;p&gt;This is not a deal-breaker in case of small articles with few chapters. But image you are writing your next big article or book with lots of chapters and frequent changes. Now, the necessity to manually update child chapters can quickly turn into a daunting, boring, and error-prone task.&lt;/p&gt;

&lt;p&gt;Note: Asciidoctor provides a &lt;code&gt;leveloffset&lt;/code&gt; variable that can be used to change the level of chapters. This might be useful in some cases, but it also creates additional unneeded complexity, as can be seen &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/530" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/1616" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A more serious kind of problem can arise in the following situation: Imagine a set of different documents that share some common chapters. To avoid code duplication, the common chapters are stored in different files, and an &lt;code&gt;insert file&lt;/code&gt; directive is used in the main documents. This works fine as long as the levels of all common chapters are the same in all documents. But troubles emerge if this is not the case.&lt;/p&gt;

&lt;p&gt;It is also worth to mention that HTML, Asciidoctor and reStructuredText don't protect you against wrong chapter hierarchies. For example, you don't get a warning or error if a chapter of level 2 contains a direct child chapter of level 4.&lt;/p&gt;

&lt;p&gt;In a language like PML, the above problems simply don't exist, because the level is not specified in the markup code. All chapters (of any level) are defined with the same, unique syntax. The chapters' tree structure (i.e. the level of each chapter) is automatically defined by the parser. And wrong hierarchies in the markup code, such as a missing &lt;code&gt;}&lt;/code&gt; to close a chapter, are flagged by an error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lists
&lt;/h2&gt;

&lt;p&gt;In Asciidoctor the kind of problems we have seen with chapter hierarchies can also arise with list hierarchies (e.g. lists that contain lists). The reason is the same as for chapters: &lt;a href="https://asciidoctor.org/docs/user-manual/#nested" rel="noopener noreferrer"&gt;Asciidoctor lists&lt;/a&gt; use different markup code to explicitly specify the level of list items (&lt;code&gt;*&lt;/code&gt; for level 1, &lt;code&gt;**&lt;/code&gt; for level 2, etc.). Moreover, there are a number of complications you have to be aware of when working with &lt;a href="https://asciidoctor.org/docs/user-manual/#complex-list-content" rel="noopener noreferrer"&gt;complex list content&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In reStructuredText, &lt;a href="https://stackoverflow.com/questions/5550089/how-to-create-a-nested-list-in-restructuredtext" rel="noopener noreferrer"&gt;nested lists&lt;/a&gt; are created using indentation and blank lines. This works fine for simple nested lists, but creates other problems in more complex cases (not discussed here). Using whitespace (e.g. blank lines and indentation) to define structure in markup code is a bad idea, as we'll see later.&lt;/p&gt;

&lt;p&gt;In HTML and PML, the above problems don't exist with lists because the syntax for parent- and child nodes is the same (not shown here).&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;Good support for comments is important, because they are used frequently, especially in collaborative environments. So, how well are they supported?&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-Line Comment
&lt;/h3&gt;

&lt;p&gt;A single-line comment is a line that contains only a comment (no markup). They are supported in all languages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;

&lt;p&gt;A HTML (or XML) comment starts with &lt;code&gt;&amp;lt;!--&lt;/code&gt; at any position, and ends with &lt;code&gt;--&amp;gt;&lt;/code&gt; at any subsequent position. Example:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- comment --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;A single-line comment starts with &lt;code&gt;//&lt;/code&gt; at the beginning of a line:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// comment
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;A single-line comment starts with &lt;code&gt;..&lt;/code&gt; at the beginning of a line and must be followed by an empty line&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.. comment
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;

&lt;p&gt;A comment starts with &lt;code&gt;{-&lt;/code&gt; at any position, and ends with &lt;code&gt;-}&lt;/code&gt; at any subsequent position.&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{- comment -}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trailing Comment
&lt;/h3&gt;

&lt;p&gt;A trailing comment appears at the end of a line, after markup code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The reason will be explained later &amp;lt;!-- TODO: add link --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;At the time of writing, trailing comments are not supported in Asciidoctor (see &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/991" rel="noopener noreferrer"&gt;issue 991&lt;/a&gt; on Github).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;Trailing comments are not supported in reStructuredText.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The reason will be explained later {- TODO: add link -}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Inline Comment
&lt;/h3&gt;

&lt;p&gt;An inline comment is preceded and followed by markup code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is &amp;lt;!-- good --&amp;gt; awesome.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;Inline comments are not supported in Asciidoctor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;Inline comments are not supported in reStructuredText.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is {- good -} awesome.
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multi-Line Comment
&lt;/h3&gt;

&lt;p&gt;A multi comment starts at a given line, and ends at a subsequent line.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--
comment line 1
comment line 2
comment line 3
--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;A multi-line comment starts with &lt;code&gt;////&lt;/code&gt; on a line, and ends with with &lt;code&gt;////&lt;/code&gt; on a subsequent line:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;////
comment line 1
comment line 2
comment line 3
////
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#comments" rel="noopener noreferrer"&gt;rules&lt;/a&gt; for multi-line comments are a bit 'surprising'. User Cecil Curry puts it more bluntly in a &lt;a href="https://stackoverflow.com/questions/4783814/how-to-comment-a-string-in-restructured-text" rel="noopener noreferrer"&gt;Stackoverflow question&lt;/a&gt;: "It's non-trivial, non-obvious, and tragically fragile."&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;..
  comment line 1
  comment line 2
  comment line 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All lines after the &lt;code&gt;..&lt;/code&gt; must be indented. In practice, this means that unindented text must first be indented to include it in a multi-line comment. If the text is later uncommented then the indent must be removed. Quite inconvenient and fragile, indeed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{-
comment line 1
comment line 2
comment line 3
-}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Nested Comments
&lt;/h3&gt;

&lt;p&gt;Nested comments are useful when we want to comment a block of text that contains already one or more comments.&lt;/p&gt;

&lt;p&gt;Nested comments are not supported in HTML, Asciidoctor, and reStructuredText. However, there are some tricky workarounds in HTML, as explained &lt;a href="https://stackoverflow.com/questions/18145886/html-nested-comments" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PML supports nested comments to any level. Here is a simple example.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{-
These lines
will not {- nested comment -}
appear in the final document.
-}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Removed Comments
&lt;/h3&gt;

&lt;p&gt;By definition, comments are not displayed to the readers. But it is also important that comments are &lt;em&gt;removed in the final document&lt;/em&gt;, because otherwise readers might be able to see them. This rule is applied in Asciidoctor, reStructuredText, PML, and probably most other markup languages. But not in &lt;em&gt;hand-coded&lt;/em&gt; HTML. This can lead to troubles. Imagine the following scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Boss to Bob: "Please remove my private mobile number from the website".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bob to Boss: "Ok".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bob comments the HTML code containing the mobile number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boss checks the new version and is happy because his number is no more displayed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A website visitor clicks on "Display Source Code" in the browser's context menu, and ... discovers the boss's private mobile number.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to learn the hard way that silly things like this do happen. And yes, I was the 'Bob'.&lt;/p&gt;
&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The following table summarizes the support for comments:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt; Single-line &lt;/th&gt;
&lt;th&gt; Trailing &lt;/th&gt;
&lt;th&gt; Inline &lt;/th&gt;
&lt;th&gt; Multi-line &lt;/th&gt;
&lt;th&gt; Nested &lt;/th&gt;
&lt;th&gt; Removed &lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Asciidoctor&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reStructuredText&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PML&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;td&gt;✔&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Whitespace And Indentation
&lt;/h2&gt;

&lt;p&gt;At first, using whitespace to define structure seams like a good idea. Look at the following example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent
    child 1
    child 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The structure is very easy to read &lt;em&gt;and&lt;/em&gt; write. No noisy special markup characters are needed.&lt;/p&gt;

&lt;p&gt;It is therefore tempting for markup language designers to use whitespace as a simple way to define structure. Unfortunately, this works well only for simple structures, and has other inconveniences we'll see soon.&lt;/p&gt;

&lt;p&gt;Therefore, a simple, but important rule must be applied in markup languages designed to work well with complex content:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Whitespace doesn't change the structure or semantics of the document."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- whitespace-insignificant-rule&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does this mean?&lt;/p&gt;

&lt;p&gt;First, let us define &lt;em&gt;whitespace&lt;/em&gt;: Whitespace is any set of one or more consecutive spaces, tabs, new lines, and other Unicode characters that represent space.&lt;/p&gt;

&lt;p&gt;In our context, the above rule means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Within text, a set of &lt;em&gt;several&lt;/em&gt; (i.e. more than one) whitespace characters is treated the same as a &lt;em&gt;single&lt;/em&gt; space character.&lt;/p&gt;

&lt;p&gt;For example, this code:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a beautiful
    flower
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... is identical to this one:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a beautiful flower
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Between structural elements, a set of whitespace characters is insignificant.&lt;/p&gt;

&lt;p&gt;For example, this code:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;

    &amp;lt;tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... is identical to this one:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A special case of whitespace is &lt;em&gt;indentation&lt;/em&gt; (leading whitespace at the beginning of a line). The above rule implies that indentation is insignificant too. Indentation doesn't change the result of the final document.&lt;/p&gt;

&lt;p&gt;Applying the &lt;em&gt;whitespace-insignificant&lt;/em&gt; rule is important, because it leads to significant advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There is no need to learn, apply and worry about complex whitespace rules (see examples below).&lt;/p&gt;

&lt;p&gt;Violating the &lt;em&gt;whitespace-insignificant&lt;/em&gt; rule in a markup specification adds unneeded complexity, and can lead to markup code that is ugly, error-prone, and difficult to maintain, especially in the case of nested lists.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whitespace can freely be used by authors to format the markup code in a more understandable, presentable and attractive way (pretty printing). For example, lists (and lists of lists) can be indented to display their structure in a visually clear and maintainable way, without the risk of changing the underlying structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Text blocks can be copy/pasted without the need to adapt whitespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If shared text blocks (stored in different files) are imported into several documents with different structures, there is no risk of changing or breaking the structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is no unexpected or obscure behavior if the whitespace is not visible for human readers. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  a mixture of whitespace characters, such as spaces and tabs, especially when used to indent code&lt;/li&gt;
&lt;li&gt;  whitespace at the end of a line&lt;/li&gt;
&lt;li&gt;  whitespace in empty lines&lt;/li&gt;
&lt;li&gt;  visually impaired (blind) people who can't read whitespace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: To alleviate the pain, some editors provide a &lt;em&gt;display-whitespace&lt;/em&gt; mode.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Tools that generate markup code, as well as markup parsers are generally easier to create.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;In some situations it is useful to reduce whitespace to a minimum (e.g. no new lines), in order to save storage space and improve performance.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you want a few examples demonstrating the kind of technical problems that arise if whitespace is significant, you can read:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.quora.com/What-are-the-downsides-to-whitespace-indentation-rather-than-requiring-curly-braces" rel="noopener noreferrer"&gt;What are the downsides to whitespace indentation rather than requiring curly braces?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://fsharpforfunandprofit.com/posts/fsharp-syntax/" rel="noopener noreferrer"&gt;F# syntax: indentation and verbosity&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nodeca/js-yaml/issues/80" rel="noopener noreferrer"&gt;Issue in nodeca/js-yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, how is whitespace handled in the languages we are discussing in this article?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML&lt;/p&gt;

&lt;p&gt;HTML applies the &lt;em&gt;whitespace-insignificant&lt;/em&gt; rule.&lt;/p&gt;

&lt;p&gt;For a thorough explanation, look at this excellent article written by Patrick Brosset: &lt;a href="https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33" rel="noopener noreferrer"&gt;When does white space matter in HTML?&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Asciidoctor&lt;/p&gt;

&lt;p&gt;In Asciidoctor, whitespace is significant in some cases.&lt;/p&gt;

&lt;p&gt;This can lead to surprising behavior and problems with no easy or no satisfying solution. Some examples can be seen &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/686" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/asciidoctor/asciidoctor/issues/623" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reStructuredText&lt;/p&gt;

&lt;p&gt;reStructuredText has whitespace rules that are 'a bit surprising'.&lt;/p&gt;

&lt;p&gt;For example, writing &lt;code&gt;*very*&lt;/code&gt; results in &lt;em&gt;very&lt;/em&gt; (text in italics, as expected). However, &lt;code&gt;* very*&lt;/code&gt; results in * very* (no italics!), because of the whitespace preceding "very". To understand why, the answer might be found in chapter &lt;a href="http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#whitespace" rel="noopener noreferrer"&gt;Whitespace&lt;/a&gt; of the specification.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PML&lt;/p&gt;

&lt;p&gt;Similar to HTML, PML applies the &lt;em&gt;whitespace-insignificant&lt;/em&gt; rule.&lt;/p&gt;

&lt;p&gt;There is one exception: For practical reasons, a blank line between two text blocks results in a paragraph break. This means that instead of writing:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{p text of paragraph 1}
{p text of paragraph 2}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... we can simply write:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text of paragraph 1

text of paragraph 2
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note&lt;/p&gt;

&lt;p&gt;Sometimes, whitespace &lt;em&gt;is&lt;/em&gt; significant in text. For example whitespace must be preserved in source code examples. Or, in verbatim text, several consecutive spaces or new lines must be preserved in the final document. All languages support this. However, in reStructuredText it's not always obvious how to it, as shown &lt;a href="https://stackoverflow.com/questions/51198270/how-do-i-create-a-new-line-with-restructuredtext" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Inconveniences
&lt;/h2&gt;

&lt;p&gt;As seen already, some markup languages systematically use opening and closing tags. An example would be &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;/i&amp;gt;&lt;/code&gt; in HTML. All XML-based languages, as well as PML belong to this class of languages.&lt;/p&gt;

&lt;p&gt;Without digging into details, here are some drawbacks that can occur in languages that do &lt;em&gt;not&lt;/em&gt; (or not always) use pairs of distinct opening/closing tags (e.g. Markdown, Asciidoctor, and reStructuredText):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Editor support&lt;/p&gt;

&lt;p&gt;Creating good, reliable editor support is more difficult to develop. Examples of useful editor features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  syntax highlighting for markup code&lt;/li&gt;
&lt;li&gt;  markup code completion&lt;/li&gt;
&lt;li&gt;  visualizing pairs of block start/end marks (e.g. &lt;code&gt;{&lt;/code&gt; and its corresponding &lt;code&gt;}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  block collapsing/expanding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the case of languages that use distinct opening/closing tags, the two last features work out-of-the-box in some editors. For example, PML uses &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;}&lt;/code&gt; for node boundaries. This is also used in many programming languages (C, Java, Javascript, etc.) and therefore block features implemented for programming languages will also work for PML.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Document validation&lt;/p&gt;

&lt;p&gt;Fewer syntax and structure errors can be detected automatically. This can lead to more time spent on debugging documents. Or, even worse, there might be silently ignored errors that end up in wrong output (Did I really fail to spot the missing warning block on page 267 of my 310 pages book?).&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Parsers&lt;/p&gt;

&lt;p&gt;It is more difficult to create parsers (i.e. programs that read markup code) that work well in all cases. If different parsers read the same markup code, there is an increased risk of getting different results for corner-cases.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Auto-generated markup code&lt;/p&gt;

&lt;p&gt;Tools that generate markup code programmatically are more difficult to create. For example, if whitespace is significant, or font styles cannot be nested, then additional state must be updated and tracked, in order to respect these rules.&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  My Own Experience
&lt;/h1&gt;

&lt;p&gt;When I started writing technical documents a few years ago, I used Docbook. It took me some time to learn it, but after that I never stumbled on anything I couldn't do. Docbook is powerful. However, I disliked typing verbose XML code. I tried some XML editors, but gave up. Finally I just wrote complete text blocks unformatted in Notepad++, and then adorned the text with the necessary markup code. It was frustrating and time-consuming. Moreover, I couldn't find a stylesheet that produced good-looking web documents, and I didn't have the patience, motivation, and experience to fiddle around with big, complex CSS files and adapt them.&lt;/p&gt;

&lt;p&gt;Later on I discovered Asciidoctor. What a relief. Everything was so much simpler and the web documents were beautiful, out of the box. Asciidoctor's documentation is great, and I think the community is helpful and active. However, when I started to write more complex and bigger documents, I had to deal with problems similar to those described in the previous chapters. At one point, I had to develop a specific pre- and post-processor to solve a problem for which I couldn't find a solution in Asciidoctor/Gitbook.&lt;/p&gt;

&lt;p&gt;An intriguing question emerged: "Why do these problems not exist in Docbook?".&lt;/p&gt;

&lt;p&gt;To make a long story short, I concluded that we need a new markup syntax. The key points to success would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;easy to learn: few, simple, consistent and predictable rules (no exceptions)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;easy to write and read&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;well-structured documents with no ambiguities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;powerful enough to create big, complex documents without the need for "special rules, tricks, or workarounds"&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a period of investigating, pondering, programming, testing and improving, the &lt;a href="http://www.practical-programming.org/pml/index.html" rel="noopener noreferrer"&gt;Practical Markup Language (PML)&lt;/a&gt; was born. Since then, I never looked back again. Today I write all my web documents in PML (including this article). Of course, when I started to create PML, it was to cover my own needs. So, I am probably biased. I tried my best to write an article based on &lt;em&gt;facts&lt;/em&gt;, but I encourage you to leave a comment if you see anything wrong, unfair, or missing in this article. I appreciate constructive feedback of any kind, and I will update the article if needed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As demonstrated in this article, a good number of problems encountered with existing document markup languages vanish with the PML syntax.&lt;/p&gt;

&lt;p&gt;Now we should come together to improve PML and make it more powerful, so that it covers more use cases and more people can benefit from it.&lt;/p&gt;

&lt;p&gt;Please help to spread the word. Or try out PML and send feedback, so that we know what needs to be refined. Your voice counts!&lt;/p&gt;

&lt;p&gt;The vision is to create the best possible document markup language and all necessary tools, so that writers can focus on writing and enjoy creating beautiful documents in a minimum of time - without worrying about unneeded complexity.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>markup</category>
      <category>markdown</category>
      <category>asciidoctor</category>
    </item>
    <item>
      <title>Advantages of Document Markup Languages vs WYSIWYG Editors</title>
      <dc:creator>Christian Neumanns</dc:creator>
      <pubDate>Thu, 07 Mar 2019 06:18:57 +0000</pubDate>
      <link>https://dev.to/practicalprogramming/advantages-of-document-markup-languages-vs-wysiwyg-editors-9f6</link>
      <guid>https://dev.to/practicalprogramming/advantages-of-document-markup-languages-vs-wysiwyg-editors-9f6</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Did you ever wonder what's the best tool to write an article, user manual, book, or any other kind of text document?&lt;/p&gt;

&lt;p&gt;There are many options to choose from. Most people use a &lt;em&gt;What-You-See-Is-What-You-Get (WYSIWYG)&lt;/em&gt; editor (also called a &lt;em&gt;text processor&lt;/em&gt;), such as Google Docs, LibreOffice or Word. However, more and more people are writing their documents using another, less known option: a &lt;em&gt;document markup language&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Should you, too, use a document markup language instead of a WYSIWYG editor? Let's see.&lt;/p&gt;

&lt;p&gt;Note: This article does not compare or evaluate different writing solutions/products. It will not tell you why product X is better than product Y. The purpose of this article is to point out &lt;em&gt;general&lt;/em&gt; advantages of document markup languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  WYSIWYG Editors
&lt;/h1&gt;

&lt;p&gt;Offline or online WYSIWYG editors are often the best solution for non-technical people who occasionally write short or medium-size documents. Some websites have their own WYSIWYG editor integrated in the website, which makes it very easy to write formatted text. WYSIWYG software is also the right choice for design-intensive publications where you want to have total control of the position, size, font, and other visual properties of the document's elements, and you want to immediately see and trim the end result while working on the document. Examples of such documents are flyers, advertisements, party invitations, posters, etc.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/List_of_word_processors" rel="noopener noreferrer"&gt;many&lt;/a&gt; word processors to choose from.&lt;/p&gt;

&lt;p&gt;Some word processors offer advanced features for particular tasks, such as writing a novel.&lt;/p&gt;

&lt;p&gt;However, as said already, this article focuses on markup languages, so let's move on and see why many people prefer them over WYSIWYG editors.&lt;/p&gt;

&lt;h1&gt;
  
  
  Document Markup Languages
&lt;/h1&gt;

&lt;p&gt;Note: Readers familiar with markup languages can skip the following two chapters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Concept
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;document markup language&lt;/em&gt; consists of a set of rules and symbols (special characters) used to annotate plain text. The annotated text can then be read by a &lt;em&gt;markup processor&lt;/em&gt; to generate styled documents (e.g. HTML, PDF, ePub, etc.) or any other kind of data.&lt;/p&gt;

&lt;p&gt;For example, in some markup languages an underline (&lt;code&gt;_&lt;/code&gt;) is used to emphasize text and render it in italics. Writing:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A _good_ girl.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;... results in:&lt;br&gt;&lt;br&gt;
A &lt;em&gt;good&lt;/em&gt; girl.&lt;/p&gt;

&lt;p&gt;Hence, &lt;em&gt;markup code&lt;/em&gt; is just plain text intermixed with markup instructions.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;markup document&lt;/em&gt; consists of one or more text files that contain markup code.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/List_of_document_markup_languages" rel="noopener noreferrer"&gt;many&lt;/a&gt; document markup languages to choose from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Example
&lt;/h2&gt;

&lt;p&gt;Suppose you create a text file with the following content (written in Markdown syntax):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Simple Markup Example

This is just a _simpe_ example.

Here is a list:

- orange
- banana
- apple
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the above text has been converted to HTML (by the markup processor), the result in the browser looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgn76npgs18pwx77omtjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgn76npgs18pwx77omtjb.png" alt="Simple example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The style of the final document can be customized. This is often done by modifying a separate CSS files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ubiquitous Advantages
&lt;/h3&gt;

&lt;p&gt;All document markup languages work like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A markup document consists of &lt;em&gt;plain text.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Content and presentation are defined in &lt;em&gt;separate&lt;/em&gt; files.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;content&lt;/em&gt; file contains the text and markup instructions. The &lt;em&gt;presentation&lt;/em&gt; file contains the stylesheet (e.g. a CSS file).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It turns out that these two simple concepts lead to an astonishing set of practical advantages, explained in the following chapters.&lt;/p&gt;

&lt;h4&gt;
  
  
  Distraction-Free Writing
&lt;/h4&gt;

&lt;p&gt;When you write, you focus on content, not on presentation. You focus on what you want to say, instead of how it should be displayed or printed.&lt;/p&gt;

&lt;p&gt;Moreover, you can customize your writing environment (editor) without worrying about the end result. For example, you can use a different font and a different number of characters displayed per line, without thinking about how this will affect the final document.&lt;/p&gt;

&lt;p&gt;Thus, when you write, it's easier to &lt;em&gt;be in the flow (in the zone)&lt;/em&gt;, which Wikipedia &lt;a href="https://en.wikipedia.org/wiki/Flow_(psychology)" rel="noopener noreferrer"&gt;describes&lt;/a&gt; as a &lt;em&gt;"mental state of operation in which a person performing an activity is fully immersed in a feeling of energized focus, full involvement, and enjoyment in the process of the activity"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is a big deal!&lt;/p&gt;

&lt;h4&gt;
  
  
  Choice of Editor
&lt;/h4&gt;

&lt;p&gt;You can use &lt;em&gt;your&lt;/em&gt; preferred &lt;a href="https://en.wikipedia.org/wiki/List_of_text_editors" rel="noopener noreferrer"&gt;text editor&lt;/a&gt; or Integrated Development Environment (IDE) to write your document. You are not tied to a specific editor. There is no vendor lock-in.&lt;/p&gt;

&lt;p&gt;Imagine a team of writers collaborating on the same document. Everybody just uses the text editor he/she likes the most for the task at hand. For example, Bob and Alice are working on a new user manual, but Bob uses Emacs on Linux, while Alice uses Notepad++ on Windows.&lt;/p&gt;

&lt;p&gt;Some high-end text editors provide incredibly powerful features (some out-of-the-box, some via extensions) and are highly customizable, so that you can setup your ideal writing software. As a result, you have a more enjoyable writing experience and you are more productive than with a WYSIWYG editor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choice of Presentation
&lt;/h4&gt;

&lt;p&gt;Because content and presentation are defined in separate files, you can change presentation by simply choosing another stylesheet (e.g. CSS file) from a predefined set, and adapt it if needed. If your document is read on different reading/printing devices, you can use different presentations for each device.&lt;/p&gt;

&lt;p&gt;Sometimes the same stylesheet is used for many documents. Thus, presentation remains consistent over large sets of documents. Moreover, global presentation changes can often be done in a matter of seconds, because only one file needs to be changed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choice of Transformation
&lt;/h4&gt;

&lt;p&gt;Depending on the language and tools you use, you can transform your markup code into final documents of different formats, such as HTML, PDF, ePub etc.&lt;/p&gt;

&lt;p&gt;And if your tool can't do it, there is &lt;a href="http://pandoc.org/" rel="noopener noreferrer"&gt;Pandoc&lt;/a&gt;, the swiss-army-knife for document conversions. At the time of writing, Pandoc can convert not less than 31 input formats into not less than 49 output formats. That's 31 x 49 = 1,519 transformations supported by one tool.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choice of Text Tools
&lt;/h4&gt;

&lt;p&gt;There are many tools and online services available to handle plain text files - some possibly pre-installed on your PC. You can use them to handle your markup documents, in whatever way you want.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can use a version control service such as Github, Gitlab, or Bitbucket to track changes and issues, collaborate on documents, synchronize documents on different devices, and use all other powerful features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To get an idea of free tools for technical people, look at this &lt;a href="https://en.wikibooks.org/wiki/Guide_to_Unix/Commands/Text_Processing" rel="noopener noreferrer"&gt;List of Unix Text Processing Tools&lt;/a&gt;. Nowadays, you can also easily install these Linux tools on Windows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Customized Tools
&lt;/h4&gt;

&lt;p&gt;Reading and writing plain text files is very well supported in most programming languages. Therefore it is easier for programmers to develop customized tools to explore and manipulate documents.&lt;/p&gt;

&lt;p&gt;For instance, pre-processors and post-processors can be created to add features and automate recurring tasks. A concrete example would be a tool that displays a sorted list of website links used in your document and checks for any broken links.&lt;/p&gt;

&lt;p&gt;Moreover, it is easy to &lt;em&gt;programmatically create&lt;/em&gt; documents. For instance, a product catalog or a reference manual could be created automatically based on structured data stored in a database.&lt;/p&gt;

&lt;h4&gt;
  
  
  Portability
&lt;/h4&gt;

&lt;p&gt;As content and presentation is defined in plain text files, documents are portable among different operating systems (Windows, Unix/Linux, macOS, etc.). All operating systems have very good support for text files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Language-Dependant Advantages
&lt;/h3&gt;

&lt;p&gt;In this chapter we'll look at additional advantages found in &lt;em&gt;some&lt;/em&gt; document markup languages.&lt;/p&gt;

&lt;h4&gt;
  
  
  File Splitting
&lt;/h4&gt;

&lt;p&gt;Some markup languages allow you to split a document into different files.&lt;/p&gt;

&lt;p&gt;For example, each chapter of a book (and maybe also each sub-chapter) can be stored in a different file and in a directory hierarchy of your choice.&lt;/p&gt;

&lt;p&gt;This can be a game-changer when a team collaborates on mid-size or big documents, because it makes editing, reorganizing, and collaborating much more convenient.&lt;/p&gt;

&lt;h4&gt;
  
  
  Semantic Markup
&lt;/h4&gt;

&lt;p&gt;Some document markup languages support only &lt;em&gt;presentation&lt;/em&gt; tags. The better breed of them prefer &lt;em&gt;semantic&lt;/em&gt; tags over &lt;em&gt;presentation&lt;/em&gt; tags. This means that, when you use markup, you specify the &lt;em&gt;meaning&lt;/em&gt; of a piece of text. You do not specify &lt;em&gt;how&lt;/em&gt; the text will be displayed or printed. You define the &lt;em&gt;What&lt;/em&gt;, not the &lt;em&gt;How&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A first benefit is that this leads to much more flexibility in the rendering process.&lt;/p&gt;

&lt;p&gt;Suppose your text contains several warning messages that need to stand out. If you use a markup language that supports only &lt;em&gt;presentation&lt;/em&gt; tags, you could decide to aggressively display a centered text in red on yellow, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3uek43av4k02n6c6d7bu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3uek43av4k02n6c6d7bu.png" alt="Coffee machine warning"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This works well if the warnings are displayed on a color screen. But if the document is printed on a color-less printer, or displayed on a black-and-white e-ink device, the result is a mess.&lt;/p&gt;

&lt;p&gt;On the other hand, in a markup language that provides &lt;em&gt;semantic&lt;/em&gt; tags, you would simply adorn your warnings with a &lt;code&gt;warning&lt;/code&gt; tag. The stylesheet used in the conversion process specifies &lt;em&gt;how&lt;/em&gt; all warnings are displayed. Hence, you can globally change the presentation of all warnings for a given output device by simply changing &lt;em&gt;one&lt;/em&gt; entry in the corresponding stylesheet. For example, in the stylesheet used for e-ink devices, you could specify to display the warnings in &lt;strong&gt;&lt;em&gt;italics with a bigger font&lt;/em&gt;&lt;/strong&gt;. Moreover, if you have other messages that have to stand out, like errors or tips, you can use different, specific tags and handle them separately, without any interference.&lt;/p&gt;

&lt;p&gt;A second advantage is that semantic markup opens the door for searchable documentation databases. You can query your markup code and extract useful information. For example, you could create a tool to count the number of warnings contained in the document or extract and save the warnings in a separate file for further exploration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parameters
&lt;/h4&gt;

&lt;p&gt;Advanced markup languages support &lt;em&gt;parameters&lt;/em&gt; embedded in the markup code. You first define a parameter by assigning a value to a name (e.g. &lt;code&gt;my_email=foo@example.com&lt;/code&gt;). Then, later in the document, you use the parameter name, instead of the value. If the value changes later, you just need to change it in one place, which is easy, fast, and less error-prone.&lt;/p&gt;

&lt;p&gt;This is an application of the important &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;Don't Repeat Yourself (DRY)&lt;/a&gt; principle. It improves maintainability, productivity, and reliability. It is useful for all kinds of recurring text and markup attribute values, especially if they are subject to change. For example: your email address, the price of your product, the name of your dog, or whatever.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advanced Features
&lt;/h4&gt;

&lt;p&gt;Here is a brief summary of additional powerful options:&lt;/p&gt;

&lt;h5&gt;
  
  
  Real-time preview
&lt;/h5&gt;

&lt;p&gt;Sometimes it is convenient to see a preview of the final document (e.g. a HTML page) &lt;em&gt;while&lt;/em&gt; typing the markup code. As soon as you edit the markup code, you can immediately see the effect, without the need to re-launch the markup processor. Some editors support this kind of immediate feedback out-of-the-box or by plugins. For example, you type the document in one window, and you see the real-time preview in an adjacent window.&lt;/p&gt;

&lt;p&gt;You can think of this as a markup editor with WYSIWYG support.&lt;/p&gt;

&lt;h5&gt;
  
  
  Public API
&lt;/h5&gt;

&lt;p&gt;A public &lt;em&gt;Application Program Interface (API)&lt;/em&gt; allows programmers to programmatically execute, change, or extend the markup processor's operations.&lt;/p&gt;

&lt;p&gt;At the bare minimum, an API enables other applications to convert documents. For example, a web server could read markup code stored in a file or entered by the user and convert it to HTML on-the-fly, by using the API. This could be used, for instance, to provide an online markup tester, so that people can try out snippets of markup code, without the need to install anything on their PC.&lt;/p&gt;

&lt;p&gt;More advanced APIs can provide additional functionality, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Change the rendering of some tags&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add more tags to the language&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add more output formats to the converter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a markup document programmatically, by retrieving data from different sources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hooks (also called extension points)&lt;/p&gt;

&lt;p&gt;Hooks allow programmers to execute functions when specific events occur.&lt;/p&gt;

&lt;p&gt;For example, once the &lt;em&gt;Abstract Syntax Tree (AST)&lt;/em&gt; (i.e. tree structure) of the document has been created by the markup processor, an extension point can programmatically explore the AST to extract and report useful information, or even change it to implement the most extravagant requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Templates
&lt;/h5&gt;

&lt;p&gt;Templates allow you to customize or redefine the rendering of specific tags, by modifying text files containing the template code.&lt;/p&gt;

&lt;h5&gt;
  
  
  User-defined tags
&lt;/h5&gt;

&lt;p&gt;You can use configuration files to extend the language and add your own tags to the markup language, and specify how each tag is rendered.&lt;/p&gt;

&lt;h5&gt;
  
  
  Processor Directives
&lt;/h5&gt;

&lt;p&gt;Processor Directives are special instructions inserted in the markup code and interpreted by the markup processor.&lt;/p&gt;

&lt;p&gt;Suppose somebody writes a test sheet for students. The sheet contains instructions that should only be visible for teachers. In that case, a directive could be used to display specific text blocks only if the document is printed for teachers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Further readings
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The advice of a technical writer who uses an "über-powerful text editor" (spoiler: Emacs) and doesn't like the mouse: &lt;a href="http://www.alandmoore.com/blog/2012/08/08/how-and-why-to-dump-your-word-processor/" rel="noopener noreferrer"&gt;How and Why to Dump Your Word Processor&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The title says it all: &lt;a href="http://ricardo.ecn.wfu.edu/~cottrell/wp.html" rel="noopener noreferrer"&gt;Word Processors: Stupid and Inefficient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An interesting article for novel writers (followed by some insightful comments): &lt;a href="https://thewritepractice.com/book-writing-software-word-vs-scrivener/" rel="noopener noreferrer"&gt;Best Book Writing Software: Word vs. Scrivener&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will soon publish a follow-up article with more specific information and comparisons of different document markup languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Should you use a WYSIWYG editor or a markup language?&lt;/p&gt;

&lt;p&gt;As so often, the answer depends on your use case.&lt;/p&gt;

&lt;p&gt;However, as demonstrated in this article, in many cases a document markup language is the better choice, because you can benefit from numerous advantages. In a nutshell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When you write, you can &lt;em&gt;focus on writing&lt;/em&gt;, because you don't have to think about presentation, and you can use your preferred text editor with your customized setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your writing environment is &lt;em&gt;more flexible and powerful&lt;/em&gt;, because you have a lot of options to handle plain text files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is easier to &lt;em&gt;automate and customize&lt;/em&gt; your writing process, which saves time and reduces errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately, a well-designed document markup language makes your writing experience more enjoyable and increases your productivity.&lt;/p&gt;

&lt;p&gt;What's your own experience? Please share it by leaving a comment.&lt;/p&gt;

&lt;p&gt;Note: For more insight, please read &lt;a href="https://dev.to/practicalprogramming/we-need-a-new-document-markup-language---here-is-why-5d4c"&gt;We Need a New Document Markup Language - Here is Why&lt;/a&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>markup</category>
      <category>editor</category>
      <category>markdown</category>
    </item>
  </channel>
</rss>
