<?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: P. Schreiber 🧙🏻‍♂️🔮🐐</title>
    <description>The latest articles on DEV Community by P. Schreiber 🧙🏻‍♂️🔮🐐 (@escribapetrus).</description>
    <link>https://dev.to/escribapetrus</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%2F554131%2F364392f7-8439-48cf-9870-4df524e2ff70.jpeg</url>
      <title>DEV Community: P. Schreiber 🧙🏻‍♂️🔮🐐</title>
      <link>https://dev.to/escribapetrus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/escribapetrus"/>
    <language>en</language>
    <item>
      <title>Prolog first steps: predicates, metapredicates, lambdas</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Sun, 30 Jun 2024 00:11:24 +0000</pubDate>
      <link>https://dev.to/escribapetrus/prolog-first-steps-predicates-metapredicates-lambdas-47md</link>
      <guid>https://dev.to/escribapetrus/prolog-first-steps-predicates-metapredicates-lambdas-47md</guid>
      <description>&lt;p&gt;I first became interested in Prolog after I watched a talk by Joe Armstrong, creator of Erlang, in which he mentioned this small, niche language twice. The first time, he explains how he took inspiration from the Prolog syntax to write Erlang's. The second, he mentions that if he were to choose only 4 languages to learn, Prolog would be among them.&lt;/p&gt;

&lt;p&gt;I have always found it super instructive to learn languages that are very distinct from one another. There isn't much to learn from a third dynamically-typed imperative language. But coming from, say, imperative to fuctional or, in this case, logical paradigm is quite the mind-bending experience. It makes us see things we think we know from a different angle, and provides &lt;em&gt;new ways of expressing ideas and operations&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is my first contact with logical programming, so everything here is basic and rudimentary. It is a first step in learning how logical programming works and why it is interesting.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deductions: logical results
&lt;/h1&gt;

&lt;p&gt;Prolog provides a very interesting functionality, one that I haven't seen in other languages. While all languages provide results for problems such as,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let X = A, Y = B, what is the result R of X + Y ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Prolog provides a way to find &lt;em&gt;all possible values of variables that make a problem true&lt;/em&gt;. For example,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let X + Y = R, what are the possible values of X and Y for which R = C&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Predicates: defining our data set
&lt;/h1&gt;

&lt;p&gt;In Prolog, we define &lt;em&gt;relations between terms&lt;/em&gt;. These relations are called predicates, statements that evaluate to &lt;code&gt;true&lt;/code&gt;. Let us define some.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="c1"&gt;% astrology.pl &lt;/span&gt;

&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;aries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mars&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;taurus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;venus&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;gemini&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;cancer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;moon&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;leo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;sun&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;virgo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;libra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;venus&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;scorpio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mars&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;sagittarius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;jupiter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;capricorn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;saturn&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;aquarius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;saturn&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 
&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;pisces&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;jupiter&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; 

&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;taurus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;earth&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;virgo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;earth&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;capricorn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;earth&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;aquarius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;air&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;libra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;air&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;gemini&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;air&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;pisces&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;water&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;cancer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;water&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;scorpio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;water&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;aries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;sagittarius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;leo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Undefined possible relations such as &lt;code&gt;ruler(aries, pluto)&lt;/code&gt; evaluate to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Queries: deducting results from the data set
&lt;/h1&gt;

&lt;p&gt;Let us generate some new information from the data we have, using logical deduction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get a value from relations
&lt;/h2&gt;

&lt;p&gt;Suppose we have two friends whose star sign we do not know, but for whom we can imagine, from their personality, their ruler planets and elements. We can deduce their signs based on those traits. &lt;/p&gt;

&lt;p&gt;To extract values from queries, we use variables, terms starting with an uppercase letter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;sun&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nv"&gt;Sign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Leo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alfred is has a fiery spirit and a sunny personality. By deduction, his sign is no other than Leo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;water&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mars&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nv"&gt;Sign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;scorpio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beth loves the ocean, and is very combative, like the god Ares. By deduction, her sign has to be scorpio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;water&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;venus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="ss"&gt;false&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Charles also loves the ocean, and is beautiful like Aphrodite. But there is no sign that fits this combination. Our assumptions about him must be wrong. &lt;/p&gt;

&lt;h2&gt;
  
  
  Get multiple valid results from relations
&lt;/h2&gt;

&lt;p&gt;In our premises, we have not defined any direct relation between planets and elements. However, planets rule signs, therefore we can establish indirect relations. For example, we can ask for planets that have the earth element; in other words, &lt;em&gt;"what is the planet X that rules some sign Y of the earth element?"&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;earth&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;taurus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;venus&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;virgo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;capricorn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;saturn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prolog is telling us that Venus, Mercury, and Saturn are ruled by earth signs (taurus, virgo, capricorn). It is noteworthy in our dataset, while a single &lt;em&gt;sign&lt;/em&gt; has a single element (1-n), a single &lt;em&gt;planet&lt;/em&gt; may have multiple elements (n-n).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;air&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;aquarius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;saturn&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;libra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;venus&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;gemini&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that Saturn and Mercury are also air planets in this world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get a list of valid results
&lt;/h2&gt;

&lt;p&gt;As we saw, a planet may have multiple elements based on its ruled signs. Let us try now to get the elements of a certain planet. This time, we will wrap those in a list, using the buit-in predicate &lt;code&gt;findall/3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;El&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Planet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;El&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Planet&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;El&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;El&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;Elements&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
    &lt;span class="nv"&gt;Elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;earth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;air&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we wrap the same query for elements of some planet from the previous topic in a function (more precisely, in a &lt;em&gt;conditional predicate&lt;/em&gt;). Functions in Prolog are &lt;strong&gt;Horn clauses&lt;/strong&gt;, a form of implication that reverses the position of &lt;code&gt;p -&amp;gt; q&lt;/code&gt; to &lt;code&gt;q &amp;lt;- p&lt;/code&gt;, or "q if p", in natural language.&lt;/p&gt;

&lt;p&gt;Our Horn clause states that, &lt;em&gt;"E is the element of a planet P if E is the element of a sign S, and the sign S is the ruler of the planet P"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then we find the elements of the planet Mercury, and throw those in a list. The built-in predicate &lt;code&gt;findall/3&lt;/code&gt; evaluates all elements for which P(El, ...) is true, and appends them to a list of valid elements.&lt;/p&gt;

&lt;p&gt;One amazing feature of Prolog is that, because it deals with values that evaluate to two, the &lt;code&gt;elem/2&lt;/code&gt; serves not only to find elements of a planet, but also planets of an element! In other words, we can query both &lt;code&gt;elem(E, mercury)&lt;/code&gt; and &lt;code&gt;elem(earth, P)&lt;/code&gt;, and both return the valid results that we look for. It is a feature I have never seen in a language.&lt;/p&gt;

&lt;h1&gt;
  
  
  Metapredicates
&lt;/h1&gt;

&lt;p&gt;Metapredicates are the logical programming equivalents of &lt;em&gt;higher-order functions&lt;/em&gt; in functional programming. They are predicates that have predicates as arguments. The predicate &lt;code&gt;findall/3&lt;/code&gt; mentioned earlier is such an example.&lt;/p&gt;

&lt;p&gt;Metapredicates are very useful generalizations on common operations. We may go beyond the metapredicates already predefined in the standard library, and define our own.&lt;/p&gt;

&lt;p&gt;For example, suppose we want to judge whether all planets in a list of planets are rulers of some sign. We may define a predicate &lt;code&gt;all_rulers&lt;/code&gt;, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;all_rulers&lt;/span&gt;&lt;span class="p"&gt;([]).&lt;/span&gt;
&lt;span class="ss"&gt;all_rulers&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;P&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;Ps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;P&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;all_rulers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Ps&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; &lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;all_rulers&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;sun&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;
&lt;span class="ss"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;all_rulers&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;pluto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;sun&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;
&lt;span class="ss"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The predicate is defined recursively, and states that all planets are rulers if the first element of the list is a ruler, and all other elements are also rulers.&lt;/p&gt;

&lt;p&gt;Judging whether all elements in a list are true according to some condition is so useful that we would be wise to define a general operation that accepts not just &lt;code&gt;ruler/2&lt;/code&gt;, but any condition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="ss"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;Es&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Es&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;sun&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lambdas
&lt;/h2&gt;

&lt;p&gt;We have an inconvenient limitation in our program: &lt;code&gt;all/2/&lt;/code&gt; only accepts as arguments predicates with &lt;em&gt;arity&lt;/em&gt; 1 (i.e. that take one argument). That is becase we make use of &lt;code&gt;call(Pred, E)&lt;/code&gt;, which applies the current element to the predicate.&lt;/p&gt;

&lt;p&gt;To further generalize our metapredicate, we can make use of lambdas, anonymous predicates that allow us not only to apply predicates of different arities, but also to define predicates on runtime.&lt;/p&gt;

&lt;p&gt;Let's define another metapredicate &lt;code&gt;any&lt;/code&gt;, which judges whether any element in a list is valid according to a condition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="ss"&gt;false&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="ss"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;Es&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="ss"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Es&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Pred&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;pack_install&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;use_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;library&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;
&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;pluto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mercury&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uranus&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;
&lt;span class="ss"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;?-&lt;/span&gt; &lt;span class="ss"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;pluto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uranus&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="ss"&gt;ruler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;
&lt;span class="ss"&gt;false&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The metapredicate &lt;code&gt;any/2&lt;/code&gt; is very similar to &lt;code&gt;all/2&lt;/code&gt;, except that instead of using AND operators (&lt;code&gt;,&lt;/code&gt;), it uses OR operators (&lt;code&gt;;&lt;/code&gt;); in other words, &lt;code&gt;any/2&lt;/code&gt; is true if the predicate for the first element of the list is true, or if it is true for some other subsequent element.&lt;/p&gt;

&lt;p&gt;This time, we are not passing a predicate previously defined in compilation, but rather a dynamic predicate with a lambda (we install and require the &lt;code&gt;lambda&lt;/code&gt; package first). Lambdas empower us to call a 2-arity predicate such as &lt;code&gt;ruler/2&lt;/code&gt; by wrapping it in an anonymous 1-arity anonymous predicate.&lt;/p&gt;

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

&lt;p&gt;Prolog is an interesting language, with a mind-bending paradigm. In this article, we have explore some of its features, such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getting bidirectional results;&lt;/li&gt;
&lt;li&gt;finding multiple solutions to a problem using variables;&lt;/li&gt;
&lt;li&gt;defining functions as Horn clauses;&lt;/li&gt;
&lt;li&gt;generalizing particular predicates into metapredicates;&lt;/li&gt;
&lt;li&gt;stating anonymous predicates with lambdas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you liked this article, and I look forward to exploring Prolog further. I have just started using this language, so I apologize for any incorrect terminology or explanations. If you have any comments or suggestions, I'll be happy to read them.&lt;/p&gt;

</description>
      <category>prolog</category>
      <category>logicalprogramming</category>
      <category>programming</category>
    </item>
    <item>
      <title>12 great music records for programers</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Fri, 23 Feb 2024 14:57:59 +0000</pubDate>
      <link>https://dev.to/escribapetrus/12-great-music-records-for-programers-24f9</link>
      <guid>https://dev.to/escribapetrus/12-great-music-records-for-programers-24f9</guid>
      <description>&lt;p&gt;Our senses can really influence our mood, actions, and ideas. Great art is inspirational, and it is a wholesome companion to our day to day work.&lt;/p&gt;

&lt;p&gt;Many programmers I know are music geeks, or at least have some interest in music. So, I want to give my recommendations for 12 music albums that I think are great to listen while programming. I have put these albums in three categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Inspirational:&lt;/strong&gt; for when we want to discover, explore and come up with great ideas&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Energetic:&lt;/strong&gt; for when we need a boost of energy to power through the work&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Chill:&lt;/strong&gt; for when we just want to enjoy our happy lives&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Searching for inspiration
&lt;/h1&gt;

&lt;p&gt;These are albuns for when we know what we need to do, but still need to discover how to do it. We want inspiration, and this is exactly what they provide.&lt;/p&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%2Fbybraza9ohr5shl3xffq.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%2Fbybraza9ohr5shl3xffq.png" alt="Image description" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "Stone Flower", Antônio Carlos Jobim
&lt;/h2&gt;

&lt;p&gt;Widely recognized as the greatest composer of Brazilian music, every album of Antônio Carlos Jobim's discography is worth the listen, as an exploration of the wide range of his musical creativity and influence in the most varied genres: samba, bossa nova, jazz, classical music, and more.&lt;/p&gt;

&lt;p&gt;"Stone Flower", released in 1970, features some of Jobim's classic songs in orchestral arrangements that elevate even higher the already esteemed sounds of bossa nova and jazz. It is a mostly instrumental, elegant, and joyful record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Sabiá, Brazil&lt;/p&gt;

&lt;h2&gt;
  
  
  "Peer Gynt", Edvard Grieg
&lt;/h2&gt;

&lt;p&gt;It is a little scary to talk about classical music, as its aura produces such awe and the fear of blasphemy. But let me try, if only to inspire readers to try this great record.&lt;/p&gt;

&lt;p&gt;"Peer Gynt" was composed around 1870's by Edvard Grieg as a musical accompaniment (a soundtrack, so to speak) to the play by Henrik Ibsen, and later worked into a standalone musical suite. The music has a distinct dramatic and narrative sound, and the listener can really feel immersed in the different settings of the story that is being told: a story of dangerous adventures in distant lands.&lt;/p&gt;

&lt;p&gt;Each track in the suite paints a distinct picture, and it is very &lt;em&gt;album-like&lt;/em&gt; in this sense. Some give the vibe of the idyllic Norwegian countryside village, while others present the otherworldly setting of fairy tales, magical woods and eerie dungeons.&lt;/p&gt;

&lt;p&gt;While this is not my favourite work by Grieg (that would be the magnificent Piano Concerto in A Minor), it is a truly pleasant and fun listen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Morning Mood, In The Hall of the Mountain King&lt;/p&gt;

&lt;h2&gt;
  
  
  "The Inner Mounting Flame", The Mahavishnu Orchestra
&lt;/h2&gt;

&lt;p&gt;The 1971 debut record of John McLaughlin's Mahavishnu Orchestra is a turning point in modern music, stretching the limits of the avant-garde music explorations initiated by Miles Davis' jazz fusion classic Bitches Brew. The band applies unparalleled technical prowess to the most different sounds, with influences from Eastern and Western music, to create a truly spiritual experience.&lt;/p&gt;

&lt;p&gt;Take, for example, "A Lotus on the Irish Streams". Luckily for us, the name of the track gives us a hint of what to expect: it is a mix of celtic folk, beautifully led by the melody of the violin, with some Indian-sounding guitar reminiscent of a sitar. I have to admit that it can be hard to grasp what is happening sometimes, when everything in this record is so fast and crazy. But there are beautiful moments, such as the aforementioned track or the contemplative "You Know, You Know".&lt;/p&gt;

&lt;p&gt;To some people, this record may sound self-indulgent. But if you like to hear some crazy guitar shredding, insane drums, that kind of stuff, give this one a try.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Meeting of the Spirits, Vital Transformation, You Know, You Know&lt;/p&gt;

&lt;h1&gt;
  
  
  Powering though
&lt;/h1&gt;

&lt;p&gt;When programming, sometimes what we need is a boost of energy, some nurturing of our will to exist, in order to power through challenging tasks.&lt;/p&gt;

&lt;p&gt;This is a list of albums for when you want to code while headbanging, playing air drums and singing (or growling) loudly.&lt;/p&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%2F8wwdvrnr2a066gj0vbc1.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%2F8wwdvrnr2a066gj0vbc1.png" alt="Image description" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "Blackwater Park", Opeth
&lt;/h2&gt;

&lt;p&gt;The sheer brutality of this record is almost unmatched, even when we talk about metal music. Even in the first moments of "The Leper Affinity", this album throws the listener into an absolute maelstrom of dark matter.&lt;/p&gt;

&lt;p&gt;This is the prime example of progressive death metal, taking inspiration in the inventiveness of progressive rock giants such as King Crimson or Genesis, and applying that to the technically challenging and insanely fast sound of death metal. By using a mix of weird scales and odd tempos, the band achieves such face-melting riffs unheard since the times of the first Black Sabbath albums.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; The Leper Affinity, The Drapery Falls&lt;/p&gt;

&lt;h2&gt;
  
  
  "Saosin", Saosin
&lt;/h2&gt;

&lt;p&gt;Arguably one of the best albums in the post-hardcore genre, this album is an unbroken string of bangers from start to finish.&lt;/p&gt;

&lt;p&gt;The guitar work is beautiful, with thick riffs and fast arpeggios, tastefully mixed to sound not like pretentious guitar metal, but balanced, impressive, and super cool.&lt;/p&gt;

&lt;p&gt;The singing does away with the violent growls that are a staple of the &lt;em&gt;screamo&lt;/em&gt; genre, which can sound too harsh or tiresome for some people, and rather focuses on high-pitch screams on the livelier passages. The lyrics are much clearer than the arcane verses of previous iterations of this band, making them super catchy and making the listener feel in a concert, screaming, &lt;em&gt;"We speak in different voices!"&lt;/em&gt; while banging keys on the code editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; It's Better to Learn, Come Close, Voices&lt;/p&gt;

&lt;h2&gt;
  
  
  "Inspiration is DEAD", Ling Tosite Sigure
&lt;/h2&gt;

&lt;p&gt;Ling Tosite Sigure plays a mix of post-hardcore and shoegaze that features all the characteristics of both genres, while also presenting a unique and immediately recognizable sound.&lt;/p&gt;

&lt;p&gt;You can expect to find shoegaze &lt;em&gt;walls of sound&lt;/em&gt;, intensely distorted, delayed and reverbed guitars; also, post-hardcore screaming high vocals, fast-tempo guitar arpeggios and insane drum rolls. But what makes this band special is that it has so much &lt;em&gt;character&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;First, the band is a &lt;em&gt;power trio&lt;/em&gt;, i.e. drum, bass, guitar. This is a perfect band formation because you can hear each instrument very distinctly. Not having two guitars makes the bass really slap: think Black Sabbath, Rush, The Jimi Hendrix Experience.&lt;/p&gt;

&lt;p&gt;Second, the vocals are so weird that it may take some time to get used to. At first listen it may even sound bad. But at the same time, they are super cool. TK and 345 both sing, and the boy-girl dynamic makes a colourful mix of sweet, aggresive, soft and harsh sounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Disco Flight, am 3:45, I Not Crazy Am You Are&lt;/p&gt;

&lt;h1&gt;
  
  
  Chilling
&lt;/h1&gt;

&lt;p&gt;Different moods are good for different tasks. Sometimes, what we need is to just chill and do what we are confident in.&lt;/p&gt;

&lt;p&gt;These are records for when you want to code while vibing and enjoying life, thinking about the weekend that is coming.&lt;/p&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%2Fjj6aldphj45kte9z4uj1.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%2Fjj6aldphj45kte9z4uj1.png" alt="Image description" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "No. 4", Serge Gainsbourg
&lt;/h2&gt;

&lt;p&gt;Last year I decided to dive deep in Serge Gainsbourg's discography, and while there is much to talk about many of his records, I believe this the masterpiece. No. 4 is a mix of many artistic expressions: poetry, jazz, rock, bossa nova, samba, pop.&lt;/p&gt;

&lt;p&gt;Though time has made records made in the 60's sound old or &lt;em&gt;vintage&lt;/em&gt;, this record is incredibly modern and forward-driven in its artistic explorations: For example, "Baudelaire" sets the lyrics of XIXth century poetry to the sounds of bossa nova and samba, offering a sunny, tropical and sensual take on the words of a poet whose work is commonly associated to a sinister aesthetic of dark rooms, smoke and absinthe. Also worthy of note are the sick electric organ solos that sound like a weird French precursor to The Doors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Black Trombone, Baudelaire, Intoxicated Man&lt;/p&gt;

&lt;h2&gt;
  
  
  "At Home", Paddy Reilly
&lt;/h2&gt;

&lt;p&gt;"The voice of Ireland", wrote some wise YouTube commenter.&lt;/p&gt;

&lt;p&gt;Paddy Reilly, the great guitarist, singer, and one could even say at one point frontman of the legendary band The Dubliners, dropped this killer record in 1972. There is no mix of styles here, no avant-garde sound explorations, just the purest, most beautiful sound of Irish balladry.&lt;/p&gt;

&lt;p&gt;Paddy's voice is powerful and heartwarming, and while marked by a strong and beautiful Irish accent, his words are clear, and wrap the listener in the most varied stories, from heroic war songs of rebellion to the love stories of whiskey-filled drunks. This is a record that just makes me want to take arms against the British and die in the arms of a golden-haired maiden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; The Foggy Dew, Come Out Ye Black and Tans, The Limerick Rake&lt;/p&gt;

&lt;h2&gt;
  
  
  "Canta en Español Con Los Panchos", Eydie Gormé
&lt;/h2&gt;

&lt;p&gt;I first heard this record when searching for the original Spanish version of the Dalida song "Histoire d'un amour". The Frech version is beautiful in its own term, providing a mix of the Latin rhythm of bolero with the melodramatic charm of the &lt;em&gt;chanson française&lt;/em&gt;. But Eydie Gormé's version is superior to my ears for being livelier, more cheerful, showing, even if the lyrics are sad, the inherent beauty of a love story.&lt;/p&gt;

&lt;p&gt;The 1964 record is a collaboration between the American singer and the Mexican trio, and is a beautiful display of the warm and colourful charm of Latin American music. Eydie Gormé's voice is soft, sweet, and elegant, with the perfect dose of drama (a character that can sometimes be excessive in such a genre as bolero), and a clear and charming accent. Los Panchos' guitars are expressive, sharp, and act like singers themselves.&lt;/p&gt;

&lt;p&gt;This is definitely a record to put us in a good mood, reminding us of warmth, sunshine, dancing, love, and other joys of life.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt; Historia de un Amor, Quando Vuelva a Tu Lado, Sabor a Mí&lt;/p&gt;

</description>
      <category>programming</category>
      <category>music</category>
      <category>productivity</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Pretty writing in Emacs: exporting Org files to PDF</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Thu, 15 Jun 2023 14:58:39 +0000</pubDate>
      <link>https://dev.to/escribapetrus/pretty-writing-in-emacs-exporting-org-mode-files-to-pdf-372i</link>
      <guid>https://dev.to/escribapetrus/pretty-writing-in-emacs-exporting-org-mode-files-to-pdf-372i</guid>
      <description>&lt;h1&gt;
  
  
  Introduction: Org to LaTeX to PDF
&lt;/h1&gt;

&lt;p&gt;There are two types of Emacs users: those who give up and go back to vscode, and those who get full citizenship and move permanently to Emacs town. This article is for those masochists who don't care if Google provides an easier tool for writing pretty texts and code notebooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Org-mode&lt;/strong&gt; is an awesome tool for writing multi-purpose text in Emacs. It can be used for &lt;a href="https://en.wikipedia.org/wiki/Literate_programming"&gt;literate programming&lt;/a&gt; (like Jupyter Notebooks) in any languages we want, for todo-lists and schedules, for articles and much more.&lt;/p&gt;

&lt;p&gt;We have been using Org files for our own notetaking for a few months now, but until yesterday we didn't really explore the &lt;em&gt;export&lt;/em&gt; and &lt;em&gt;publish&lt;/em&gt; functionalities, which allow us to transform org texts into formats used in the world outside of Emacs, and package a collection of texts into a cohesive unit. (we will not explore &lt;em&gt;publish&lt;/em&gt; in this article, as we have not yet used it).&lt;/p&gt;

&lt;p&gt;We want to configure Emacs to export an Org text to a pretty PDF. Let's use this article, which we are currently writing in org-mode (inception!) as an example. Our objective is to use &lt;code&gt;org-export-dispatch (C-c C-e)&lt;/code&gt; to &lt;em&gt;export to LaTeX as PDF file and open&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  LaTeX: what is it, installation, exporting PDF
&lt;/h1&gt;

&lt;p&gt;The first step in our pipeline from Emacs Org to PDF is exporting our document to LaTeX. Emacs can't do that if the program is not installed. So, before we try to export our Org file, let us make sure that we can correctly produce a PDF from LaTeX code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is LaTeX?
&lt;/h2&gt;

&lt;p&gt;From the &lt;a href="https://www.latex-project.org/about/"&gt;LaTeX documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;LaTeX is a high-quality typesetting system; it includes features designed for the production of technical and scientific documentation. LaTeX is the de facto standard for the communication and publication of scientific documents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this sense, LaTeX is a hierarchical text definition language, like markup or html, which allow us to describe the role of each section in the context of the whole text. This is an example of LaTeX code, taken from the docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;    &lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;article&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;\title&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Cartesian closed categories and the price of eggs&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;\author&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Jane Doe&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;\date&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;September 1994&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;\begin{document}&lt;/span&gt;
       &lt;span class="k"&gt;\maketitle&lt;/span&gt;
       Hello world!
    &lt;span class="nt"&gt;\end{document}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;documentclass&lt;/code&gt; section describes the template for the output document; in other words, the &lt;em&gt;style&lt;/em&gt;, which is defined in the LaTeX document template.&lt;/p&gt;

&lt;p&gt;In summary, LaTeX is a language and a program for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  hierarchical text definition language (like markup, html)&lt;/li&gt;
&lt;li&gt;  format and style definition language (like css)&lt;/li&gt;
&lt;li&gt;  text processing program&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;If we open the &lt;a href="https://www.latex-project.org/get/"&gt;LaTeX Project GET page&lt;/a&gt;, we will find the recommended distributions for the most popular operating systems. We are configuring this on our MacBook Air, so we should get MacTeX. However, the complete MacTeX bundle is 5GB, which is absurdly huge for our humble project. Rather, let us go for the &lt;em&gt;much smaller&lt;/em&gt; 90MB &lt;a href="https://www.tug.org/mactex/morepackages.html"&gt;BasicTeX&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The BasicTeX .pkg file is very much plug and play, as it installs the binaries to folders already supported in the terminal PATH. For generating a PDF from LaTeX code, will use XeLaTeX, an improved version of LaTeX with support for unicode and special fonts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing problems and exporting the PDF
&lt;/h2&gt;

&lt;p&gt;Even the minimal BasicTeX comes with the necessary tools to generate a PDF. Therefore, we should be ready to export our PDF after the installation. Let's save the the LaTeX code example provided earlier as &lt;code&gt;article.tex&lt;/code&gt; and try exporting it to PDF by using the &lt;code&gt;xelatex article.tex&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;In our machine we have encountered some problems, registered in a .log file. Let us see what they are and how to solve them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;    &lt;span class="p"&gt;$&lt;/span&gt;&lt;span class="nb"&gt; xelatex article.tex
    ...
    &lt;/span&gt;&lt;span class="o"&gt;(/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texlive&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2023&lt;/span&gt;&lt;span class="nb"&gt;basic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texmf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;tex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;latex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amsmath&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amsopn.sty&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="nb"&gt;
    &lt;/span&gt;&lt;span class="o"&gt;(/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texlive&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2023&lt;/span&gt;&lt;span class="nb"&gt;basic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texmf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;tex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;latex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amsfonts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amssymb.sty
     &lt;/span&gt;&lt;span class="o"&gt;(/&lt;/span&gt;&lt;span class="nb"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texlive&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2023&lt;/span&gt;&lt;span class="nb"&gt;basic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;texmf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;tex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;latex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amsfonts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;amsfonts.sty&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="nb"&gt;

    &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt; LaTeX Error: File 'wrapfig.sty' not found.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error is very clear. LaTeX cannot find the &lt;a href="https://www.ctan.org/tex-archive/macros/latex/contrib/wrapfig"&gt;wrapfig package&lt;/a&gt;. Our distribution must have come without it. The good thing is that the error message even shows us where to put it. The fix is easy, we just download the file and store it where the error pointed us, maybe in the &lt;code&gt;graphics/&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;    &lt;span class="p"&gt;$&lt;/span&gt;&lt;span class="nb"&gt; wget http:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nb"&gt;mirrors.ctan.org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;macros&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;latex&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;contrib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;wrapfig&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;wrapfig.sty
    &lt;/span&gt;&lt;span class="p"&gt;$&lt;/span&gt; sudo mv wrapfig.sty /usr/local/texlive/2023basic/texmf-dist/tex/latex/graphics/wrapfig.sty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run &lt;code&gt;xelatex article.tex&lt;/code&gt; again, we get a different error, and that is progress; it means the first problem&lt;br&gt;
was solved. Here is the second error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$ &lt;/span&gt;xelatex article.tex
    ...
    &lt;span class="o"&gt;(&lt;/span&gt;/usr/local/texlive/2023basic/texmf-dist/tex/latex/amsmath/amsopn.sty&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;/usr/local/texlive/2023basic/texmf-dist/tex/latex/amsfonts/amssymb.sty
    &lt;span class="o"&gt;(&lt;/span&gt;/usr/local/texlive/2023basic/texmf-dist/tex/latex/amsfonts/amsfonts.sty&lt;span class="o"&gt;))&lt;/span&gt;

    &lt;span class="o"&gt;!&lt;/span&gt; LaTeX Error: File &lt;span class="s1"&gt;'capt-of.sty'&lt;/span&gt; not found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is almost the same error as before. LaTeX cannot find the &lt;a href="https://www.ctan.org/tex-archive/macros/latex/contrib/capt-of"&gt;capt-of&lt;/a&gt; package. The solution here is a bit more challenging, because the source does not provide the .sty file (don't ask us why). We have to compile it ourselves.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$ &lt;/span&gt;wget http://mirrors.ctan.org/macros/latex/contrib/capt-of/capt-of.dtx
    &lt;span class="nv"&gt;$ &lt;/span&gt;wget http://mirrors.ctan.org/macros/latex/contrib/capt-of/capt-of.ins

    &lt;span class="nv"&gt;$ &lt;/span&gt;xelatex capt-of.ins

    &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo mv &lt;/span&gt;capt-of.sty /usr/local/texlive/2023basic/texmf-dist/tex/latex/caption/capt-of.sty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we run &lt;code&gt;xelatex article.tex&lt;/code&gt;, we get a beautiful &lt;code&gt;article.pdf&lt;/code&gt; exported by LaTeX. Awesome.&lt;/p&gt;

&lt;h1&gt;
  
  
  Running on Emacs
&lt;/h1&gt;

&lt;p&gt;The essential part is basically done. All we have to do now in order to export our org files to PDF is telling Emacs what LaTeX compiler and command to use. For that, just add to the elisp configuration file (e.g. &lt;code&gt;init.el&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="o"&gt;(&lt;/span&gt;setq org-latex-compiler &lt;span class="s2"&gt;"xelatex"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;setq org-latex-pdf-process &lt;span class="s1"&gt;'("xelatex %f"))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now run &lt;code&gt;M-x org-export-dispatch (C-c C-e)&lt;/code&gt; to &lt;em&gt;export to LaTeX as PDF file and open&lt;/em&gt; (options l-o), just like we wanted. In fact, we have done it in just the org file for this article, and it worked beautifully.&lt;/p&gt;

&lt;p&gt;This concludes our explanation of how to export an Org text to a pretty PDF. One thing to add is that we are not academics who produce papers frequently, so our knowledge of LaTeX is &lt;em&gt;very&lt;/em&gt; limited. Feel free to leave any suggestions and corrections in the commentaries.&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>writing</category>
    </item>
    <item>
      <title>Transparent execution of Fortran code from the Erlang machine using ports</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Fri, 10 Mar 2023 00:31:14 +0000</pubDate>
      <link>https://dev.to/escribapetrus/transparent-execution-of-fortran-code-from-the-erlang-machine-using-ports-37ba</link>
      <guid>https://dev.to/escribapetrus/transparent-execution-of-fortran-code-from-the-erlang-machine-using-ports-37ba</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; Transparent execution of Fortran code from the Erlang machine using ports

&lt;ol&gt;
&lt;li&gt; The plan
&lt;/li&gt;
&lt;li&gt; The Fortran program
&lt;/li&gt;
&lt;li&gt; The Erlang program
&lt;/li&gt;
&lt;li&gt; Conclusion
&lt;/li&gt;
&lt;/ol&gt;


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

&lt;p&gt;&lt;a id="org1d76819"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Joe Armstrong, creator of the Erlang programming language, said a couple of times that, though the Erlang system is the perfect tool for writing programs designed for concurrent execution, it is not the best tool for compute-intensive tasks, such as numerical calculations. Those tasks, he said, would be best served by calling an external program written in Fortran.&lt;/p&gt;

&lt;p&gt;The problem, however, is that he never told us how to run such a program from inside the Erlang machine.&lt;/p&gt;

&lt;p&gt;Code for this article is available on &lt;a href="https://github.com/escribapetrus/f90_port"&gt;my Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="org1c01772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The plan
&lt;/h2&gt;

&lt;p&gt;We are going to write a Fortran program that receives input and does some calculations with the values provided by the user. Because our problem here is not how to write Fortran, but rather how to run the program from inside the Erlang runtime, a simple program will do just fine. For this exercise, we will write a program that calculates the force according to Newton's 2nd law.&lt;/p&gt;

&lt;p&gt;In order to interface with the Fortran program, we use a genserver process that manages an Erlang port. Ports are Erlang processes that allow running external programs and interact with them in the same way we interact with processes in the Erlang machine, by sending and receiving messages.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Our objective is to call the genserver API in Erlang, have the function transparently execute in the Fortran program (that is, as if it had been called locally), and return the correct result.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Eshell V13.1.2  (abort with ^G)
    1&amp;gt; f90:start_link("./newton").
    {ok,&amp;lt;0.84.0&amp;gt;}
    2&amp;gt; f90:force(90,80).
    7200 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a id="orgc9101e4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fortran program
&lt;/h2&gt;

&lt;p&gt;First, we focus on the Fortran program that will effectively perform the calculations. As we said, we are going to calculate the force using newton's formula, which is, as we all know, defined as: &lt;code&gt;f = m * a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's start with the simplest program possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fortran"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;! newton0.f90&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newton&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="k"&gt;write&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'(10i0)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="k"&gt;contains&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newton&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program consists of a simple function definition for the Newtonian formula, a couple of variable declarations and assignments, and a write statement that prints the result of applying the function to the variables as arguments.&lt;/p&gt;

&lt;p&gt;We compile the program with &lt;code&gt;gfortran newton0.f90 -o newton&lt;/code&gt;. Running it in the terminal produces the correct result.&lt;/p&gt;

&lt;p&gt;For the next step, we need to process user input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fortran"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;! newton.f90&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newton&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rstat&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="kt"&gt;character&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;.true.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;.true.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'(A)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;iostat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rstat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rstat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;stop&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mass'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;maybe_read_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; 
           &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'accel'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;maybe_read_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'return'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="k"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bad input'&lt;/span&gt;&lt;span class="w"&gt; 
           &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt;

         &lt;/span&gt;&lt;span class="k"&gt;write&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'(10i0)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

         &lt;/span&gt;&lt;span class="n"&gt;mass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="n"&gt;accel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="k"&gt;contains&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;subroutine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;maybe_read_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="k"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iostat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rstat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rstat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'(10i0)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
           &lt;/span&gt;&lt;span class="k"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bad input'&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;endif&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;subroutine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;maybe_read_int&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;implicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newton&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program starts with a loop, which reads the standard input, and assigns its value to a string. The input is matched to the expected patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;mass [value]:&lt;/strong&gt; stores the value in the mass variable&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;accel [value]:&lt;/strong&gt; stores the value in the accel variable&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;return:&lt;/strong&gt; exits the loop and proceeds to the next step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, the program prints the result of the force function over the variables, just like in the previous snippet. Let's compile the program and run it in the terminal to see it in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;gt; ./newton
    &amp;gt; mass 90
    90
    &amp;gt; accel 80
    80
    &amp;gt; return
    7200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, we have successfully written a Fortran program that calculates the force using the Newtonian formula. Now, we need to write an Erlang program that is able to run it.&lt;/p&gt;

&lt;p&gt;&lt;a id="org846b653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Erlang program
&lt;/h2&gt;

&lt;p&gt;As we said, we want to be able to call an Erlang function that produces the result from the Fortran program's execution. The appropriate way to do this in Erlang is using ports. Acording to the documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ports provide the basic mechanism for communication with the external world, from Erlang's point of view. The ports provide a byte-oriented interface to an external program. When a port is created, Erlang can communicate with it by sending and receiving lists of bytes (not Erlang terms). This means that the programmer might have to invent a suitable encoding and decoding scheme.&lt;/p&gt;

&lt;p&gt;When to use: Ports can be used for all kinds of interoperability situations where the Erlang program and the other program runs on the same machine. Programming is fairly straight-forward.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most things in the Erlang system are processes, and ports are no exception. A port is a processes that sends and receives messages from other processes in the Erlang runtime, and sends and receives messages from the external program.&lt;/p&gt;

&lt;p&gt;One key difference of message passing from ports to the external program, compared with message passing between processes inside the Erlang runtime, is that internal processes understand Erlang terms (e.g. atoms, tuples, records, maps), while the external program absolutely does not. Everything we can do is send and receive binaries.&lt;/p&gt;

&lt;p&gt;This is very similar to what happens in the distributed architecture of microservices implemented in different programming languages. For example, three services running Node, JVM, and Python cannot share objects native to their respective languages. They must instead resort to a common binary (string) protocol (e.g. JSON) for the API, and implement encoding/decoding internally.&lt;/p&gt;

&lt;p&gt;Luckily for us, our Fortran program is designed to expect very simple binary patterns. Let's see how we create a port and send and receive messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Eshell V13.1.2  (abort with ^G)
    1&amp;gt; Port = open_port({spawn, "./newton"}, [use_stdio, exit_status]). 
    #Port&amp;lt;0.5&amp;gt;
    2&amp;gt; Port ! {self(), {command, "mass 90\n"}}.
    {&amp;lt;0.82.0&amp;gt;,{command,"mass 90\n"}}
    3&amp;gt; flush().
    Shell got {#Port&amp;lt;0.5&amp;gt;,{data,"90\n"}}
    ok
    4&amp;gt; Port ! {self(), {command, "accel 90\n"}}.
    {&amp;lt;0.82.0&amp;gt;,{command,"accel 90\n"}}
    5&amp;gt; flush().
    Shell got {#Port&amp;lt;0.5&amp;gt;,{data,"90\n"}}
    ok
    6&amp;gt; Port ! {self(), {command, "return\n"}}.  
    {&amp;lt;0.82.0&amp;gt;,{command,"return\n"}}
    6&amp;gt; flush().
    Shell got {#Port&amp;lt;0.5&amp;gt;,{data,"8100\n"}}
    ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a port with the Erlang library function &lt;em&gt;open_port/2&lt;/em&gt;, which receives the command to the external program and some options, and returns the port Pid. We use the Pid to send messages to the port, which it will relay to the external program using the stdin.&lt;/p&gt;

&lt;p&gt;Here, we are creating a port to the Fortran program "./newton", and sending it three messages. The flush() call reads the messages received by the Erlang shell process. Notice the third message: it is the result of the &lt;code&gt;force()&lt;/code&gt; function, executed by the Fortran program!&lt;/p&gt;

&lt;p&gt;We are very close to wrapping this up. All that is left is to put this functionality in a genserver that manages the port and provides a clear interface in accordance with the OTP standards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;    &lt;span class="c"&gt;%% f90.erl
&lt;/span&gt;    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f90&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;behaviour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;export&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;export&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;

    &lt;span class="c"&gt;%% API
&lt;/span&gt;    &lt;span class="nf"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nn"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;

    &lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nn"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

    &lt;span class="nf"&gt;force&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Accel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nn"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Accel&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;

    &lt;span class="c"&gt;%% callbacks
&lt;/span&gt;    &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;process_flag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trap_exit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nv"&gt;Port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open_port&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nb"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;use_stdio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exit_status&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;}}.&lt;/span&gt;

    &lt;span class="nf"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Mass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Accel&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt;&lt;span class="nv"&gt;From&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;call_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Mass&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;call_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;accel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Accel&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nv"&gt;Res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;

    &lt;span class="nf"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;port_close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]}.&lt;/span&gt;

    &lt;span class="nf"&gt;call_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;port_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;receive&lt;/span&gt;
        &lt;span class="p"&gt;{_,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;TrimmedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nb"&gt;list_to_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;TrimmedData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;after&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

    &lt;span class="nf"&gt;accel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"accel "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="nb"&gt;integer_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nf"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"mass "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="nb"&gt;integer_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"return&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start the genserver with &lt;code&gt;start_link/1&lt;/code&gt; by providing the external program command as argument. The &lt;code&gt;init/1&lt;/code&gt; function runs as a callback, spawns the port, and stores the port Pid in the genserver state.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;force/2&lt;/code&gt; function takes two integers, mass and acceleration, and will callback a handler that sends messages to the port and receives the response from the external program.&lt;/p&gt;

&lt;p&gt;With this, we have implemented exactly the functionality we wanted in the beginning: &lt;em&gt;a server that provides a simple Erlang function and produces the result of a calculation done in an external Fortran program&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="org3e40706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The computer is an awesome machine, and it provides so many different tools and patterns with which we can create programs. It is a waste of intelligence to be confined to a single programming language.&lt;/p&gt;

&lt;p&gt;In this exercise, we showed that with a simple construct, the Erlang port, we can interface with external programs in other languages. Once we set up a common binary protocol between the two programs, we can send and receive messages just like we do inside the Erlang machine, requesting execution and getting back results.&lt;/p&gt;

</description>
      <category>erlang</category>
      <category>fortran</category>
      <category>elixir</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Notes on Russel's Introduction to Mathematical Philosophy</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Mon, 08 Aug 2022 22:18:23 +0000</pubDate>
      <link>https://dev.to/escribapetrus/notes-on-russels-introduction-to-mathematical-philosophy-4ol6</link>
      <guid>https://dev.to/escribapetrus/notes-on-russels-introduction-to-mathematical-philosophy-4ol6</guid>
      <description>&lt;p&gt;In the &lt;strong&gt;Introduction to Mathematical Philosophy&lt;/strong&gt;, Bertrand Russell describes a philosophical ethos in relation to mathematics, that stands in contrast with the standard practice of mathematicians. Rather than progressing from a set of established principles into complex operations -- from the arithmetics of natural numbers to the algebra of real numbers, and from that to the differentiation and integration calculus -- Russel describes the philosophical ethos as the research of the essence of mathematics, and the logical operations by which we can deduce these foundational principles, such as numbers, sequences, sets and functions.&lt;/p&gt;

&lt;p&gt;As mathematics undergoes a process of arithmetisation, in a divergence from formal logic, it follows that, in order to take on the investigation of its principles, it is necessary to define first the fundamental concept of number. As Russell describes it, though the number is an ubiquitous concept in the hundreds of years of the history of mathematics, a clear and correct definition was only formalised and published in recent years, by Frege (&lt;strong&gt;Foundations of Arithmetics&lt;/strong&gt;, 1884). Frege's definition is different to that of Peano, who defines numbers in terms of sequences or progressions, and also subtly different to the philosophers who defined numbers simply in terms of plurality -- one apple, two apples, three apples.&lt;br&gt;
The problems in defining numbers in terms of progressions or plurality are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Progressions, while they provide a correct knowledge about the relationships of numbers -- according to the function f(x) that determines the successor of x -- they do not provide any knowledge about the number itself and what it represents; if we change the reference to the first element of the sequence, the reference to all elements in the sequence is lost.&lt;/li&gt;
&lt;li&gt;Plurality, on the other hand, while it does provide knowledge of a single number in terms of the quantity of objects, it tells us nothing about the number as a number -- and, more importantly, about what numbers are; in other words, it provides a sense of what "three" is, but not of what "number" is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A precise definition of what a number is requires that we abstract a single quantity into the general concept of all quantities, therefore putting forward the concept of groups -- or, more precisely, classes. Just as we can define a class a with three apples, and a class b with three bananas, we can define a class of all classes with three elements (i.e. all classes similar to a class with three elements, in terms of quantity of elements). Similarly, we can describe a class of all classes with thirty elements, or a class of all classes with three hundred elements.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The number of a class, then, will be the class of all classes similar to it. A number is any entity that is the number of a class.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The definition of numbers in terms of classes is interesting to the student of computer sciences, because of the importance that term has gained since the advent of object-oriented programming. Though I want to tread carefully and avoid the sin of anachronism (we are talking about a text written in 1919, when modern computation by electronic machines was a distant dream), it is worthy of note how Russell describes classes as "logical fictions" -- not real things in and of themselves, but rather a sort of imaginary line traced around objects, grouping them together in terms of some arbitrary common description (generative function; e.g. the class of men, the class of cars).&lt;/p&gt;

&lt;p&gt;Am I then accusable of being too hasty and unconsidered in seeing a similarity between this definition of classes with the concept of abstract data types, which is so cherished in the field of object-oriented programming? Of course classes in OOP languages are much more complex structures -- with attributes, behaviours, contracts, interfaces -- than the simple abstractions of classes as "logical fictions" described by Russell; but I do see how we could interpret the latter as the former's source and inspiration. &lt;/p&gt;

&lt;p&gt;We could, for example, describe the type specification of a class constructor as its intentional definition, and the instances of a class as its extensional definition. As Russell writes, classes can be defined in two ways: extensionally, in terms of its members, or intentionally, in terms of an abstract description; so, a class A could be defined as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A = {Jack, Jim} &lt;/li&gt;
&lt;li&gt;A = "men in this room now"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for methods, they describe the relations between objects of this class with other objects in the world.&lt;/p&gt;

&lt;p&gt;This approximation was brought to my mind because of a tweet someone posted some other day, about the weirdness of writing numbers as class objects in OOP languages, which leads to constructs such as &lt;code&gt;10.is_pair()&lt;/code&gt;. As we see in Russell's writing, the idea of describing numbers as abstract classes capable of having properties is not an invention of object-oriented programming.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>oop</category>
      <category>computerscience</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Map, Filter, Reduce in C: recursive high-order functions using pointers</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Mon, 04 Apr 2022 20:42:42 +0000</pubDate>
      <link>https://dev.to/escribapetrus/map-filter-reduce-in-c-recursive-high-order-functions-using-pointers-376n</link>
      <guid>https://dev.to/escribapetrus/map-filter-reduce-in-c-recursive-high-order-functions-using-pointers-376n</guid>
      <description>&lt;p&gt;The functional programming journey has a dual aspect: understanding the paradigm conceptually, and applying it in practice on the daily work. When working with the current common tools for programmer, however, we are usually far removed from the arcane knowledge of Haskell and functional Lisp. Sometimes, what we have to do is to find ways to program in a functional style in the languages we use day to day, like Python or Javascript.&lt;/p&gt;

&lt;p&gt;Usually, this starts with three techniques which, though simple for someone whose mind is used to functional programming fundamentals, like recursion and higher-order functions, can prove challenging for someone used to the imperative style, for loops and mutable variable assignment. These techniques, which feature in most "functional programming in [blank]" tutorials, are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;map(function, list): produces a new list where the elements are the result of the application of the function to the elements of list in the argument;&lt;/li&gt;
&lt;li&gt;filter(function, list): produces a new list where the elements are those where the application of the elements to the function returns true;&lt;/li&gt;
&lt;li&gt;reduce: produces the result of the application of the function to all elements over an accumulator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are higher-order functions: functions that receive other functions as arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;list = 1 2 3 4 5 6

f(x) = x + 2    
map(f, list) = 3 4 5 6 7 8

g(x) = x &amp;gt; 3
filter(g, list) = 4 5 6

h(x,y) = x + y
reduce(h, list) = 21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this article, we are attempting to implement this functionality in the C programming language. Please note that this is just an exercise, not a recommendation for a serious style of programming in this language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations for implementing functional tools in C
&lt;/h2&gt;

&lt;p&gt;There are a few things we must consider before we try to implement these functional tools in C.&lt;/p&gt;

&lt;p&gt;First, we must remember that, in functional programming, data is meant to be immutable. Therefore, we must make sure that our functions do not alter the values of our variables and data structures, but rather create new variables and data structures, whose values are derived com computations applied to a source.&lt;/p&gt;

&lt;p&gt;Second, we must consider that, in C, functions are not first class objects: they cannot be defined inside functions, returned from functions, or passed to functions as arguments. We need to find a way provide our functions with a function to be applied to the values in a data structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing a linked list
&lt;/h2&gt;

&lt;p&gt;It is a general rule that recursive algorithms work best with recursively defined data structures: data structures defined by making reference to themselves, such as a linked list or a binary tree. &lt;/p&gt;

&lt;p&gt;A linked list is a chain of nodes, each of which contains a value and a reference to the next node (and therefore to the rest of the list). &lt;/p&gt;

&lt;p&gt;In functional programming lingo borrowed from Lisp, we can define a linked list in terms of a &lt;em&gt;cons cell&lt;/em&gt;, a pair of elements (a, b), where the &lt;em&gt;head&lt;/em&gt; is the first element, and the &lt;em&gt;tail&lt;/em&gt; is a recursive sequence of cons cells ending on an empty cell.&lt;/p&gt;

&lt;p&gt;Our tools -- map, filter, reduce -- are recursive high-order-functions, so it is natural that the lists they iterate over are recursively defined. Our first step should be to define the data type. &lt;/p&gt;

&lt;p&gt;We define each element of our linked list as a &lt;code&gt;struct Node&lt;/code&gt; containing two values: &lt;code&gt;int data&lt;/code&gt;, the value of the node itself; &lt;code&gt;Node *next&lt;/code&gt;, a pointer to the next node in the chain. Every node points to a next node, up to the final element in the chain, with points to nothing (nil pointer, or zero).&lt;/p&gt;

&lt;p&gt;Also, we define a &lt;code&gt;cons&lt;/code&gt; function, which allows us to create a linked list. It receives an integer value and a list to add it to, allocates space in memory for a node, assigns the value as its data, and plugs the node into a list by pointing &lt;code&gt;next&lt;/code&gt; to the &lt;code&gt;head&lt;/code&gt; of the list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* linkedlist.c */&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"functional.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is worth mentioning that the linked list is defined as a pointer to the first node_, not as the first node itself. To make that explicit, we could have written a type definition &lt;code&gt;typedef *Node Linkedlist&lt;/code&gt;, where Linkedlist is a pointer to the first node of a linked list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using pointers to pass functions as arguments
&lt;/h2&gt;

&lt;p&gt;Lambda functions are essential for functional programming, because they provide a clear syntax to create function objects that can be passed to and returned from functions. In Haskell, for example, we can write &lt;code&gt;\x -&amp;gt; x + 3&lt;/code&gt; to create a function, without having to name it or write it separately from our main program.&lt;/p&gt;

&lt;p&gt;Unfortunately, we don't have that luxury in C. The language does not allow us to write functions inside of other functions, to pass them as arguments, or return them as results of functions. So, we have to find another way to pass functions to our higher-order functions map, filter, and reduce.&lt;/p&gt;

&lt;p&gt;One awesome thing that C does provide is the &lt;em&gt;function pointer&lt;/em&gt;, a pointer to the memory address of a function. This allows us to pass the address of a function as an argument. For example, we can create a function &lt;code&gt;apply&lt;/code&gt; that takes a function (or rather, a pointer to a function) and a value, and returns the result of applying that function to the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* apply.c */&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"functional.h"&lt;/span&gt;&lt;span class="c1"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this device, we can do different operations on a variable, depending on which function we pass an argument to &lt;code&gt;apply&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing recursive iterators
&lt;/h2&gt;

&lt;p&gt;We have addressed our two considerations, and are now able to define the three high-order functions: map, filter and reduce. They are very simple to implement, if we remember to compute recursively-defined data structures with recursion. &lt;/p&gt;

&lt;p&gt;Our three functions take the first element of the list (the &lt;code&gt;head&lt;/code&gt;), apply a function to it, and proceed to compute the next elements (the &lt;code&gt;tail&lt;/code&gt;) according to the result, recursively, until it reaches a nil pointer, at which point the list is exhausted and the computation stops.&lt;/p&gt;

&lt;p&gt;Let us implement and explore them in further detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  map
&lt;/h3&gt;

&lt;p&gt;Map takes a function and a linked list, and produces a new linked list by applying the function to each element of the list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* iterators.c */&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We take the value of the head of the list, apply the function specified in the arguments, pointed to by &lt;code&gt;fp&lt;/code&gt;, and &lt;code&gt;cons&lt;/code&gt; the result into a new list build by the recursive application of &lt;code&gt;map&lt;/code&gt; to the next elements. &lt;/p&gt;

&lt;p&gt;Let us define a few different functions that can be passed to &lt;code&gt;map&lt;/code&gt;, and create a transformed linked list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;addThree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;doDouble&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toFour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* main.c */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;addThree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;doDouble&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;toFour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 4 5 6 7 8&lt;/span&gt;
&lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 2 4 6 8 10&lt;/span&gt;
&lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 4 4 4 4 4&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;addThree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;doDouble&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;toFour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  filter
&lt;/h3&gt;

&lt;p&gt;Filter takes a function and a linked list, and produces a new linked list by applying the function to each element of the argument, conserving or discarding it, depending on whether the function returns true or false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* iterators.c */&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pass to the &lt;code&gt;filter&lt;/code&gt; what is called a &lt;em&gt;predicate&lt;/em&gt;: a function that returns a boolean value. We take the value of the head of the list, and apply the predicate to it. If it returns true, we &lt;code&gt;cons&lt;/code&gt; that value into a new list built by the recursive application of &lt;code&gt;filter&lt;/code&gt; to the next elements. If it returns false, we discard it, and proceed with the recursion of the tail.&lt;/p&gt;

&lt;p&gt;Let us define a few different functions that can be passed to &lt;code&gt;filter&lt;/code&gt;, and create a filtered list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;greaterThanTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* main.c */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;greaterThanTwo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 2 4&lt;/span&gt;
  &lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 3 4 5&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;greaterThanTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  reduce
&lt;/h3&gt;

&lt;p&gt;Reduce takes a function, a linked list, and an accumulator, and returns the result of applying the function to the accumulator and to every element of the list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* iterators.c */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;reduce&lt;/code&gt; function receives a &lt;em&gt;binary operator&lt;/em&gt;: a function with two arguments, just like the basic arithmetic operators. We take the head of the list and apply the binary operator to it, together with the accumulator. Then, we set the result as the new value of the accumulator, and recursively repeat the operation on the next elements of the list.&lt;/p&gt;

&lt;p&gt;Let us define a few different functions that can be passed to &lt;code&gt;reduce&lt;/code&gt;, and compute the value of a reduced list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* functional.h */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sumTimesTen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* main.c */&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;greaterThanTwo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 15&lt;/span&gt;
&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// prints 150&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sumTimesTen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have developed a way to implement the popular tools for a functional programmer -- map, filter, reduce -- in C, a language that does not really support lambda functions. &lt;/p&gt;

&lt;p&gt;To recap, the first thing we had to consider was the data structure on which we wanted to operate. We chose the linked list, the standard data structure for collecting items in functional programming languages like Scheme, Haskell and Erlang. We defined or linked list as pointers to nodes, every node being a structure that stores some data (an integer) and points to the next item of the list. The end of the list is marked by a nil pointer (a zero value). We have also define a &lt;code&gt;cons&lt;/code&gt; function that allows us to construct a list by plugging elements to an existing list (or to an empty list, represented by a nil pointer).&lt;/p&gt;

&lt;p&gt;One thing to keep in mind is that this is meant to be merely a study on recursive data structures and function pointers, and not a proposal for &lt;em&gt;functional programming in C&lt;/em&gt;. One major problem with our approach is that, in order to achieve the immutability of data structures, we are allocating new data to memory, but we haven't provided any way to clean the unnecessary or unused data. That would require a garbage collector, something that is not provided in C, and is beyond the scope of this exercise.&lt;/p&gt;

&lt;p&gt;Another thing worth mentioning is that our functions are limited to working with integer types &lt;code&gt;int&lt;/code&gt;. It would have been nice to implement some sort of &lt;em&gt;parametric polymorphism&lt;/em&gt;, that is, defining of function types to accept any types of arguments.&lt;/p&gt;

&lt;p&gt;I would appreciate any comments, corrections, critiques or suggestions.&lt;/p&gt;




&lt;p&gt;Functions used but not explained in the article:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printlist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



</description>
      <category>functional</category>
      <category>c</category>
      <category>computerscience</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Abstraction, Composition as Software Development Fundamentals: Reading List 1-3/2022</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Tue, 15 Mar 2022 20:27:05 +0000</pubDate>
      <link>https://dev.to/escribapetrus/abstraction-composition-as-software-development-fundamentals-reading-list-1-32022-40l6</link>
      <guid>https://dev.to/escribapetrus/abstraction-composition-as-software-development-fundamentals-reading-list-1-32022-40l6</guid>
      <description>&lt;p&gt;I have decided to organise my studies of computer science based on trimestral reading lists. For the first trimester, I am taking the advice of Joe Armstrong, from his talk "Computer Science: A Guide for the Perplexed". Between January and March, I set myself to reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Algorithms + Data Structures = Programs, Niklaus Wirth;&lt;/li&gt;
&lt;li&gt;The Mythical Man-Month, Frederick Brooks;&lt;/li&gt;
&lt;li&gt;Category Theory for Programmers, Bartosz Milewski.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The three texts discuss computer science on a fundamental level, but from three different aspects: the elements and operations of computer programs, the human process of writing software systems and products, and the algebra of high-level abstractions that on a lower level manifest themselves as data and algorithms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstraction and Composition
&lt;/h2&gt;

&lt;p&gt;Despite these differences in perspective, there are points of convergence between the three texts. The first is the role of &lt;strong&gt;abstraction&lt;/strong&gt; as a way of conceiving programs, making the understanding easier and the architecture leaner. The second is the idea that &lt;strong&gt;composition&lt;/strong&gt; is the fundamental operation in the architecture and building of programs and software systems.&lt;/p&gt;

&lt;p&gt;Abstraction in computer science can be described as the action of zooming out, blurring details and providing a wide view. By abstracting, we hide the particular qualities of something and treat it simply as a named object; we hide the individual operations in a program and treat it as a named function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{red, wheels: 4, fuel: .8, ignition: off} → car
{1 * 2 * 3 * 4 * ... n} → factorial(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Composition, on the other hand, is the action of joining parts of a program to solve a complex problem. &lt;/p&gt;

&lt;p&gt;Both operations, composition and abstraction, can be applied iteratively. Consider the biosphere: it is a humongous quantity of atoms, related to each other or not based on the laws of physics, forming molecules. That is a ridiculously complex system to understand in terms of their interactions as living beings, so we abstract the complex structures of molecules into objects, and call these cells, which interact with each other by forming tissues and organs. But these systems are still far too complex; therefore, we iterate the same process, abstracting organisms into living beings, living beings into species, species into classes, kingdoms, and so on. &lt;/p&gt;

&lt;p&gt;The same can be applied to computer systems, to great effect. We join elements to each other to create data structures, and can compose data structures themselves. We join functions acting on data, and create programs. We join programs to create systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithms + Data Structures = Programs
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"A systematic and scientific approach to program construction is bound to include all aspects of data structuring. Programs, after all, are concrete formulations of abstract algorithms based on particular representations and structures of data."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The progress of almost all sciences can be traced back to a few fundamental principles from which they develop. In the study of Metaphysics, for example, we are required to understand the concepts of substance and attributes, the intellect and the extension, the entities and the phenomena. All further development and the branching of newer disciplines depends on these principles. The same goes for the science of computation by machines.&lt;/p&gt;

&lt;p&gt;This book, in the spirit of modern philosophers, concerns itself with the first principles of computer science: primitive data, basic operators, &lt;strong&gt;composition&lt;/strong&gt; of data (fundamental and recursive data structures), composition of operations (procedures and functions), the building blocks of computer programs, from which we can build all sorts of complex systems. &lt;/p&gt;

&lt;p&gt;The book is divided into 5 subjects. Each step is necessary for the next; just like we design programs by composition of functions and data types, we understand the science itself by composing ideas. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic data structures;&lt;/li&gt;
&lt;li&gt;Algorithms;&lt;/li&gt;
&lt;li&gt;Recursion;&lt;/li&gt;
&lt;li&gt;Advances data types;&lt;/li&gt;
&lt;li&gt;Compilers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Concerning data, the main problem is how we represent the &lt;strong&gt;abstract&lt;/strong&gt; objects, structures and operations we have conceptually designed (i.e. the product), in a form that fits and executes in the physical constraints of the machine. &lt;br&gt;
For this, we require a readable abstraction for the binary operations done by the machine, allowing us to represent the data structures and operations that compose the system in a human language. This is the finality of the programming language. The author explains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The essence of the use of abstractions in programming is that a program may be conceived, understood, and verified on the basis of laws governing the abstractions, and that it is not necessary to have further insight about how the abstractions are implemented and represented in a physical computer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The programming language allows us not only to represent the simple elements, but also to abstract functions and procedures as named objects, therefore allowing us to reference them, and implement repetitive operations through recursion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fact 0 = 1
fact n = n * fact(n - 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By applying the idea of recursive referencing to data, we can also create repetitive, complex, and potentially infinite data structures, such as lists and n-ary trees. In a lower level, these abstract structures are implemented as pairs or tuples of elements, containing the element itself and references (pointers) to the next elements in the structure. But in a high level abstraction, these can be defined very simply in programming language notation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;list(a) = [] | [a | list(a)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are called dynamic structures, due to the fact that their structure and size change during the execution of the program. We can see that there are similarities between the definitions of algorithms and data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mythical Man-Month
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recognising that the human aspect -- communication, leadership and subordination, decision making --  is a major part of software development is a hard pill to swallow. What we want is to explore new technologies, to write algorithms that produce expected results, and to create programs that solve real problems. But the reality is that problems are rarely understood, and conceptual schematics are rarely precise, leading to great difficulties in the ideally simple task of writing programs -- after all, how do we write stuff when we don't know what it is we have to write?&lt;/p&gt;

&lt;p&gt;Joe Armstrong describes software development, in physics' terms, as an entropy-increasing process. It is an essential and inescapable problem that, as a project grows, so does the complexity of functions, procedures, and data structures: more attributes, more states to keep track, more secondary effects, more dependencies, more errors to handle.&lt;/p&gt;

&lt;p&gt;The main virtue of software systems and products is described by Brooks as conceptual integrity: removing unnecessary components, therefore reducing potential bugs and making the system more easily understood. The task of the product developer is therefore to make the product grow, while containing the spread of complexity.&lt;/p&gt;

&lt;p&gt;The project, as described by Brooks, has two requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;conceptual design, the logical &lt;strong&gt;abstract&lt;/strong&gt; structure of how the parts of the system interact implementation;&lt;/li&gt;
&lt;li&gt;representation (implementation) of the abstract structures as programming language code and compiled machine language code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both these aspects force us to face the problem of growing complexity. The main takeaway is that software development is an art that allows us to create great things, but it comes with a challenge for which there is no magical solution. We cannot wait for a wonderful programming language, machine or project management framework to make complexity disappear or communication to flow flawlessly. All we can do is, through diligence, apply proven experiences and try new things. &lt;/p&gt;

&lt;p&gt;From the first programs in machine code to our current state of the art, several techniques have been developed and proven to work, both in terms of architecture and implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;centralised architecture and decision-making, which improves conceptual integrity;&lt;/li&gt;
&lt;li&gt;rapid prototyping and incremental growth, which allows feedback iteration;&lt;/li&gt;
&lt;li&gt;high-level languages, which remove accidental flaws;&lt;/li&gt;
&lt;li&gt;improved tooling, which speeds up development and tests;&lt;/li&gt;
&lt;li&gt;object-oriented programming, with abstract data types and inheritance&lt;/li&gt;
&lt;li&gt;interactive programming;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We could add to the list the more recent trend of functional programming, which reduces bugs by eliminating side effects, and providing the ideal conditions for concurrent programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Category Theory for Programmers
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"I hope future generations will be as admiring of the programming skills we've been displaying in building complex operating systems, web servers, and the internet infrastructure [as we admire the builders of old gothic cathedrals]. And they should be, because we've done all this based on flimsy theoretical foundations. We have to fix those foundations if we want to move forward."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a standard method of solving problems which seems to be common in a wide range of intellectual activities: it is the method of dividing a complex problem into smaller chunks, solving them separately, and &lt;strong&gt;composing&lt;/strong&gt; the solutions. For example: when we try to understand a complex historical event, such as a revolution or a war, we cannot fully grasp the entire situation all at once; rather, we divide the narrative by different aspects: the economy, the political relationships of leaders, the cultural, philosophical and artistic spirit of the time. These aspects interact with one another, producing the results we call events.&lt;/p&gt;

&lt;p&gt;Similarly, we use decomposition and composition in all sciences: mathematics, physics, music, computer science. The author of the book poses the question of whether this method is the way our species evolved to think.&lt;/p&gt;

&lt;p&gt;Category theory is the science of &lt;strong&gt;abstraction&lt;/strong&gt; par excellence. It allows us to understand the structure of complex systems, and how the elements interact with each other, without making reference to their qualities. It takes information and stripes down to the bare essentials, until all we have left are objects and arrows between them.&lt;/p&gt;

&lt;p&gt;Categories are described in terms of objects and morphisms, where morphisms are arrows that go from one object to the next, and compose with one another. In the realm of programming, for example, we are mostly working with the category Type, where objects are types and morphisms are functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f :: a → b
g :: b → c
g . f :: a → b → c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But abstractions, as we described earlier, can be employed iteratively. Just as we have described functions as morphisms between objects in the category Type, we can wrap this structure in an object, and throw it as an object in a new category. This is the category Cat, where objects are small categories and morphisms are functors.&lt;/p&gt;

&lt;p&gt;A functor is a mapping of objects and morphisms between two categories. Given a category C, a functor F maps its objects and morphisms to a category D, preserving identity and composition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For C (a, b), where f :: a → b
Functor F gives D (Fa, Fb), where Ff :: Fa → Fb
For h = g . f in C
Fh = Fg . Fh in D 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mapping of morphisms is implemented as a higher order function fmap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(a → b) → (Fa → Fb)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In programming, functors can be understood as parametric type constructors: equations that, given a type, produce a new type. We can, for example, take a type int and map it to types such as maybe_int or list_of_ints. Or, we can take the types int and boolean, and construct a list_of_ints_and_bools applying a bifunctor.&lt;/p&gt;

&lt;p&gt;We can continue abstracting these structures to higher degrees. Just as we wrapped the objects and morphisms of small categories, forming Cat, we can wrap its objects and morphisms (functors) and throw these in a new category. This is the category Fun, where objects are functors and morphisms are natural transformations (mappings of functors).&lt;/p&gt;

&lt;p&gt;As we can see, category theory is a powerful exercise in abstraction and composition, which, as was mentioned before, are often described as the essentials of programming. This ultra abstract science reveals to us a top-down approach to thinking. It consists of the declaration of general, abstract principles, that are then developed into material entities, just like the platonic idea of a chair is materialised into wooden or metal chairs. Brooks calls this the top-down approach for software development, where the work is divided between architecture (or design) and representation (or implementation). &lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>software</category>
      <category>projectmanagement</category>
      <category>categorytheory</category>
    </item>
    <item>
      <title>Fantasy-Oriented Programming</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Wed, 12 Jan 2022 15:56:31 +0000</pubDate>
      <link>https://dev.to/escribapetrus/fantasy-oriented-programming-5gan</link>
      <guid>https://dev.to/escribapetrus/fantasy-oriented-programming-5gan</guid>
      <description>&lt;p&gt;Fantasy is the realm of imagination, magic, and dreaming about endless possibilities, even the seemingly or truly impossible. It allows us not just to question "what would it be if...", but actively express and create possible worlds, even if they do not make sense in reality. Sure, giant reptiles cannot fly and spit fire: there is no muscle mass and energy source that would allow that; &lt;em&gt;but what if they did&lt;/em&gt;? &lt;/p&gt;

&lt;p&gt;Programming is a fantastic activity, even if we lose sight of that aspect. It creates reasoning -- a spiritual thing -- from sand and metal; that is something not even the most audacious magicians and alchemists could dream. It is no joke when Sussman compares sorcery and computation, which harnesses the demon in the machine to produce magic results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You, the Spirit of Earth, are nearer:&lt;br&gt;
Already, I feel my power is greater,&lt;br&gt;
Already, I glow, as with fresh wine.&lt;br&gt;
I feel the courage to engage the world,&lt;br&gt;
Into the pain and joy of Earth be hurled&lt;br&gt;
And though the storm wind is unfurled,&lt;br&gt;
Fearless, in the shipwreck’s teeth, be whirled."&lt;/em&gt;&lt;br&gt;
Faust conjures the Earth Spirit, Goethe, pt. I, sc. I&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fantasy-oriented programming is not a paradigm. Rather, it is an ethos, a reflective understanding of ourselves as programmers. By contemplating the abstract, philosophical, and almost mystic aspects of programming, we allow ourselves to feel awe -- a double affection of being at the same time terrified and fascinated by greatness -- in face of the vast universe of possibilities offered by computation by machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Art and science: identity and difference
&lt;/h2&gt;

&lt;p&gt;There is in programming a tension between science and art, which is common to all human activity.&lt;/p&gt;

&lt;p&gt;By science, I mean the work of the human mind, &lt;em&gt;the abstraction of real entities into symbolic representations, and the logical operations of the intellect on these symbols&lt;/em&gt;. Think geometry, computer algorithms, musical composition.&lt;/p&gt;

&lt;p&gt;By art, I mean the work of the human hand, &lt;em&gt;the hypostasis of spiritual entities into real substance by transforming the physical matter&lt;/em&gt;. Think building a house, manufacturing computer hardware, playing the guitar.&lt;/p&gt;

&lt;p&gt;Programming has these two contradictory aspects at once, coexisting in a harmony. They cannot exist one without the other. We cannot compute equations without giving instructions to the processor, which transforms them into the physical reality of electrical pulses; conversely, it is in the symbolic representation of these physical realities that we find meaning through equations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pragmatic ethos
&lt;/h2&gt;

&lt;p&gt;There is a pragmatic approach to programming that is akin to the work of the artist. The Artist does not care about the alignment of doors and windows to the stars and constellations; he does not need to understand the principles of trigonometry in order to build walls and a roof. He has built many houses, and knows how it is done, by experience.&lt;/p&gt;

&lt;p&gt;The spirit of the Artist lives in the pragmatic programmer. His job is not to make systems that correctly implement mathematical equations; he does not care about the abstraction of types and sets into categories; the word &lt;em&gt;monad&lt;/em&gt; to him is a distraction, nothing more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scientific ethos
&lt;/h2&gt;

&lt;p&gt;Similarly, there is a scientific approach to programming. The Philosopher spends his days pondering questions his kindred, the Artist, rejects, marveling at how objects in the world can be represented in a language of mathematical symbols, and how even these symbols can be expressed by even more abstract representations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The virtue of balance
&lt;/h2&gt;

&lt;p&gt;There is a reason why the book "The Pragmatic Programmer" is considered a classic in this field. Pragmatism is a major virtue in programming. As developers, our job is not to prove mathematical theorems, but to create systems that are useful, that add value to the lives of users, whether in daily work, study or leisure. &lt;/p&gt;

&lt;p&gt;Pragmatism is also a major asset in the professional career of a programmer. As a Philosophy major, I have often heard people say: "that is so fascinating; but what do you do with it, for a job?". This is a legitimate concern. Companies are not concerned with understanding the mysteries of the universe and the human experience, but rather with developing, launching and selling products. So, what matters is the skills and tools you can effectively use. For example, if you're a marketer, it does not matter whether you have any insights about communication in abstract, but only whether you can communicate the advantages of a product over the competition in 50 words or less. The same goes for programming.&lt;/p&gt;

&lt;p&gt;If no employer is ever going to ask us &lt;em&gt;"how to express computation with lambda calculus"&lt;/em&gt;, or for a &lt;em&gt;comprehensive intuition about monads&lt;/em&gt;, what is the purpose of learning these things? Rather than spending time and mental energy with that, is it not more beneficial to apply these resources to learn something practical like how to operate the Amazon cloud or build apps with Flutter?&lt;/p&gt;

&lt;p&gt;"More useful", yes, definitely. But I would argue that there is a virtue in harnessing the philosophical spirit, even to the most pragmatic programmer. It challenges us to unravel an arcane knowledge through the power of spirit; it reveals to us that the universe is wider than our comprehension, and that our practical action of constructing things using tools is the expression of timeless principles; it shows us that there are people out there who have attained higher wisdom, which beckons us to keep moving forward. &lt;/p&gt;

&lt;p&gt;I remember the first time I watched a class about Haskell. The explanation of how we can represent complex logical and mathematical operations with the simple notation of lambda calculus is something I will never forget. I felt like the young Artie listening to Merlin, fascinated by the wizard's wisdom and his wonderful tales of the achievements of art and science.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--StdBe0z9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yq94a19o7ivktfdg1bf8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--StdBe0z9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yq94a19o7ivktfdg1bf8.jpeg" alt="The Sword In The Stone, my favorite Disney movie" width="880" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That fascination, which fuels passion and curiosity, is the source of my belief in the virtue of contemplating the philosophical aspects of computer science. That is fantasy-oriented programming.&lt;/p&gt;

&lt;p&gt;In summary, there is nothing I can say that Byron has not said better, in these words: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I love not Man the less, but Nature more,&lt;br&gt;
From these our interviews, in which I steal&lt;br&gt;
From all I may be, or have been before,&lt;br&gt;
To mingle with the Universe, and feel&lt;br&gt;
What I can ne'er express, yet cannot all conceal."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>software</category>
      <category>art</category>
      <category>science</category>
      <category>ethics</category>
    </item>
    <item>
      <title>Compreendendo tipos de dados algébricos com exemplos em Elixir</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Mon, 20 Dec 2021 17:55:00 +0000</pubDate>
      <link>https://dev.to/escribapetrus/compreendendo-tipos-de-dados-algebricos-com-exemplos-em-elixir-33ff</link>
      <guid>https://dev.to/escribapetrus/compreendendo-tipos-de-dados-algebricos-com-exemplos-em-elixir-33ff</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Il est des jours de brume et de lumière vague,&lt;br&gt;
Où l'homme, que la vie à chaque instant confond,&lt;br&gt;
Étudiant la plante, ou l'étoile, ou la vague,&lt;br&gt;
S'accoude au bord croulant du problème sans fond."&lt;br&gt;
Victor Hugo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Números, no mundo real, raramente são apenas números. Pelo contrário, quase sempre apresentam-se como valores relativos a um certo atributo, categoria, unidade de medida. Se alguém dissesse: "este prédio tem 48", nossa resposta imediata seria, "48 o que?"&lt;/p&gt;

&lt;p&gt;Imaginemos um prédio com 48 metros de altura. Isso é tudo que podemos dizer sobre este prédio? É claro que não. Podemos enumerar uma série de valores e atributos que descrevem esse prédio e compõem sua existência. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;pr&lt;/span&gt;&lt;span class="err"&gt;é&lt;/span&gt;&lt;span class="n"&gt;dio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="ss"&gt;altura:&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;unidades:&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;cores:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:branco&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:laranja&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;categoria:&lt;/span&gt; &lt;span class="ss"&gt;:comercial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;completo:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa descrição é bastante inteligível, e nos permite imaginar um prédio real. Levando esse exercício mais longe, poderíamos abstrair os valores específicos, descrevendo um prédio platônico, uma ideia de todos os prédios possíveis. Construiríamos, assim, um &lt;em&gt;tipo de dados prédio&lt;/em&gt;, composto pelos diferentes tipos de dados que descrevem os prédios (altura, unidades, cores, categorias, estágio de construção). &lt;/p&gt;

&lt;p&gt;Neste artigo, explicaremos os tipos de dados algébricos, isto é, como definir tipos de dados compostos de tipos singulares e as regras que governam sua composição. Mostraremos os exemplos mais comuns de tipos de dados algébricos, como tipo multiplicação e soma de tipos, tipos de funções ou exponenciação de tipos, e tipos recursivos, utilizando exemplos na linguagem Elixir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de dados
&lt;/h2&gt;

&lt;p&gt;Toda computação é uma operação sobre valores de determinados tipos. Para explicar os tipos de dados, a ciência da computação costuma referir-se ao tamanho e à disposição dos números binários que expressam os elementos de diferentes tipos: desta maneira é formalizada a distinção entre &lt;em&gt;Integers&lt;/em&gt; e &lt;em&gt;Longs&lt;/em&gt;, &lt;em&gt;Floats&lt;/em&gt; e &lt;em&gt;Doubles&lt;/em&gt; -- quanto maior o espaço em memória reservado aos valores, maior a precisão ou o limite de valores representáveis. A mesma explicação vale para coleções de tipos, como arrays de tamanho fixo: o tamanho da coleção é o tamanho do dado multiplicado pelo numero de entradas na coleção&lt;/p&gt;

&lt;p&gt;Entretanto, essa explicação é limitada quando queremos nos referir a certos valores computáveis. Por exemplo, como podemos expressar em termos de quantidade de bits uma coleção com um número indeterminado de valores; ou, em outras palavras: qual é o tamanho de uma coisa da qual não sabemos o tamanho?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;tamanho&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;tamanho&lt;/span&gt;&lt;span class="p"&gt;([]),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;tamanho&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tamanho&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É claro, neste exemplo, que o tipo &lt;code&gt;list()&lt;/code&gt; não pode ser definido em termos de quantidade de bits, porque a quantidade varia de acordo com o tamanho da lista. Vamos, então, usar outra explicação: &lt;em&gt;tipos são representações abstratas de valores possíveis de operações computacionais&lt;/em&gt;. Em uma analogia com a teoria matemática dos conjuntos, um tipo é um conjunto de valores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de dados algébricos
&lt;/h2&gt;

&lt;p&gt;Da mesma maneira como somos capazes de criar funções que operam sobre números e produzem determinados valores, podemos definir operações sobre tipos de dados, que produzam tipos compostos de outros tipos. &lt;/p&gt;

&lt;p&gt;Entretanto, tipos de dados são muito diferentes de números. Antes de realizar operações com tipos de dados, precisamos descrever uma certa álgebra que governe as regras de composição dos tipos. Para isso, recorremos à matemática, especificamente à teoria dos conjuntos. &lt;/p&gt;

&lt;p&gt;Tipos de dados algébricos nos permitem definir coisas como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;#apelidos&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;palavras_magicas&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;charlist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#tipos compostos&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:fogo&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:terra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:agua&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:ar&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;mistura&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;transformacao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#tipos recursivos&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lista&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;arvore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arvore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;arvore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entendidos de forma matemática, tipos de dados algébricos podem ser definidos em termos de três operações básicas: soma, multiplicação e potenciação. Assim como entendemos um tipo de dados como o conjunto dos seus valores possíveis, &lt;em&gt;um tipo composto é o conjunto dos valores possíveis resultante da composição&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Soma de tipos
&lt;/h2&gt;

&lt;p&gt;O que significa falar sobre a soma de dois tipos de dados, como "inteiro mais booleano"? A idéia parece estranha a princípio. Para entender, vamos primeiro pensar sobre a soma de números, que já conhecemos: dois mais três são cinco, quatro mais cinco são nove, e assim por diante. &lt;/p&gt;

&lt;p&gt;A soma de tipos é semelhante. Se descrevermos um tipo como o conjunto dos valores possíveis, a soma de tipos é a soma do número desses valores. Por exemplo, imaginemos um tipo "certeza", com dois valores: verdadeiro e falso; imaginemos um tipo que tem apenas um valor possível, e vamos chamá-lo de "dúvida". Somando os dois tipos, compomos um tipo com três valores possíveis: ou é verdadeiro, ou é falso, ou é duvidoso. Vamos chamar esse tipo de "hipótese":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;duvida&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:undefined&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;certeza&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;hipotese&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;duvida&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;certeza&lt;/span&gt;

&lt;span class="n"&gt;valores_possiveis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:undefined&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É fácil entender que somamos tipos com 1 e 2 valores, e obtivemos um tipo com 3 valores. Em matemática, na teoria dos conjuntos, essa composição é chamada de disjunção: "A ou B".&lt;/p&gt;

&lt;p&gt;Funções que aceitam tipos compostos dessa maneira apresentam comportamentos diferentes dependendo do tipo de dado utilizado (o que nos levaria a um outro tópico, &lt;em&gt;polimorfismo&lt;/em&gt;, que não trataremos neste artigo). Para isso, é necessário utilizar estruturas condicionais, como &lt;em&gt;if, guards ou pattern match&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;is_boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:bool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;is_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:int&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Representamos a soma de tipos como &lt;code&gt;a + b&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiplicação de tipos
&lt;/h2&gt;

&lt;p&gt;A multiplicação de tipos segue uma lógica semelhante. Para entender, vamos primeiro pensar sobre a multiplicacão de números, que já conhecemos: dois vezes três são seis, três vezes três são nove, e assim por diante. &lt;/p&gt;

&lt;p&gt;A multiplicação de tipos é semelhante. Se descrevermos um tipo como o conjunto dos valores possíveis, a multiplicação de tipos é a multiplicação do número de valores desses tipos. Por exemplo, imaginemos um tipo "materiais", com dois valores: "madeira" e "pedra"; imaginemos um tipo "cores", com três valores, "branco", "amarelo" e "azul". Multiplicando os dois tipos, compomos um tipo com seis valores possíveis. Vamos chamar esse tipo de "casa":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:madeira&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:pedra&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;cor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:branco&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:amarelo&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:azul&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;casa&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;cor&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="n"&gt;valores_poss&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;veis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:madeira&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:branco&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:madeira&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:amarelo&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:madeira&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:azul&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:pedra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:branco&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;  
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:pedra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:amarelo&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:pedra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:azul&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É fácil entender que multiplicamos tipos com 2 e 3 valores, e obtivemos um tipo com 6 valores. Em matemática, na teoria dos conjuntos, o número de valores do produto de dois tipos corresponde ao produto cartesiano de dois conjuntos, e o valor composto a uma intersecção, "A e B".&lt;/p&gt;

&lt;p&gt;Para nossa surpresa, esse tipo de dado algébrico não é uma novidade, mas um velho conhecido: uma tupla de n valores. Esta é a razão por que os &lt;em&gt;records&lt;/em&gt; em Erlang (nome dado para &lt;em&gt;structs&lt;/em&gt; ou &lt;em&gt;hash tables&lt;/em&gt;, coleções de valores de tipos distintos) são implementados simplesmente como tuplas normais.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;casa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cor&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;

&lt;span class="nl"&gt;#casa&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;madeira&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;branco&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;
&lt;span class="c"&gt;% é o mesmo que
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;casa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;madeira&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;branco&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Representamos a multiplicação de tipos como &lt;code&gt;a * b&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  E quando o número de valores for infinito?
&lt;/h2&gt;

&lt;p&gt;Quando entendemos a composição de tipos de valores finitos, fica fácil entender a composição de tipos de valores infinitos. Lembremos que na matemática, na teoria dos conjuntos, nem todos os infinitos são iguais: o conjunto dos números reais é infinito; o conjunto de números divisíveis por 999 também é infinito, mas eles são infinitos muito diferentes. &lt;/p&gt;

&lt;p&gt;Vamos definir um tipo "booleano inteiro"; em outras palavras, um número que pode ser verdadeiro ou falso. Para isso, multiplicamos o tipo booleano pelo tipo inteiro. Nosso novo tipo tem um número de valores possíveis que é o número de valores possíveis do tipo booleano vezes o número de valores possíveis do tipo inteiro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;booleano&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:verdadeiro&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:falso&lt;/span&gt;
&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;inteiro&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; 
&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;bool_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;booleano&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;inteiro&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="n"&gt;valores&lt;/span&gt; &lt;span class="n"&gt;poss&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;veis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:verdadeiro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:verdadeiro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:verdadeiro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:falso&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:falso&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:falso&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tipos de funções
&lt;/h2&gt;

&lt;p&gt;Em muitas linguagens de programação, funções são objetos de primeira classe, ou seja são entidades em si próprias, e podem ser registradas em variáveis, passadas como argumentos de funções ou retornadas como resultados de uma função. A exponenciação de tipos é a composição de tipos em tipos de funções, isto é, corresponde ao conjunto de funções que mapeiam valores de um tipo a outro. &lt;/p&gt;

&lt;p&gt;Por exemplo, podemos definir um tipo de função "validação numérica" que aceita um valor inteiro e retorna um valor booleano. Utilizamos funções do tipo "validação" como funções de alta ordem, aplicando à função "validar" para garantir que um valor é válido ou não para determinada aplicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;validacao&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;charlist&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;validar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;validacao&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;validar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;regra&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:erro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"valor inválido"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tipos de dados algébricos nos proporcionam propriedades interessantes para pensar a lógica e a matemática das funcões em programas computacionais. Por exemplo, sabemos que na álgebra do conjunto de números reais, a seguinte propriedade é válida: &lt;code&gt;a^(b+c) = a^b * a^c&lt;/code&gt;. Ora, esta propriedade também é válida para tipos algébricos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:agua&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:ar&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:fogo&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:terra&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;espirito&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:trevas&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:luz&lt;/span&gt; 
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;efeito&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:boom&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:kablam&lt;/span&gt;

&lt;span class="c1"&gt;# a^(b+c)&lt;/span&gt;
&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;magia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;esp&lt;/span&gt;&lt;span class="err"&gt;í&lt;/span&gt;&lt;span class="n"&gt;rito&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;efeito&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;magia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;elemento?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:boom&lt;/span&gt;
        &lt;span class="n"&gt;espirito?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:kablam&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# a^b * a^c`&lt;/span&gt;
&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;feitico&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elemento&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;efeito&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;feitico&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;elemento?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:boom&lt;/span&gt;

&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;bruxaria&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;espirito&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;efeito&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;bruxaria&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;espirito?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;poder&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:kablam&lt;/span&gt;


&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;elemento?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:agua&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fogo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:terra&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;espirito?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:trevas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:luz&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que a propriedade descreve é que o mesmo cálculo pode ser representado de duas maneiras distintas: como duas funções que aceitam tipos a e b, ou como uma só função que aceita um tipo composto a + b.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos recursivos
&lt;/h2&gt;

&lt;p&gt;Vimos como representar tipos compostos de um número definido de elementos: pares, tuplas, variantes. Estes tipos, embora nos proporcionem um grande poder expressivo para estruturar os dados de um programa, ainda não respondem uma questão que colocamos no início: como podemos representar um conjunto com um número indefinido de elementos? &lt;/p&gt;

&lt;p&gt;Para isso, precisamos recorrer a um dispositivo que nos permita trabalhar com repetições. Em programação funcional, esse dispositivo é a recursão. Da mesma maneira como podemos definir funções recursivas que expressam-se em termos de si mesmas, podemos definir tipos que expressam-se em termos de si mesmos, recursivamente. Podemos, por exemplo, definir uma lista como a junção de um elemento a uma lista.&lt;/p&gt;

&lt;p&gt;Vamos definir uma lista de animais. Para isso, vamos usar a conjunção que vimos antes na &lt;em&gt;multiplicação de tipos&lt;/em&gt;, e expressar nossa lista como uma tupla recursiva:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:gato&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:cachorro&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:hamster&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:galinha&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;lista_de_animais&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lista_de_animais&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

&lt;span class="n"&gt;meus_bichos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:gato&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hamster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}}}}}}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vejamos que não precisamos nos restringir ao &lt;em&gt;tipo list()&lt;/em&gt; nativo do Elixir para definir nosso tipo. Não é o tipo de coisa que utilizaríamos em um projeto em produção, é claro: para isso, é sempre recomendado utilizar o padrão estabelecido pela comunidade. Mesmo assim, o que esses tipos representam é fundamentalmente a mesma coisa -- um tipo algébrico recursivo definido pela conjunção de um elemento a uma lista de elementos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:gato&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hamster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;#é o mesmo que&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:gato&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:hamster&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:peixe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[]]]]]]&lt;/span&gt;
&lt;span class="c1"&gt;#que não é muito diferente de&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:gato&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hamster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:peixe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}}}}}}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outro exemplo de um tipo recursivo é a árvore binária, que pode ser definida como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;planta&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:folha&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;planta&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;planta&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; 

&lt;span class="n"&gt;grama&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:folha&lt;/span&gt;
&lt;span class="n"&gt;muda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:folha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:folha&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;arbusto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:folha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:folha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:folha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="p"&gt;{}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="ss"&gt;:folha&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo, nosso tipo planta() não é muito útil, porque não nos permite registrar nada além de folhas. Mas o poder expressivo desse tipo fica claro se percebermos que o tipo &lt;em&gt;folha&lt;/em&gt; poderia ser qualquer outro tipo, simples ou complexo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observação sobre os exemplos em Elixir
&lt;/h2&gt;

&lt;p&gt;Antes de concluir, vale adicionar uma nota sobre a relevância deste assunto no contexto da linguagem de programação Elixir e do ecossistema Erlang. Ambas as linguagens são dinamicamente tipadas e, desta forma, a verificação de tipos de dados ocorre em tempo de execução. Isso significa que, em geral, as especificações de tipos servem mais para documentar o código do que efetivamente restringir a execução, garantir a correção e acusar erros. Desta forma, o entendimento de tipos de dados algébricos não é tão indispensável para a programação como no caso de linguagens estaticamente tipadas. Mesmo assim, optamos por utilizar o Elixir para os exemplos pela familiaridade e gosto pelo linguagem.&lt;/p&gt;

&lt;p&gt;Precisamos ainda dar os devidos créditos. Este artigo é inspirado na apresentação do programador e matemático Bartosz Milewski, a propósito de tipos algébricos e sua representação na linguagem C++. A apresentação é de 2018, e pode ser vista &lt;a href="https://www.youtube.com/watch?v=LkqTLJK2API"&gt;clicando aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Neste artigo, vimos como é possível expandir nossa capacidade de representar informações por meio da compreensão dos tipos de dados algébricos, que nos permitem compor tipos singulares em tipos mais complexos e expressivos. Vimos, ainda, como certas estruturas que já conhecemos são, fundamentalmente, expressões dessa álgebra de tipos de dados.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>functional</category>
      <category>programming</category>
    </item>
    <item>
      <title>Implementando estados mutáveis e arquitetura cliente-servidor com funções recursivas e troca de mensagens entre processos</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Mon, 20 Dec 2021 17:41:57 +0000</pubDate>
      <link>https://dev.to/escribapetrus/implementando-estados-mutaveis-e-arquitetura-cliente-servidor-com-funcoes-recursivas-e-troca-de-mensagens-entre-processos-1hlf</link>
      <guid>https://dev.to/escribapetrus/implementando-estados-mutaveis-e-arquitetura-cliente-servidor-com-funcoes-recursivas-e-troca-de-mensagens-entre-processos-1hlf</guid>
      <description>&lt;p&gt;O objetivo deste artigo é apresentar como é possível implementar estados mutáveis em uma linguagem funcional sem variáveis globais, utilizando funções recursivas. Para ilustrar, utilizaremos como exemplo os processos e troca de mensagens no sistema Elixir. A abstração dessas operações nos permite implementar uma arquitetura cliente-servidor com uma clara separação entre requisições de consulta e atualização dos dados por parte do usuário, e a computação dos dados por parte da máquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estados mutáveis
&lt;/h2&gt;

&lt;p&gt;Computadores, como implementações da máquina de Turing, são essencialmente máquinas de estado mutável. Um tocador de música, por exemplo, embora não tenha todas os atributos de uma máquina de Turing, também é uma máquina de estado mutável: ele registra uma música atual e, de acordo com o tempo ou o input de um usuário, aciona funções de tocar, pausar ou trocar de música. A música que está tocando é registrada na chamada &lt;em&gt;variável global&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Esta é a base da computação imperativa, e pode ser exemplificada pelo código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rainbow - Stargazer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="nx"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Now playing: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// Now playing: Rainbow - Stargazer&lt;/span&gt;
&lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rainbow - Self Portrait&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// Now playing: Rainbow - Self Portrait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A programação funcional, implementação do &lt;a href="https://pt.wikipedia.org/wiki/C%C3%A1lculo_lambda"&gt;cálculo lambda&lt;/a&gt; para sistemas computacionais, opera basicamente com funções puras para a computação de dados. Por definição, é um paradigma no qual não existem variáveis globais. Mas se o que dissemos é verdade, e computadores são implementações da máquina de Turing, uma máquina de estados mutáveis, como é possível a computação sem variáveis globais? Ou, perguntando de outra forma: como seria possível, sem variáveis globais, implementar uma máquina de estados mutáveis, capaz se registrar e, mais importante, alterar os dados registrados após a computação?&lt;/p&gt;

&lt;h2&gt;
  
  
  Processos e troca de mensagens
&lt;/h2&gt;

&lt;p&gt;Antes de apresentar a solução para este problema, precisamos esclarecer duas ideias fundamentais para nossa implementação: &lt;em&gt;processos e troca de mensagens&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Um &lt;a href="https://elixir-lang.org/getting-started/processes.html"&gt;processo&lt;/a&gt; em Elixir é uma thread de execução que roda na BEAM, máquina virtual Erlang. Processos são concorrenciais, leves (com baixo consumo de memória), e isolados uns dos outros. Invocamos processos por meio da funçao &lt;code&gt;spawn/1&lt;/code&gt;, que retorna um &lt;em&gt;PID&lt;/em&gt;, endereço do processo na máquina virtual. &lt;/p&gt;

&lt;p&gt;Podemos, por exemplo, invocar um processo que roda uma função anônima:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;spawn&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.109.0&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Processos, embora independentes, são capazes de mandar e receber mensagens uns para os outros. Mensagens enviadas a um processo são registradas em sua caixa de mensagens, que ele lê e responde de acordo com as especificações determinadas.&lt;/p&gt;

&lt;p&gt;Enviamos mensagens a qualquer processo ativo na máquina virtual por meio da função &lt;code&gt;send/2&lt;/code&gt;, que recebe como argumentos um &lt;em&gt;PID&lt;/em&gt;, endereço do destinatário, e a mensagem (geralmente um &lt;em&gt;atom&lt;/em&gt; ou &lt;em&gt;tuple&lt;/em&gt;). Os processos recebem mensagens por meio do bloco &lt;code&gt;receive&lt;/code&gt;, que especifica as mensagens que pode receber e como responder.&lt;/p&gt;

&lt;p&gt;O código a seguir ilustra como processos podem enviar e receber mensagens. No exemplo, &lt;code&gt;self()&lt;/code&gt; retorna o &lt;em&gt;PID&lt;/em&gt; do processo que está rodando atualmente, e que receberá a mensagem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;restaurante&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;restaurante&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:pedido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"pizza"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:pedido&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Cozinhando: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# Cozinhando: pizza&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante ressaltar que, tal qual em uma comunicação entre pessoas, a comunicação entre processos só pode ocorrer por meio de mensagens que são capazes de entender, interpretar e responder. No exemplo acima, o processo &lt;em&gt;restaurante&lt;/em&gt; só entende uma mensagem: &lt;code&gt;{:pedido, item}&lt;/code&gt;. Poderíamos enviar outras mensagens para o processo, como &lt;code&gt;:cancelar_pedido&lt;/code&gt; ou &lt;code&gt;{:reclamacao, "a comida não estava boa"}&lt;/code&gt;, mas ele é incapaz de responder, porque não entende, isto é, não está devidamente configurado para essas mensagens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementação de estados mutáveis
&lt;/h2&gt;

&lt;p&gt;Com essas duas ferramentas à nossa disposição, podemos enfrentar o nosso problema anterior: &lt;em&gt;implementar estados mutáveis sem recorrer a variáveis globais&lt;/em&gt;. Para resolvê-lo, vamos dividi-lo em duas etapas: como registrar dados e como atualizar dados. &lt;/p&gt;

&lt;p&gt;Processos instanciados na VM executam a ação para que foram criados, e extinguem-se. Isso não ocorre, porém, com funções recursivas, que chamam a si mesmas em sua execução. Podemos, portanto, utilizá-las para registrar dados como parâmetros. &lt;/p&gt;

&lt;p&gt;Retornemos ao nosso exemplo do tocador de música. Podemos registrar a música que está tocando em um processo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="s2"&gt;"Rainbow - Stargazer"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.109.0&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O processo &lt;code&gt;player&lt;/code&gt; vai rodar infinitamente, registrando o valor passado como argumento da função. Entretanto, ainda é incapaz de trocar de música, e não é muito útil. O exemplo ilustra como registrar um dado, mas não explica como ele pode ser mudado. &lt;/p&gt;

&lt;p&gt;Processos são isolados uns dos outros, e uma vez chamados não podem ser redefindos no meio de sua execução. O que precisamos é dum efinir processo que registre os dados como argumentos, e tenha em si próprio a capacidade chamar-se recursivamente com dados passados do exterior. A forma como passamos dados a um processo é por meio de mensagens.&lt;/p&gt;

&lt;p&gt;Implementamos nosso tocador de música utilizando o que aprendemos até aqui:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_song&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
            &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;new_song&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="ss"&gt;:listen&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
            &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Now playing: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="s2"&gt;"Rainbow - Stargazer"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:listen&lt;/span&gt;
&lt;span class="c1"&gt;# Now playing: Rainbow - Stargazer&lt;/span&gt;
&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Rainbow - Self Portrait"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:listen&lt;/span&gt;
&lt;span class="c1"&gt;# Now playing: Rainbow - Self Portrait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, nosso tocador de música não apenas registra a música que está tocando, mas também recebe comandos e responde condicionalmente, podendo trocar de música ou tocá-la. As chamadas recursivas no final de cada função (&lt;em&gt;tail recursion&lt;/em&gt;) mantêm os processos ativos.&lt;/p&gt;

&lt;p&gt;Vimos até aqui, então, exatamente o que procurávamos no problema inicial: uma maneira de implementar estados mutáveis em um sistema de programação funcional sem variáveis globais. Pode ser interessante, para continuar essa discussão, comparar a solução implementada em Elixir com a de outras linguagens funcionais&lt;/p&gt;

&lt;p&gt;Agora que temos o conhecimento e as ferramentas necessárias para implementar uma máquina de estados mutáveis, somos capazes de desenvolver sistemas mais complexos e úteis. Pense nos exemplos de máquinas que você conhece: um semáforo de trânsito, um termostato, um videogame; todos esses sistemas, do mais simples ao mais complexo, gravam estados atuais e o atualizam de acordo com eventos e operações pré-programados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura cliente-servidor
&lt;/h2&gt;

&lt;p&gt;Vamos voltar ao nosso exemplo do tocador de música. Imaginemos um sistema que permite a vários usuários consultarem a temperatura atual em diferentes lugares do mundo: o usuário descreve em uma interface o lugar desejado, e o sistema aciona uma estação meteorológica remota, que mede a temperatura e devolve ao usuário como resposta. Esse modelo, que separa a interface de usuário do núcleo de processamento, é chamado arquitetura cliente-servidor.&lt;/p&gt;

&lt;p&gt;Entendida desta maneira, a arquitetura cliente-servidor não está restrita ao domínio das redes de Internet; é um modelo conceitual, uma abstração da máquina de estados, para implementar o sistema de forma clara e organizada. Para ilustrar, continuaremos o desenvolvimento do mesmo sistema, nosso tocador de música. &lt;/p&gt;

&lt;p&gt;A forma ideal de implementar um sistema com modelo cliente-servidor em Elixir é usando o GenServer. É um sistema construído sobre os fundamentos que apresentamos anteriormente -- processos e troca de mensagens -- que encapsula e proporciona um padrão (&lt;em&gt;behaviour&lt;/em&gt;) para a implementação, em que separamos as funções de interface e de processamento dos dados (&lt;em&gt;callbacks&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Podemos reescrever nosso tocador de música utilizando o GenServer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Blackmore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;GenserverPlayer&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;GenServer&lt;/span&gt;

  &lt;span class="c1"&gt;## Client API&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;select_song&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:select_song&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:listen&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;## Server callbacks&lt;/span&gt;
  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:listen&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;song:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apesar de utilizar mais linhas para cumprir um propósito semelhante, percebemos agora uma clara organização, separando as operações realizadas pelo cliente e pelo servidor. Nossos comandos -- as mensagens passadas para o processo -- não estão soltas, mas encapsuladas em funções com finalidades distintas e claras.&lt;/p&gt;

&lt;p&gt;Entre os recursos proporcionados pelo GenServer, vale a pena observar a possibilidade de designar callbacks síncronos, isto é, que aguardam o retorno de uma resposta, e assíncronos, que devolvem apenas a promessa de execução do comando requisitado. O GenServer também proporciona um gerenciamento de erros e uma integração eficaz com outros componentes de um sistema Elixir, como Supervisors e Application. Este é um tópico que merece um artigo dedicado inteiramente a ele, então ficará para uma próxima oportunidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O controle de estados mutáveis é a base da computação, tanto em um sentido teorético como físico. Para computar, é necessário registrar valores e atualizá-los segundo determinadas operações. Tal fato nos impõe um problema quando pensamos em implementar uma sistema computacional segundo o paradigma funcional, isto é, baseado em funções puras e sem variáveis de escopo global. &lt;/p&gt;

&lt;p&gt;Vimos, porém, que lançando mão de funcões recursivas e troca de mensagens entre processos, é possível implementar uma máquina de estados mutáveis, gravando dados nos argumentos das funções, e atualizando-os por meio de mensagens aos processos.&lt;/p&gt;

&lt;p&gt;Tais fundamentos nos permitem o desenvolvimento de um sistema no modelo cliente-servidor, em que o usuário é capaz de realizar requisições a um processo por meio de uma interface clara e isolada das funções de processamento.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>functional</category>
      <category>programming</category>
    </item>
    <item>
      <title>React Mastermind</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Tue, 05 Jan 2021 16:47:14 +0000</pubDate>
      <link>https://dev.to/escribapetrus/react-mastermind-1c4k</link>
      <guid>https://dev.to/escribapetrus/react-mastermind-1c4k</guid>
      <description>&lt;p&gt;O jogo começa com um segredo de quatro cores. Ao todo existem seis cores diferentes que podem ser combinadas de qualquer forma: azul, amarelo, rosa, verde; azul, azul, amarelo, amarelo; azul, azul, azul e azul. Não há limite para cores repetidas.&lt;/p&gt;

&lt;p&gt;Para descobrir o segredo, o jogador faz testes, escolhendo cores que o computador compara com o segredo. Se as combinações forem iguais, o jogador ganha; se forem diferentes, joga outro turno. Em 10 turnos, o jogador perde. &lt;/p&gt;

&lt;p&gt;Mas é preciso algo a mais para descobrir o segredo em menos que 1296 tentativas aleatórias. Cada teste retorna pontos: a cada ponto preto, há uma cor certa no lugar certo; a cada ponto branco, há uma cor certa no lugar errado.&lt;/p&gt;

&lt;p&gt;Agora, vamos criar esse jogo. Para entender como funciona, &lt;a href="https://escribapetrus.github.io/mastermind-react/"&gt;experimente aqui a versão pronta&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  As ferramentas utilizadas
&lt;/h2&gt;

&lt;p&gt;Para criar esse jogo, vamos utilizar duas ferramentas principais. Com o &lt;strong&gt;React&lt;/strong&gt;, vamos criar a interface, gerenciar os estados da aplicação por meio da Context API e operar os inputs do jogador.&lt;/p&gt;

&lt;p&gt;Com o &lt;strong&gt;Lodash&lt;/strong&gt; — conjunto de funções que expande[1] as possibilidades de manipulação de estruturas de dados em Javascript, vamos manipular os arrays e objetos para montar testes, comparar testes ao segredo e calcular pontos. Escolhi o Lodash porque a inspiração para recriar esse jogo veio do Mastermind in Haskell[2], uma implementação feita com funções puras que roda no terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerando o segredo
&lt;/h2&gt;

&lt;p&gt;Vamos começar pelo mais fácil. O segredo não é nada mais do que uma combinação aleatória de 4 das 6 cores disponíveis. As funções shuffle e take do Lodash nos permitem resolver isso em uma quatro linhas.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Sample colhe elementos aleatórios de arr, que são então mapeados em um novo array, e a partir dele take gera um novo array com os primeiros n elementos. É importante ressaltar que as funções são puras e não alteram a fonte arr. Um beijo para o time lambda 🧙.[3]&lt;/p&gt;

&lt;p&gt;Assim, para começar um novo jogo, basta gerar um novo segredo com algo como let secret = genSecret(cores, 4).&lt;br&gt;
Gerando os testes&lt;br&gt;
Gerar o segredo é a parte mais fácil. Agora vamos ver como gerar o teste com as cores escolhidas pelo jogador. Para isso, vamos usar o hook &lt;strong&gt;useReducer&lt;/strong&gt; do React para adicionar, remover e resetar cores no teste, que aqui será chamado de state.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;No componente, iniciamos o teste (state) como um array vazio. A cada evento que dispara uma ação do dispatch, um novo objeto teste é emitido de acordo com o tipo da ação (“add”, “remove”, “reset”): adicionando a cor escolhida (action.payload) ao teste, removendo-a ou resetando tudo.&lt;/p&gt;

&lt;p&gt;Mais uma vez, as ações não alteram o objeto do teste, mas sim criam um novo objeto que o substitui, a cada ação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerando a pontuação
&lt;/h2&gt;

&lt;p&gt;Essa é a parte mais interessante. Se você leu até aqui, aí vai um desafio: dados um conjunto teste e um conjunto segredo, ambos de quatro elementos, como descobrir quantos são os elementos iguais na posição correta e os elementos iguais na posição errada?&lt;br&gt;
Descobrir as cores certas na posição certa (pontos pretos) é fácil, é claro. Comparamos os arrays lado a lado: se na posição 0 as cores forem iguais, 1; se forem diferentes, 0; e somamos os pontos. Mas e os pontos brancos, isto é, as cores certas na posição errada?&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Mais uma vez, o Lodash nos dá uma série de ferramentas para juntar, filtrar e comparar os arrays. solução para o desafio: os pontos brancos são o numero de cores do segredo, menos as cores que o teste não acertou, menos os pontos pretos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Condições de vitória e derrota
&lt;/h2&gt;

&lt;p&gt;Falamos sobre como começar o jogo — gerar o segredo — e como fazer cada turno — criar um teste, calcular os pontos. Agora, preciso falar sobre o funcionamento geral do jogo, isto é, como registrar os testes realizados e quais são as condições de vitória e derrota.&lt;/p&gt;

&lt;p&gt;Para o jogo funcionar, eu preciso de acesso a uma informação em todos os componentes (tabuleiro, header, mão do jogador, app). Essa informação é a lista de todos os testes já realizados.&lt;br&gt;
No React, essa necessidade nos leva diretamente à ideia de uma ferramenta de gerenciamento de estado global da aplicação, como o Redux. Para criar este jogo, optei pela ferramenta nativa do React, a &lt;strong&gt;Context API&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;A lista de testes (“guesses”) agora pode estar disponível por meio do uso do custom hook useGuesses. A variável guesses lista todos os testes já realizados, e a função setGuesses é usada para incluir novos testes à lista.[4]&lt;br&gt;
Para terminar, precisamos falar sobre como ganhar o jogo, e também como perder. O jogador ganha quando o teste é igual ao segredo, e perde quando já lançou 10 testes errados. Agora que temos a lista completa e constantemente atualizada dos testes, fica fácil implementar essas condições. Para isso, utilizaremos o hook useEffect, um método que roda a cada atualização do componente.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Se o último teste tiver 4 pontos pretos, o jogador ganhou. Se o número de testes for maior que 9, o jogador perdeu.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Desde que eu comecei a programar, meu mentor sempre me disse que criar jogos é uma das maneiras mais eficazes de estudar, treinar, aprender. Isso porque é ao mesmo tempo divertido e complexo.&lt;br&gt;
Neste exercício, recriei o jogo de Mastermind que pode ser jogado pelo browser, no computador ou no celular. Ainda teria muita coisa para falar, como a organização dos componentes do React ou a estilização responsiva com Material UI. Mas acho que nesse artigo consegui explicar o que eu queria: como o jogo funciona logicamente, e como usar funções puras para manipular estruturas de dados para obter os resultados desejados.&lt;br&gt;
Se você gostou, pode &lt;a href="https://github.com/escribapetrus/mastermind-react"&gt;conferir o código no meu github&lt;/a&gt;, &lt;a href="https://escribapetrus.github.io/mastermind-react/"&gt;jogar o jogo pelo browser&lt;/a&gt; ou deixar o like no artigo. Obrigado e um abraço!&lt;/p&gt;

&lt;p&gt;1.Talvez a expressão correta seja “facilita”; afinal, não há razão para as operações feitas com o Lodash não poderem ser feitas com o Javascript puro. Mas “expandir” é mais bonito, vamos concordar.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Mastermind in Haskell, por Christophe Delord. &lt;a href="http://christophe.delord.free.fr/haskell/mastermind.html"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na primeira versão, eu utilizei a função shuffle do Lodash, que gera um array de elementos embaralhados. Como um colega apontou, dessa maneira o jogo não conseguia gerar segredos com elementos repetidos, e alterei para usar a função sample.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Para criar esse Context, foi indispensável o tutorial do Guilherme Rodz. Obrigado, meu caro! &lt;a href="https://www.youtube.com/watch?v=FsCBw9X9U84&amp;amp;t=707s"&gt;Acesse aqui&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>O robô entusiasta de poesia</title>
      <dc:creator>P. Schreiber 🧙🏻‍♂️🔮🐐</dc:creator>
      <pubDate>Tue, 05 Jan 2021 16:23:13 +0000</pubDate>
      <link>https://dev.to/escribapetrus/o-robo-entusiasta-de-poesia-12lo</link>
      <guid>https://dev.to/escribapetrus/o-robo-entusiasta-de-poesia-12lo</guid>
      <description>&lt;p&gt;Um fantasma de mil anos habita o Twitter: &lt;a href="https://twitter.com/kokinshu_bot"&gt;o fantasma do poeta japonês Ki no Tsurayuki&lt;/a&gt; (紀貫之, ca.872 — ca. 945). Na verdade, não é fantasma nenhum; trata-se de um bot que a cada duas horas posta poemas aleatórios extraídos da coleção Kokin Wakashū.&lt;/p&gt;

&lt;p&gt;A ideia é tão legal que eu resolvi programar meu próprio robô entusiasta de poesia, só que em vez de poemas japoneses, meu Charles Robaudelaire seria um robô de poesia francesa, extraída do acervo &lt;a href="https://www.poetica.fr/"&gt;poetica.fr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A versatilidade — diversidade de tarefas às quais a ferramenta pode servir — é um dos maiores atrativos da linguagem &lt;strong&gt;Python&lt;/strong&gt;. A riqueza de bibliotecas open source é igualmente grande no Javascript, é verdade. Mas esta linguagem sempre me pareceu ligada muito fortemente à manipulação do DOM do navegador. Ser general-purpose desde o princípio, e não por expansão, me fez confiar muito mais em Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Construindo o scraper
&lt;/h2&gt;

&lt;p&gt;O Robaudelaire precisava ter sua biblioteca, isto é, um banco de dados de poemas que serviriam de conteúdo para cada tweet. Para criá-la, havia duas opções: buscar uma API que providenciasse os dados dos poemas em formato JSON, ou extrair essa informação de sites que a contém, mas não providenciam uma API, por meio de um scraper.&lt;/p&gt;

&lt;p&gt;Scrapers e crawlers não são exatamente a mesma coisa, mas são parecidos — como um prego e um parafuso. Deixo aqui uma definição rasa, só para esclarecer e seguir com a história: &lt;/p&gt;

&lt;p&gt;Scrapers são scripts que visitam uma página da web e traduzem (parse) o código de forma a deixá-lo interpretável e navegável pela linguagem de programação. Desta forma, é possível buscar, listar, filtrar e manipular os elementos do html como quaisquer objetos. Crawlers são scripts que navegam as várias páginas de um site repetidamente, como um aventureiro que explora as áreas novas de um mapa. Como as duas atividades são fundamentais para o nosso programa, chamarei simplesmente de scraper.&lt;/p&gt;

&lt;p&gt;O scraper foi desenvolvido utilizando a biblioteca &lt;strong&gt;Beautiful Soup 4&lt;/strong&gt;, que faz exatamente o que está escrito na definição acima, portanto não é necessário repetir. Consiste em três funções: get_poem_list() acessa a página de um autor e retorna a lista de todos os seus poemas; get_poem_detail() acessa um poema individual e retorna o texto completo e o nome do autor devidamente formatado para o tweet (get_poem_detail() não será usada para construir a biblioteca); scrape_site() acessa o acervo e, utilizando get_poem_list() em cada um dos autores, retorna a lista total de poemas, com nome do autor, título e link.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;A função get_poem_list() opera como um procedimento interno da função principal scrape_site(), que além fazer o scrape da página inicial para montar a lista “library” de autores e urls, funciona como um crawler que navega a página de cada autor, por meio da função map(…).&lt;br&gt;
Rodando o scraper, preenchemos a biblioteca com 3.000 poemas de 150 autores. Restava apenas salvá-la no banco de dados como o arquivo .csv a ser consultado para criar os tweets. Em caso de dúvida sobre como salvar o objeto em .csv, segue o snippet.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Construindo o objeto Poem
&lt;/h2&gt;

&lt;p&gt;Tendo a biblioteca em mãos, era hora de fazer os tweets — primeiro em texto, antes de postar no Twitter. Após algumas tentativas, decidi que a melhor abordagem seria criar instâncias/objetos de uma classe Poem, que teria em si não apenas os atributos obtidos da biblioteca, mas também dois métodos importantes: get_poem() e get_tweet().&lt;/p&gt;

&lt;p&gt;Você deve ter percebido que a biblioteca que salvamos no banco de dados não contém os texto dos poemas. É claro que o Robaudelaire precisa desses textos para citar nos tweets. Para isso, cada instância do objeto Poem possui o método get_poem(), que chama a função get_poem_details() dos scrapers e retorna o poema completo.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Postando no twitter por meio da API
&lt;/h2&gt;

&lt;p&gt;O Robaudelaire já tinha uma biblioteca cheia e o método para criar seus tweets. O último passo era postá-los no Twitter.&lt;br&gt;
Para isso, era necessário criar uma conta na &lt;a href="https://developer.twitter.com/en"&gt;plataforma para developers do Twitter&lt;/a&gt;, vinculá-la à conta, registrar o app (i.e., o robô) e adquirir as quatro chaves para autenticação, api key, api secret key, access token, access token secret. (Esta parte é um desafio que vou deixar você enfrentar sozinho, porque a explicação seria longa, fácil e desinteressante).&lt;br&gt;
Com as quatro chaves, é possível autenticar na API e postar o tweet com o método api.update_status(). Utilizei a biblioteca &lt;strong&gt;pandas&lt;/strong&gt; para ler o arquivo .csv e extrair um poema aleatório com o método data.sample().&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Com o arquivo main.py rodando, o loop infinito while True: posta um tweet a cada intervalo configurado no método time.sleep(). Na hora de configurar o intervalo de tweets, lembre-se que a API impõe um limite de acessos para evitar spam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Robaudelaire foi um programa fácil de se criar, mas um bom exercício para aprender a desenvolver scrapers e crawlers, ler e escrever arquivos, desenhar classes, interagir com APIs.&lt;br&gt;
Por enquanto, ele só posta citações com links para o site que generosamente disponibiliza o acervo de poemas (espero que não se incomodem por eu pegá-lo emprestado). Mas há outras funcionalidades que podem ser desenvolvidas no futuro; por exemplo: retweetar conteúdos relevantes, responder automaticamente a mensagens e citações, entre outras.&lt;/p&gt;

&lt;p&gt;Mas essa é outra história. Agradeço ao site poetica.fr por fornecer gratuitamente na internet um acervo de poesia tão impressionante. Se você gostou deste projeto e quer tirar dúvidas ou conversar, me mande um alô pelo &lt;a href="https://www.instagram.com/escribapetrus/"&gt;Instagram&lt;/a&gt; ou me adicione no &lt;a href="https://github.com/escribapetrus"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
