{"id":5152,"date":"2017-01-28T20:48:10","date_gmt":"2017-01-28T20:48:10","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/immutable-data\/"},"modified":"2024-07-22T16:31:13","modified_gmt":"2024-07-22T16:31:13","slug":"immutable-data","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/immutable-data\/","title":{"rendered":"Immutable Data"},"content":{"rendered":"<p>A key to purely functional languages is that their data are immutable. Therefore, assignments such as<span style=\"font-family: courier new,courier;\"> x= x+1<\/span> or <span style=\"font-family: courier new,courier;\">++x<\/span> are not possible in the purely functional language Haskell. The consequence is that Haskell supports no loops like <span style=\"font-family: courier new,courier;\">for,<\/span> <span style=\"font-family: courier new,courier;\">while,<\/span> or <span style=\"font-family: courier new,courier;\">until.<\/span> They are based on the modification of a loop variable. Haskell does not modify existing data; Haskell creates new data when needed and reuses the old ones.<\/p>\n<p><!--more--><\/p>\n<h2>Immutable data<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5151\" style=\"margin: 15px;\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeImmutableDataEng.png\" alt=\"CharakteristikeImmutableDataEng\" width=\"443\" height=\"432\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeImmutableDataEng.png 443w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/CharakteristikeImmutableDataEng-300x293.png 300w\" sizes=\"auto, (max-width: 443px) 100vw, 443px\" \/><\/p>\n<p>Immutable data has a lovely property. They are implicitly thread-safe because they miss a necessary condition for a<a href=\"https:\/\/www.modernescpp.com\/index.php\/threads-sharing-data\"> data race.<\/a> A data race is a state, in which at least two threads access shared data at the same time, and at least one of the threads is a writer.<\/p>\n<h3>Quicksort in Haskell<\/h3>\n<p>The quicksort algorithm in Haskell shows the immutability of data very nicely.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">qsort <span style=\"color: #2b91af;\">[]<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #2b91af;\">[]<\/span>\nqsort (x<span style=\"color: #2b91af;\">:<\/span>xs) <span style=\"color: #0000ff;\">=<\/span> qsort [y | y <span style=\"color: #0000ff;\">&lt;-<\/span> xs, y &lt; x] ++ [x] ++ qsort [y | y <span style=\"color: #0000ff;\">&lt;-<\/span> xs, y &gt;= x]\n<\/pre>\n<\/div>\n<p>The quicksort algorithm <span style=\"font-family: courier new,courier;\">qsort<\/span> consists of two function definitions. The quicksort will be applied to the empty list in the first line. Of course, the result is an empty list. In the second line, there is the general case in which the list consists of at least one element: <span style=\"font-family: courier new,courier;\">x: xs. x<\/span> is the first element in the list, and <span style=\"font-family: courier new,courier;\">xs<\/span> is the reminder by convention.<\/p>\n<p>The quicksort algorithm strategy can be directly applied to Haskell.<\/p>\n<ul>\n<li>Use the first element of the list x, the so-called pivot element, and make a list with one element out of it:<span style=\"font-family: courier new,courier;\"> &#8230; [x] &#8230;<\/span><\/li>\n<li>Add (++) all elements before the list <span style=\"font-family: courier new,courier;\">[x]<\/span> that are smaller than x: <span style=\"font-family: courier new,courier;\">qsort [y | y &lt;- xs, y &lt; x]<\/span>)\u00a0 <span style=\"font-family: courier new,courier;\">++ [x] &#8230;<\/span><\/li>\n<li>Add (++) all elements after the list<span style=\"font-family: courier new,courier;\"> [x] <\/span>that are equal or bigger than<span style=\"font-family: courier new,courier;\"> x:<\/span><span style=\"font-family: courier new,courier;\"> &#8230;[x] ++ (<span style=\"font-family: courier new,courier;\">qsort [y | y &lt;- xs, y &gt;= x]<\/span>)<\/span><\/li>\n<li>The recursion will end if quicksort is applied to the empty list.<\/li>\n<\/ul>\n<p>Admittedly, the imperative eye is not used to the conciseness of Haskell.<\/p>\n<p>The critical point of the algorithm is that each recursion creates a new list. How does an implementation in C or C++ look like?<\/p>\n<h3>Quicksort in C++<\/h3>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #2b91af;\">void<\/span> quickSort(<span style=\"color: #2b91af;\">int<\/span> arr[], <span style=\"color: #2b91af;\">int<\/span> left, <span style=\"color: #2b91af;\">int<\/span> right) { \n  <span style=\"color: #2b91af;\">int<\/span> i = left, j = right; \n  <span style=\"color: #2b91af;\">int<\/span> tmp; \n  <span style=\"color: #2b91af;\">int<\/span> pivot = arr[abs((left + right) \/ 2)]; \n  <span style=\"color: #0000ff;\">while<\/span> (i &lt;= j) { \n    <span style=\"color: #0000ff;\">while<\/span> (arr[i] &lt; pivot) i++; \n    <span style=\"color: #0000ff;\">while<\/span> (arr[j] &gt; pivot) j--; \n    <span style=\"color: #0000ff;\">if<\/span> (i &lt;= j) { \n      tmp = arr[i]; \n      arr[i] = arr[j]; \n      arr[j] = tmp; \n      i++; j--; \n    }\n  }\n  <span style=\"color: #0000ff;\">if<\/span> (left &lt; j) quickSort(arr, left, j);\n  <span style=\"color: #0000ff;\">if<\/span> (i &lt; right) quickSort(arr, i, right);\n}\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>No worries. I will not try to explain the algorithm.\u00a0 A simple observation is enough for me. The elements are overwritten in lines 9 &#8211; 11. The algorithm works in place and needs, therefore, mutable data. There exists an excellent term in the functional programming for this overwriting:\u00a0 <strong>destructive<\/strong> <strong>assignment.<\/strong><\/p>\n<p>That was an implementation of the quicksort algorithm in C. With C++, we can do better if I use the <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/algorithm\/partition\"><span style=\"font-family: courier new,courier;\">std::partition.<\/span><\/a><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">ForwardIt<\/span>&gt;\n <span style=\"color: #2b91af;\">void<\/span> quicksort(ForwardIt first, ForwardIt last)\n {\n    <span style=\"color: #0000ff;\">if<\/span>(first == last) <span style=\"color: #0000ff;\">return<\/span>;\n    <span style=\"color: #0000ff;\">auto<\/span> pivot = *std::next(first, std::distance(first,last)\/2);\n    ForwardIt middle1 = std::partition(first, last, \n                         [pivot](<span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">auto<\/span>&amp; em){ <span style=\"color: #0000ff;\">return<\/span> em &lt; pivot; });\n    ForwardIt middle2 = std::partition(middle1, last, \n                         [pivot](<span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #0000ff;\">auto<\/span>&amp; em){ <span style=\"color: #0000ff;\">return<\/span> !(pivot &lt; em); });\n    quicksort(first, middle1);\n    quicksort(middle2, last);\n }\n<\/pre>\n<\/div>\n<p>But once more. The critical point is that I also use destructive assignment in <span style=\"font-family: courier new,courier;\">std::partition<\/span><em>. <\/em>If you look very carefully, the strategy of the C++ version is not so different from that of the Haskell version.<em><br \/>\n<\/em><\/p>\n<p>What is the story about immutability in C++?<\/p>\n<h3>Immutable data in C++<\/h3>\n<p>Using immutable data in C++ is based on the programmer&#8217;s discipline. With constant data, template metaprogramming, and constant expressions, you have three ways to express immutability. Options one and two are quite easy to present, but constant expressions deserve more attention.<\/p>\n<h4>Constant data<\/h4>\n<p>By using the instruction<span style=\"font-family: courier new,courier;\"> const int value= 1;<\/span> <span style=\"font-family: courier new,courier;\">value<\/span> becomes immutable data.<\/p>\n<h4>Template metaprogramming<\/h4>\n<p>Template metaprogramming takes place at compile time. At compile time, there is no mutation. Therefore, all values that are calculated at compile time are immutable. Of course, that holds true for the calculation of <span style=\"font-family: courier new,courier;\">Factorial::5<\/span> at compile time.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #2b91af;\">int<\/span> N&gt;\n<span style=\"color: #0000ff;\">struct<\/span> Factorial{\n  <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #2b91af;\">int<\/span> <span style=\"color: #0000ff;\">const<\/span> value= N * Factorial&lt;N-1&gt;::value;\n};\n\n<span style=\"color: #0000ff;\">template<\/span> &lt;&gt;\n<span style=\"color: #0000ff;\">struct<\/span> Factorial&lt;1&gt;{\n  <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #2b91af;\">int<\/span> <span style=\"color: #0000ff;\">const<\/span> value = 1;\n};\n\nstd::cout &lt;&lt; Factorial&lt;5&gt;::value &lt;&lt; std::endl;\nstd::cout &lt;&lt; 120 &lt;&lt; std::endl;\n<\/pre>\n<\/div>\n<p>If the short notice to template programming was too short, please read the post <a href=\"https:\/\/www.modernescpp.com\/index.php\/functional-in-c-98\">Functional in C++98.<\/a><\/p>\n<p>But now, back into the future of C++: constant expressions.<\/p>\n<h4>Constant expressions<\/h4>\n<p>C++11 supports constant expressions. With C++14, you can declare functions as constant expressions that behave almost as usual functions.<\/p>\n<p>C++ supports constant expressions in three variations: variables, user-defined types, and functions. The special feature of constant expressions is that they can be evaluated at compile time.<\/p>\n<ol>\n<li>By using <span style=\"font-family: courier new,courier;\">constexpr double pi= 3.14<\/span>\u00a0 <span style=\"font-family: courier new,courier;\">pi<\/span> becomes a constant expression. <span style=\"font-family: courier new,courier;\">pi<\/span> is, therefore, implicit <span style=\"font-family: courier new,courier;\">const<\/span> and has to be initialized by a constant expression:\u00a0 <span style=\"font-family: courier new,courier;\">3.14.<\/span><\/li>\n<li>There are a few restrictions for a user-defined type so that the instances of the user-defined type become constant expressions. For example, the constructor has to be empty and have a constant expression. The instance can only use methods that are constant expressions. Of course, you can not invoke a virtual method at compile time. If a user-defined type fulfills all requirements, you can instantiate and use its objects simultaneously.<\/li>\n<li>To execute functions in C++14 at compile time, they must follow a few rules. First, their arguments must be constant expressions. Second, they can not use static or thread-local data.<\/li>\n<\/ol>\n<p>The following example shows the power of constant expressions. I use user-defined literals to calculate all distances at compile time.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ userdefinedLiteralsConstexpr.cpp<\/span>\n\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #0000ff;\">namespace<\/span> Distance{\n\n  <span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyDistance<\/span>{\n    public:\n      constexpr MyDistance(<span style=\"color: #2b91af;\">double<\/span> i):m(i){}\n\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>+(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m + b.m);\n      }\n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>-(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a,<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; b){\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m - b.m);\n      }\n\t  \n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>*(<span style=\"color: #2b91af;\">double<\/span> m, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a){\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(m*a.m);\n      }\n\t  \n      <span style=\"color: #0000ff;\">friend<\/span> constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span>\/(<span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; a, <span style=\"color: #2b91af;\">int<\/span> n){\n        <span style=\"color: #0000ff;\">return<\/span> MyDistance(a.m\/n);\n      }\n\t  \n      <span style=\"color: #0000ff;\">friend<\/span> std::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt; (std::ostream &amp;out, <span style=\"color: #0000ff;\">const<\/span> MyDistance&amp; myDist){\n        out &lt;&lt; myDist.m &lt;&lt; <span style=\"color: #a31515;\">\" m\"<\/span>;\n        <span style=\"color: #0000ff;\">return<\/span> out;\n      }\n    private:\n      <span style=\"color: #2b91af;\">double<\/span> m;\t  \n  };\n\n  <span style=\"color: #0000ff;\">namespace<\/span> Unit{\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _km(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(1000*d);\n    }\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _m(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> m){\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(m);\n    }\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _dm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> d){\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(d\/10);\n    }\n    constexpr MyDistance <span style=\"color: #0000ff;\">operator<\/span> <span style=\"color: #a31515;\">\"\"<\/span> _cm(<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">double<\/span> c){\n      <span style=\"color: #0000ff;\">return<\/span> MyDistance(c\/100);\n    }\n  }\n  \n}\n  \nconstexpr Distance::MyDistance getAverageDistance(std::initializer_list&lt;Distance::MyDistance&gt; inList){\n  <span style=\"color: #0000ff;\">auto<\/span> sum= Distance::MyDistance{0.0};\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #0000ff;\">auto<\/span> i: inList) sum = sum + i ;\n  <span style=\"color: #0000ff;\">return<\/span> sum\/inList.size(); \n}\n\n\n<span style=\"color: #0000ff;\">using<\/span> <span style=\"color: #0000ff;\">namespace<\/span> Distance::Unit;\n\n<span style=\"color: #2b91af;\">int<\/span> main(){\n\n  std:: cout &lt;&lt; std::endl;\n  \n  constexpr <span style=\"color: #0000ff;\">auto<\/span> work= 63.0_km;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> workPerDay= 2 * work;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> abbrevationToWork= 5400.0_m;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> workout= 2 * 1600.0_m;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> shopping= 2 * 1200.0_m;\n  \n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek1= 4*workPerDay-3*abbrevationToWork+ workout+ shopping;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek2= 4*workPerDay-3*abbrevationToWork+ 2*workout;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek3= 4*workout + 2*shopping;\n  constexpr <span style=\"color: #0000ff;\">auto<\/span> distPerWeek4= 5*workout + shopping;\n  \n  constexpr <span style=\"color: #0000ff;\">auto<\/span> averageDistance= getAverageDistance({distPerWeek1,distPerWeek2,distPerWeek3,distPerWeek4});\n  \n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"averageDistance: \"<\/span> &lt;&lt; averageDistance &lt;&lt; std::endl;        <strong><span style=\"color: #339966;\">\/\/ 255900 m<\/span><\/strong>\n  \n  std::cout &lt;&lt; std::endl;\n\n}\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>I will not repeat myself by explaining constant expressions and user-defined literals in detail. I have already done it in the posts to <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/constexpr\">constexpr<\/a> and <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/benutzerdefinierte-literale\">user-defined literals<\/a>. I want to make only two observations:<\/p>\n<ol>\n<li>By declaring constexpr, all variables, class MyDistance instances, and functions become constant expressions. The compiler performs, therefore, the necessary operations at compile time.<\/li>\n<li><span style=\"font-family: courier new,courier;\">A<\/span>ll variables, instances, and functions &#8211; excluding <span style=\"font-family: courier new,courier;\">std::cout<\/span> &#8211; are constant expressions. That means the entire program will be executed at compile time. Therefore, all used variables and instances are immutable. Only the output of the program <span style=\"font-family: courier new,courier;\">255900 m<\/span> in line 77 is performed at run time.<\/li>\n<\/ol>\n<h2>What&#8217;s next?<\/h2>\n<p>Pure functions are pretty similar to mathematical functions. They are why Haskell and template metaprogramming is called pure functional languages. But what restrictions do a purely functional language have to fight with? These will be my topic for the <a href=\"https:\/\/www.modernescpp.com\/index.php\/pure-functions\">next post.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A key to purely functional languages is that their data are immutable. Therefore, assignments such as x= x+1 or ++x are not possible in the purely functional language Haskell. The consequence is that Haskell supports no loops like for, while, or until. They are based on the modification of a loop variable. Haskell does not [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":5151,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[428,508],"class_list":["post-5152","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-constexpr","tag-haskell"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5152"}],"version-history":[{"count":2,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5152\/revisions"}],"predecessor-version":[{"id":9773,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5152\/revisions\/9773"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5151"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}