<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Silly Bytes</title>
    <link href="http://www.sillybytes.net/atom.xml" rel="self" />
    <link href="http://www.sillybytes.net" />
    <id>http://www.sillybytes.net/atom.xml</id>
    <author>
        <name>Daniel Campoverde [alx741]</name>
        
        <email>alx@sillybytes.net</email>
        
    </author>
    <updated>2017-05-04T00:00:00Z</updated>
    <entry>
    <title>Deploying Yesod applications with Keter</title>
    <link href="http://www.sillybytes.net/posts/keter_tutorial.html" />
    <id>http://www.sillybytes.net/posts/keter_tutorial.html</id>
    <published>2017-05-04</published>
    <updated>2017-05-04T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><a href="https://github.com/snoyberg/keter">Keter</a> is the
<a href="http://www.yesodweb.com/">Yesod</a>’s deployment system, fully featured and a joy
to use, but there are some pitfalls that the documentation doesn’t cover, and
that the user has to find out for her self; So I’ll try to give them away here
together with a walk-through tutorial.</p>
<p>Although Keter is flexible and general enough to be used with various kind of
applications and web frameworks, here I’m going to assume you’re using it to
deploy Yesod applications. Moreover, I’ll assume you’re using Yesod’s
scaffolding, as it is the preferred way to write production ready applications.</p>
<!--more-->
<p>I’m also taking for granted that you’ve already installed on your server system
whatever DBMS that your Yesod app needs, and have also created the app’s
databases.</p>
<h1 id="installing-keter-on-the-server">Installing Keter on the server</h1>
<h2 id="keter-binary">Keter binary</h2>
<p>It is always advisable to compile on the development machine rather than the
production server, to avoid utilising its resources for building (specially
considering that GHC can make use of a fair amount of them). So, assuming the
architectures match, you can just install <code>keter</code> on you local machine:</p>
<pre><code>$ stack install keter</code></pre>
<p>And then put the binary on the server (<em>example.com</em>):</p>
<pre><code>$ scp ~/.local/bin/keter root@example.com:/root/</code></pre>
<h2 id="keter-user">Keter user</h2>
<p>It’s a good practice to have a dedicated <em>keter</em> user, so you don’t have to
deploy as root each time:</p>
<pre><code># useradd keter
# passwd keter</code></pre>
<h2 id="directory-tree">Directory tree</h2>
<p>The directory tree needed on the server is as follows:</p>
<pre><code>keter
├── bin
│   └── keter
├── etc
│   └── keter-config.yaml
├── incoming
    └── app.keter</code></pre>
<p>So create it, copy the binary to <code>/opt/keter/bin</code>, and make sure
<code>/opt/keter/incoming</code> it’s owned by the <em>keter</em> user (we’ll take care of the
<code>keter-config.yaml</code> configuration later):</p>
<pre><code># mkdir -p /opt/keter /opt/keter/bin /opt/keter/etc /opt/keter/incoming
# cp /root/keter /opt/keter/bin
# touch /opt/keter/keter-config.yaml
# chown -R keter:keter /opt/keter/icoming</code></pre>
<h2 id="init-system">Init System</h2>
<p>While you could just execute <code>/opt/keter/bin/keter</code> directly, it’s better to
register it as a job in your Init System.</p>
<h4 id="sysmted-redhat-fedora-centos-arch-opensuse-etc">Sysmted (RedHat, Fedora, CentOS, Arch, openSUSE, etc)</h4>
<p>Create a file <code>/etc/systemd/system/keter.service</code>, with the contents:</p>
<pre><code>[Unit]
Description=Keter
After=network.service

[Service]
Type=simple
ExecStart=/opt/keter/bin/keter /opt/keter/etc/keter-config.yaml

[Install]
WantedBy=multi-user.target</code></pre>
<p>Enable the service:</p>
<pre><code>$ sudo systemctl enable keter</code></pre>
<p>Now you can start <em>keter</em> with (don’t do it just yet, as we still need to write
the <em>keter</em> configuration file):</p>
<pre><code>$ sudo systemctl start keter</code></pre>
<h4 id="upstart-debian-ubuntu-etc">Upstart (Debian, Ubuntu, etc)</h4>
<p>Create a file <code>/etc/init/keter.con</code>, with the contents:</p>
<pre><code>start on (net-device-up and local-filesystems and runlevel [2345])
stop on runlevel [016]
respawn
console output
exec /opt/keter/bin/keter /opt/keter/etc/keter-config.yaml</code></pre>
<p>Now you can start <em>keter</em> with (don’t do it just yet, as we still need to write
the <em>keter</em> configuration file):</p>
<pre><code>$ sudo start keter</code></pre>
<h1 id="configuration">Configuration</h1>
<h2 id="server-side">Server Side</h2>
<p>The <em>Keter</em> configuration at <code>/opt/keter/etc/keter-config.yaml</code> is pretty
straight forward:</p>
<pre><code>root: ..

listeners:
    # HTTP
    - host: &quot;*4&quot; # Listen on all IPv4 hosts
      port: 80
    # HTTPS
    #- host: &quot;*4&quot;
      #port: 443
      #key: key.pem
      #certificate: certificate.pem

# env:
#    key: value</code></pre>
<p>The <code>root</code> option points, as expected, to <code>/opt/keter</code>.</p>
<p>Make sure to change the <code>port</code> option if you’re reverse forwarding from a
fronted server like <em>Nginx</em> or <em>Apache</em> (more on this later).</p>
<p>If you’re serving your application over SSL (and you should), uncomment the
<em>HTTPS</em> section, then point the <code>key</code> option to your <code>privkey.pem</code> file, and the
<code>certificate</code> option to your <code>fullchain.pem</code> file.</p>
<p>The <code>env</code> option, keeps pairs of <em>keys</em> and <em>values</em>. The main set of values
you’ll need here are your Database credentials. You’ve probably already
configured database credentials in the <code>database</code> section in the
<code>config/settings.yaml</code> file, so you’ll notice you need some environment
variables like <code>MYSQL_USER</code>, <code>MYSQL_PASSWORD</code>, etc. If you’re using
MySQL/MariaDB; Or <code>PGUSER</code>, <code>PGPASS</code>, etc. If you’re using PostgreSQL. You
get the idea.</p>
<p>This is how it will look like for a PostgreSQL Database where only the user and
password are different between the development and production servers (be sure
to keep the quotes).</p>
<pre><code>env:
    PGUSER: &quot;user&quot;
    PGPASS: &quot;password&quot;</code></pre>
<h2 id="yesod-application-side">Yesod application side</h2>
<p>The Keter configuration file for your Yesod application lives in
<code>config/keter.yml</code>. Set <code>user-edited</code> to <code>true</code>, so you’re able to execute
<code>yesod keter</code> later on.</p>
<p>Locate the <code>copy-to</code> option and configure it to use the <code>keter</code> user and your
server domain (or IP address):</p>
<pre><code>copy-to: keter@example.com:/opt/keter/incoming/</code></pre>
<p>This will allow you to deploy your application with:</p>
<pre><code>$ stack -- exec yesod keter</code></pre>
<h4 id="hosts-configuration">Hosts Configuration</h4>
<p>The most important part of the Keter configuration is perhaps the <code>hosts</code>
option of the <code>webapp</code> stanza, the hosts you declare here are the ones that your
application is going to respond to. Unless you’re using a separate domain for
serving static files, be sure to keep the <code>hosts</code> option of the <code>static-files</code>
stanza in sync with the <code>webapp</code> one.</p>
<p>This one here is a pretty common error message when trying to deploy a Yesod
application (and failing miserably):</p>
<p><img src="/img/keter/shot1.png" class="img-responsive" /></p>
<p>There is more than one reason for this, but the main one is that the domain name
or IP address doesn’t exactly match one of the hosts provided in the <code>hosts</code>
option.</p>
<p>If you’re serving only one application and using <em>Keter</em> as the main server
listening on port <code>80</code>, then having your domain name in <code>hosts</code> will pretty much
suffice, BUT most of the time, even if your serving only one application, you’re
probably using a frontend server like <em>Nginx</em> or <em>Apache</em>, in which case you
have to consider the port the reverse proxy is pointing to.</p>
<p>Take for instance this <em>Nginx</em> reverse proxy configuration for an app that lives
on <code>blog.example.com</code></p>
<pre><code>server {
    listen 80;
    server_name blog.example.com;
    location / {
            proxy_pass http://127.0.0.1:4321;
    }</code></pre>
<p>With a <em>Keter</em> configuration that has:</p>
<pre><code>listeners:
    - host: &quot;*4&quot; # Listen on all IPv4 hosts
      port: 4321</code></pre>
<p>Then you have a problem. If you try to connect to <code>http://blog.example.com</code>
you’ll get the aforementioned error message, telling you that “127.0.0.1:4321,
is not recognized”. It makes sense if you think about it, <em>Nginx</em> will redirect
the connection to <code>127.0.0.1:4321</code> so <em>Keter</em> can handle it, but there is no
application that responds to <code>127.0.0.1:4321</code>, and notice the port number here,
as it is significant for <em>Keter</em> when trying to find a corresponding
application.</p>
<p>To fix this, we must allow our application to respond to <code>127.0.0.1:4321</code> as
well:</p>
<pre><code>hosts:
    - blog.example.com
    - blog.example.com:4321
    - 127.0.0.1:4321</code></pre>
<p>Restart <em>Ngnix</em> and <em>Keter</em> on the server to allow the configuration to take
effect and redeploy the application:</p>
<pre><code>$ stack -- exec yesod keter</code></pre>
<h4 id="redirections">Redirections</h4>
<p>If you’re going to use the <code>redirect</code> stanza to automatically redirect any
connection to, lets say <code>example.com</code> to <code>wwww.example.com</code>:</p>
<pre><code>- type: redirect
  hosts:
      - example.com
  actions:
      - host: www.example.com</code></pre>
<p>Then be completely sure to have <code>www.example.com</code> in the <code>hosts</code> option of the
<code>webapp</code> stanza as well, failing to do this will take you to the same error
message.</p>
<h1 id="other-sources-of-error">Other sources of error</h1>
<h2 id="welcome-to-keter">“Welcome to Keter”</h2>
<p>If you’re still reaching this error:</p>
<p><img src="/img/keter/shot1.png" class="img-responsive" /></p>
<p>Unfortunately, the same error message appears if an application that responds to
that host is actually found, but is failing to start.</p>
<p>Check the <code>/opt/keter/log/app-yourapp/current.log</code> log file, chances are you
have changes in your persistent models that can’t be reflected in your database
without user intervention, so be sure to manually fix them the same way you have
to do in your development database.</p>
<h2 id="changes-in-new-deployed-version-not-taking-effect">Changes in new deployed version not taking effect</h2>
<p>It is pretty common to forget changes in persistent models that need manual user
intervention after deploying, similarly to the error above, this will prevent
the app to start. If you currently have a version of your app working, <em>Keter</em>
will use it instead of the new one if it fails to start, so if the latest
deployed changes seem to not be taking effect, this can also be the source of
the problem.</p>]]></summary>
</entry>
<entry>
    <title>What's wrong with Java?</title>
    <link href="http://www.sillybytes.net/posts/whats_wrong_with_java.html" />
    <id>http://www.sillybytes.net/posts/whats_wrong_with_java.html</id>
    <published>2017-04-14</published>
    <updated>2017-04-14T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>There’s already a rant about Java in <a href="https://sillybytes.net/2016/03/why-do-i-hate-java.html">a previous
post</a>, in which I
basically list the annoyances that the ecosystem around Java imposes and how
those relate and intersect with the problems of IDEs.</p>
<p>Here I’d like to talk about the issues of Java as a language. Although these are
a significant part of what’s wrong with Java, keep in mind that it’s only half
of the equation, the other part being its
<a href="https://sillybytes.net/2016/03/why-do-i-hate-java.html">surroundings</a>.</p>
<!--more-->
<h1 id="pointers-pointers-everywhere">Pointers, Pointers everywhere</h1>
<p>Java is supposed to be a <em>pointers-free language</em>, unlike those <em>pesky</em> C and
C++. Pointers, although very powerful, are a low level construct that should not
be present in a higher level language. Most of the time We want to be as far
away as possible from pointers when programming unless lower level memory access
is specifically needed.</p>
<p>The problem is Java <em>does</em> have pointers; Moreover, it manages to keep most of
the inconveniences of having pointers while giving none of the benefits of not
having them. If you’re not giving me the power of pointers, at least be kind
enough to remove the problems they induce.</p>
<h2 id="everything-is-a-reference-everything-is-a-pointer">Everything is a reference, everything is a pointer</h2>
<p>Java loves to call pointers by the nickname of “references”, which is only a way
to pretend that there are no pointers.</p>
<p>Java makes everything a pointer, thus the heavy usage of the <code>new</code> keyword as a
way to create a <em>reference</em>. Having this references gives the <em>JVM</em> the ability
to manage memory with the Garbage Collector of course, but it comes with
negative consequences for the programmer.</p>
<h2 id="nullpointerexception">NullPointerException</h2>
<p>The book <em>Elegant Objects</em> by Yegor Bugayenko says:</p>
<blockquote>
<p>In a nutshell, you’re making a big mistake if you use NULL anywhere in your
code. Anywhere – I mean it.</p>
</blockquote>
<p>And I completely agree with that. The problem here is having to take into
account the possibility of <em>NULL</em> in a high level language that supposedly
doesn’t have pointers and tries to hide those details from you in the first
place.</p>
<p>In C or C++, when you dereference a <em>NULL</em> pointer, you get a <em>Segmentation
Fault</em> and your program crashes. In Java, when you try to use a <em>NULL</em> reference
you get a
<a href="https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html">NullPointerException</a>
and your program crashes as well. So what gives?</p>
<p>You may say that the sources of these crashes are different, the <em>Segmentation
Fault</em> comes from the OS trying to stop you from crashing the entire system,
while the <em>NullPointerException</em> comes from the JVM that… Well, has nothing
left to do but crash. I don’t see how is that any better.</p>
<p><em>NullPointerException</em>s are terribly common in Java, and you have to hunt them
down just as any null pointer dereference bug. And if you’re thinking the actual
benefit of this is having the <em>GC</em> taking care of the memory instead of having
to remember to manually free memory, then think again, as there are languages
that take care of that without a <em>GC</em>, including C++.</p>
<p>Tony Hoare himself calls <em>NULL</em> the <a href="https://en.wikipedia.org/wiki/Nullable_type#Compared_with_null_pointers">“Billion-Dollar
mistake”</a>.</p>
<h2 id="useless-pointers">Useless pointers</h2>
<p>So java is cluttered with pointers, useless pointers. In <em>C/C++</em> pointers are
one of the most powerful constructs, they allow you to get closer to the machine
and control its actions with scalpel precision; In Java you get your programs to
crash due to <em>NULL</em> pointers while getting no benefit in exchange.</p>
<p>Pointers in Java percolate up in even more creative ways, take for instance
the Equality comparison problem: When you perform equality comparison <code>==</code> what
you’re actually comparing is <em>pointer equality</em>, not <em>value equality</em> for which
you need a special method <code>equal()</code>, this is a low level language trait that,
unlike other low level languages, won’t put the power on the programmers hand
but just the burden.</p>
<h1 id="the-bad-the-worst-and-the-ugly">The bad, the worst and the ugly</h1>
<p>Java has a lot of additional traits that make it not only a low level language
in disguise, but also in my opinion a bad language in general.</p>
<p><img src="/img/javawrong/good_bad_ugly.jpg" class="img-responsive" /></p>
<h2 id="awful-verbosity">Awful Verbosity</h2>
<p>Most of the Java ugly verbosity is attributed to its static, strong typing
discipline that forces you to annotate the types of everything, everywhere. But
this is not the type discipline fault.</p>
<p>In Java, you declare, for instance, a vector of integers:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Integer</span><span class="op">&gt;</span> vector <span class="op">=</span> <span class="kw">new</span> <span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Integer</span><span class="op">&gt;();</span></span></code></pre></div>
<p>Or a vector of vectors of integers:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Integer</span><span class="op">&gt;&gt;</span> vector <span class="op">=</span> <span class="kw">new</span> <span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Integer</span><span class="op">&gt;&gt;();</span></span></code></pre></div>
<p>And it gets progressively uglier like that. Java’s way of dealing with this to
some extent, is the empty <em>diamond</em> operator <code>&lt;&gt;</code>, so instead we could write:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Vector</span><span class="op">&lt;</span><span class="bu">Integer</span><span class="op">&gt;&gt;</span> vector <span class="op">=</span> <span class="kw">new</span> <span class="bu">Vector</span><span class="op">&lt;&gt;();</span></span></code></pre></div>
<p>But that’s pretty much as far as it gets. <em>C++11</em> on the other hand has the
<code>auto</code> keyword to let the compiler do what compilers do best: mechanical,
repetitive, deterministic tasks; Type inference is one of those tasks.</p>
<p>Every time, everywhere a time annotation is needed, you provide one only if it’s
necessary to avoid ambiguity, otherwise, just use <code>auto</code> and let the compiler do
it for you.</p>
<h2 id="resource-un-safety">Resource un-safety</h2>
<p>One of the main Java selling points is <em>Memory Safety</em>, you see, in C you have
to free your memory with <code>free()</code> in the right place, at the right time after
every memory allocation with <code>malloc()</code> and friends. If you forget to free your
memory you’ll have memory leaks, if you free it twice, or if you free it at the
wrong time you’ll have a segmentation fault.</p>
<p>Java on the other hand leverages the Garbage Collector to do it for you, the
problem is, this works for memory only!</p>
<p>Whenever you initialize a socket, or a database connection, or open a file, you
still need to <em>close</em> it at the right time; So you still can and will have
resources leakage.</p>
<p>C++ solves all of those problems beautifully by using <a href="http://en.cppreference.com/w/cpp/language/raii">Resource Acquisition Is
Initialization</a> or RAII for
short. And by the way, if you hit the same kind of problems you face in C with
<code>malloc()</code> and <code>free()</code> but with <em>C++</em>’s <code>new</code> and <code>delete</code>, then you’re doing
it wrong.</p>
<p>By using C++’s RAII mechanisms you’ll never have to remember to free memory,
close files, sockets, database connections or anything else. Java is supposed to
be a higher level language than C++.</p>
<h2 id="exceptions-driven-programming">Exceptions Driven Programming</h2>
<p>C++ and many other imperative and OOP languages suffer form the <em>Exceptions
driven programming</em> issue as well, but Java manages to screw it up even further.</p>
<p>The heavy use of exceptions forces the programmer to write tons of:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">...</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="cf">catch</span><span class="op">(</span>someExcetption e<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">...</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="cf">catch</span><span class="op">(</span>someOtherExcetption e<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">...</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="cf">catch</span><span class="op">(</span>yetAnotherExcetption e<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">...</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The usual alternative is just:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">...</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="cf">catch</span><span class="op">(</span>Excetption e<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="bu">System</span><span class="op">.</span><span class="fu">out</span><span class="op">.</span><span class="fu">println</span><span class="op">(</span><span class="st">&quot;An exception has occurred, sorry ¯</span><span class="er">\_</span><span class="st">(ツ)_/¯&quot;</span><span class="op">);</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The result of this is that the code that matters, the actual logic we’re trying
to encode in the program gets deeply buried, making it hard to read, hard to
understand, hard to maintain, hard to modify and awfully ugly. Although most
languages suffer from a variant of this issue, some other languages handle it
gracefully by encoding the possibility of failure in the type system.</p>
<p>Most programming languages break equational reasoning, but that’s pretty common;
Exceptions go further by even breaking the imperative sequentiality (<em>cough</em>
GOTO <em>cough</em>).</p>
<h1 id="everything-is-an-object">Everything is an object</h1>
<p>As mentioned in a <a href="https://sillybytes.net/2016/03/why-do-i-hate-java.html">previous
post</a>: No, not
everything is an object. OOP has a lot of problems on its own, and it deserves
its own post, but here I’m talking about the way Java enforces OOP.</p>
<p>Most OOP languages have this paradigm as a <em>feature</em>, but still allow for free
functions, free data and so on. The problem with Java being strictly OOP is that
it forces objects even when they don’t fit, even when they adversely affect
composition, modularity or readability.</p>
<blockquote>
<p>The problem with object-oriented languages is they’ve got all this implicit
environment that they carry around with them. You wanted a banana but what you
got was a gorilla holding the banana and the entire jungle. – Joe Armstrong</p>
</blockquote>
<p>In most languages you can perform <em>actions</em>, but in Java, having objects as the
only mean of abstraction you must have <em>“actioners”</em> to perform <em>actions</em>, and
must force them into existence to do anything even if it convolutes your code
and logic. OOP is usually bad in general, although useful in certain contexts;
Java makes it so that everything that is wrong with OOP is also the only way.</p>
<p>Those and more are the common pains of <em>Javaland</em>, that Steve Yegge describes
wonderfully in <a href="http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html">Execution in the Kingdom of
Nouns</a>.</p>
<h1 id="performance">Performance</h1>
<p>Java is both fast and slow, depending on what language you compare it with. When
you compare it with higher level languages, Java is reasonably faster, but when
you compare it with C or C++, Java is miserably slow and heavy on resources.</p>
<p>Taking into account that Java is more of a low level language rather than a high
level one as we have seen, it should be compared to its closes cousins C and
C++, in which case you inevitably conclude that it’s just slow, very slow.</p>
<h1 id="java-sits-in-a-dead-spot">Java sits in a dead spot</h1>
<p>As we’ve seen, Java is mostly a low level programming language that doesn’t
really provide the benefits of one, while it pretends to be a high level
language and fails miserably.</p>
<p>This leads to the current situation:</p>
<pre><code>| C | C++ | Rust | Java | Ruby | Python | PHP | Perl | Earlang | OCaml | Haskell

|--- Low Level --| ???  |---                  High Level                    ---|</code></pre>
<h2 id="java-is-a-bad-low-level-language">Java is a bad low level language</h2>
<p>From the low level languages extreme, Java can perfectly be replaced by C++,
Rust and others. Both of these languages provide low level capabilities, and are
good for systems programming, while providing better high level traits like
C++’s RAII or Rust’s statically guaranteed safety. Both of these languages will
avoid Java’s <code>NullPointerException</code> and resource leaks.</p>
<h2 id="java-is-a-bad-high-level-language">Java is a bad high level language</h2>
<p>From the high level languages extreme, Java can be replaced by pretty much
<strong>any</strong> other language. Almost any of them will provide a nicer syntax, better
and more powerful ways of abstraction, better terseness, better tooling, better
everything.</p>
<p>This makes Java completely replaceable by any other language, it serves no
particular purpose and is particularly good at nothing.</p>
<h1 id="bad-programmers-abstractfactory">Bad programmers abstractFactory</h1>
<p>Professors in computer science Robert B.K. Dewar and Edmond Schonberg, published
<a href="http://static1.1.sqspcdn.com/static/f/702523/9242013/1288741087497/200801-Dewar.pdf?token=%2B5Thxkc7TmMcmP0qpas4Xaozf%2Bg%3D">an
article</a>
in the “Journal of Defense Software Engineering” discussing how Java is a bad
programming language for CS education, and how it produces programmers that are
incapable of doing actual problem-solving. Or, as Joel puts it in his article
<a href="https://www.joelonsoftware.com/2005/12/29/the-perils-of-javaschools-2/">“The Perils of
JavaSchools”</a>:</p>
<blockquote>
<p>I’ve seen that the 100% Java schools have started churning out quite a few CS
graduates who are simply not smart enough to work as programmers on anything
more sophisticated than Yet Another Java Accounting Applications</p>
</blockquote>]]></summary>
</entry>
<entry>
    <title>Using Cassius (Shakespearean template) with Hakyll</title>
    <link href="http://www.sillybytes.net/posts/using_hakyll_with_cassius.html" />
    <id>http://www.sillybytes.net/posts/using_hakyll_with_cassius.html</id>
    <published>2017-04-11</published>
    <updated>2017-04-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>As a user of the <a href="http://www.yesodweb.com/">Yesod</a> framework, I’ve come to know
and love the
<a href="https://www.stackage.org/haddock/lts-8.4/shakespeare-2.0.12.1/Text-Cassius.html#v:cassius">Cassius</a>
CSS templating language, although its reliance on Template Haskell is meant to
fit better with Yesod’s needs and makes it a bit cumbersome to use everywhere
else, I still like the templating language itself and its features a lot. That’s
why I used it for styles generation in <a href="https://sillybytes.net">Silly Bytes</a>
together with <a href="https://jaspervdj.be/hakyll/">Hakyll</a>. In this post I will
describe the process.</p>
<!--more-->
<h1 id="cassius-files">Cassius files</h1>
<p>Our <code>.cassius</code> files will live inside the <code>css</code> directory, together with a
<code>Gen.hs</code> Haskell module that will take the <em>Cassius</em> sources and compile them to
<em>CSS</em>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TemplateHaskell #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Gen</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Text.Cassius</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Text.Lazy</span> (unpack)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">writeFile</span> <span class="st">&quot;default.css&quot;</span> <span class="op">$</span> unpack <span class="op">$</span> renderCss def</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="fu">writeFile</span> <span class="st">&quot;post.css&quot;</span> <span class="op">$</span> unpack <span class="op">$</span> renderCss post</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="fu">writeFile</span> <span class="st">&quot;post-list.css&quot;</span> <span class="op">$</span> unpack <span class="op">$</span> renderCss postList</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>def <span class="ot">=</span> <span class="op">$</span>(cassiusFile <span class="st">&quot;default.cassius&quot;</span>) ()</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>post <span class="ot">=</span> <span class="op">$</span>(cassiusFile <span class="st">&quot;post.cassius&quot;</span>) ()</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>postList <span class="ot">=</span> <span class="op">$</span>(cassiusFile <span class="st">&quot;post-list.cassius&quot;</span>) ()</span></code></pre></div>
<p>This module, when executed (<code>runhaskell Gen.hs</code>), will compile the <em>Cassius</em>
sources <code>default.cassius</code>, <code>post.cassius</code> and <code>post-list.cassius</code> to the
corresponding <em>CSS</em> files that the -untouched- <em>CSS</em> rule in <code>site.hs</code> will
take and use in the generated site.</p>
<h1 id="compiling">Compiling</h1>
<p>The <em>Cassius</em> compilation doesn’t happen when we <code>stack exec site build</code>, as we
haven’t defined a rule, nor a compiler for them in <code>site.hs</code> and we won’t,
because the Template Haskell requirements mess things up.</p>
<p>So instead we are going to have a <code>Makefile</code> that will watch for changes in all
the <code>css/*.cassius</code> files and perform the recompilation by executing <code>Gen.hs</code>:</p>
<pre class="make"><code>.PHONY: build test css

build: css
    stack build
	stack exec site rebuild

css:
	cd css &amp;&amp; stack runhaskell Gen.hs

watch:
	while true; do make css; inotifywait -qre close_write css/*.cassius; done</code></pre>
<p>This way, we can execute <code>make watch</code> and it will recompile the <em>Cassius</em> files
when needed. A normal <code>stack exec site watch</code> can be running alongside to take
care of everything else.</p>]]></summary>
</entry>
<entry>
    <title>From Blogger to Hakyll</title>
    <link href="http://www.sillybytes.net/posts/from_blogger_to_hakyll.html" />
    <id>http://www.sillybytes.net/posts/from_blogger_to_hakyll.html</id>
    <published>2017-04-10</published>
    <updated>2017-04-10T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><a href="https://jaspervdj.be/hakyll/">Hakyll</a> is an amazing static site generator
written in Haskell, it allows for blog posts to be written in <em>markdown</em> and
then compiled with <em>pandoc</em>. It’s very well suited to be used with <em>GitHub
pages</em>. It’s everything I wanted and more.</p>
<p><a href="http://www.sillybytes.net">Silly Bytes</a> went through its first 5 years of
existence hosted on Google’s <a href="https://www.blogger.com">Blogger</a> service, and it
did well. Although Blogger offers a fair amount of flexibility, you can’t have
total control over it, and having to write posts with the built-in <em>WYSIWYG</em>
interface or pasting the HTML output is the biggest pain point of it. I solved
most of that by writing a <a href="http://www.sillybytes.net/2016/09/how-do-i-blog-blogger-posts-from.html">CLI
tool</a>
that allows me to write posts offline in <em>markdown</em>, compile them, and deploy
them from the terminal leveraging Blogger’s API. But that’s still too much of a
flex.</p>
<p>In this post I’ll describe the process of porting an existing Blogger blog to
<em>Hakyll</em> and <em>GitHub pages</em> using <em>Silly Bytes</em> itself as a case study.</p>
<!--more-->
<h1 id="expectations">Expectations</h1>
<p>So here is what I want instead:</p>
<ol type="1">
<li><p>Completely port <em>Silly Bytes</em> to <em>Hakyll</em> and <em>GitHub pages</em>. Write every
post in <em>markdown</em> only, and have them automatically generated.</p></li>
<li><p>Further customize the design. While I’ve managed to get pretty far with
Blogger’s custom CSS option, there are still some aspects that doesn’t quite fit
what I want.</p></li>
<li><p>Preserve all the links to previous posts.</p></li>
</ol>
<h1 id="the-initial-setup">The initial setup</h1>
<p>We’ll strive to keep the old blog completely functional till the last moment
when we finally change where the domain name points to.</p>
<h2 id="github-page">GitHub page</h2>
<p>The <em>GitHub pages</em> <a href="https://help.github.com/articles/user-organization-and-project-pages/">naming
convections</a>
state that, in order to create a dedicated repo for a personal or organizational
page, we must have a repository named <code>user.github.io</code> or
<code>organization.github.io</code> respectively, this way GitHub will read and serve any
<em>index</em> file in the repository root; This supposes a problem though, We want to
keep our generated site inside a directory to keep compiled files separated from
the sources.</p>
<p>There are a couple of solutions for this, but they all use some Git branches
trickery, juggling with a CI service, or both; It feels way to hacky to me, not
saying that my solution is better, but it just fits better with the work flow
I’m looking for.</p>
<p><em>GitHub pages</em> offers project specific pages as well, those are served from a
dedicated <code>docs</code> directory on it, so this is what we’re going to use instead.</p>
<p>I’ve created a <code>sillybytes</code>
<a href="https://github.com/sillybytes/sillybytes">repository</a> in the <code>sillybytes</code>
organization. Then in <code>settings → GitHub Pages → Source</code> I’ve selected
<code>master branch /docs folder</code> as the page source.</p>
<h2 id="hakyll-site">Hakyll site</h2>
<p>For the content of that repository, this will create the initial Hakyll
scaffolding:</p>
<pre><code>$ hakyll-init sillybytes
$ cd sillybytes
$ stack init
$ stack build</code></pre>
<p>By default, Hakyll outputs the generated site in a <code>_site</code> directory, but
<em>GitHub pages</em> will read the site from a <code>docs</code> directory, so let’s fix that by
editing the <code>site.hs</code> file.</p>
<p>The <code>main</code> function in <code>site.hs</code> uses the <code>hakyll</code> function with the default
configuration, so we need to swap that with a custom one:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> hakyllWith config <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="ot">config ::</span> <span class="dt">Configuration</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>config <span class="ot">=</span> <span class="dt">Configuration</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    { destinationDirectory <span class="ot">=</span> <span class="st">&quot;docs&quot;</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    , storeDirectory       <span class="ot">=</span> <span class="st">&quot;_cache&quot;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    , tmpDirectory         <span class="ot">=</span> <span class="st">&quot;_cache/tmp&quot;</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    , providerDirectory    <span class="ot">=</span> <span class="st">&quot;.&quot;</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    , ignoreFile           <span class="ot">=</span> ignoreFile&#39;</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    , deployCommand        <span class="ot">=</span> <span class="st">&quot;echo &#39;No deploy command specified&#39; &amp;&amp; exit 1&quot;</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    , deploySite           <span class="ot">=</span> system <span class="op">.</span> deployCommand</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    , inMemoryCache        <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    , previewHost          <span class="ot">=</span> <span class="st">&quot;127.0.0.1&quot;</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    , previewPort          <span class="ot">=</span> <span class="dv">8000</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>    ignoreFile&#39; path</span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="st">&quot;.&quot;</span>    <span class="ot">`isPrefixOf`</span> fileName <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="st">&quot;#&quot;</span>    <span class="ot">`isPrefixOf`</span> fileName <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="st">&quot;~&quot;</span>    <span class="ot">`isSuffixOf`</span> fileName <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="st">&quot;.swp&quot;</span> <span class="ot">`isSuffixOf`</span> fileName <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span>                    <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>        fileName <span class="ot">=</span> takeFileName path</span></code></pre></div>
<p>Here I’ve pretty much left the default configuration intact and only changed the
<code>destinationDirectory</code> field to be <code>docs</code>.</p>
<p>Now recompile and regenerate the site:</p>
<pre><code>$ stack build
$ stack exec site rebuild</code></pre>
<p>And the generated site will now be on <code>docs</code>.</p>
<h2 id="deploying">Deploying</h2>
<p>The deployment process consists of regenerating the site:</p>
<pre><code>$ stack exec site rebuild</code></pre>
<p>Committing the changes on <code>docs</code>:</p>
<pre><code>$ git add docs
$ git commit -m &quot;Build&quot;</code></pre>
<p>And pushing:</p>
<pre><code>$ git push origin master</code></pre>
<p>No need for esoteric spells here.</p>
<h1 id="dont-shatter-my-links">Don’t shatter my links!</h1>
<p>It is imperative to preserve the links to previous posts that were originally
published on Blogger, so they keep pointing to the right post.</p>
<h2 id="preserve-legacy-paths">Preserve legacy paths</h2>
<p>Blogger paths convention is as follows:</p>
<p>Every post is on the corresponding <em>year</em> and <em>month</em> of publication name space
like <code>year/month/post.html</code>. So we must preserve this structure at least for the
legacy posts.</p>
<p>In order to achieve this keep a <code>legacy</code> directory inside <code>posts</code>, that will in
turn contain a directory tree for every year and month when posts exist.</p>
<pre><code>sillybytes/posts/legacy
|
+---2012
|   |
|   +----01
|   |    +---- post.md
|   |
|   +----02
|   |
|   +---- ...
|
|
+---2013
|   |
|   +----01
|   |
|   +----02
|   |
|   +---- ...
|
|
+--- ...
    |
    +----01
    |
    +----02
    |
    +---- ...</code></pre>
<p>Then we need an additional rule in <code>site.hs</code></p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>match <span class="st">&quot;posts/legacy/**&quot;</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    route <span class="op">$</span> customRoute <span class="op">$</span> (<span class="fu">flip</span> replaceExtension <span class="st">&quot;html&quot;</span>) <span class="op">.</span> joinPath</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span> (<span class="fu">drop</span> <span class="dv">2</span>) <span class="op">.</span> splitPath <span class="op">.</span> toFilePath</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    compile <span class="op">$</span> pandocCompiler</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">&gt;&gt;=</span> saveSnapshot <span class="st">&quot;content&quot;</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;templates/post.html&quot;</span>    postCtx</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;templates/default.html&quot;</span> postCtx</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">&gt;&gt;=</span> relativizeUrls</span></code></pre></div>
<p>This will ensure that the <code>year/month/post.html</code> directory structure is
preserved on the resulting generated site.</p>
<h2 id="port-legacy-posts">Port legacy posts</h2>
<p>From here, a pretty much manual porting process is required. Most of the legacy
posts were originally published right in the Blogger interface, so some rewrite
to <em>markdow</em> is needed.</p>
<p>The porting process is as follows:</p>
<ol type="1">
<li>Visit the legacy post and copy the trailing name of it from the URL.</li>
<li>Create the appropriate directory structure inside <code>posts/legacy</code> to preserve
the same <code>year/month/post.html</code> path.</li>
<li>Create a <em>markdown</em> file with the same name as it appears in the URL, but
with the <code>.md</code> extension.</li>
<li>Create a dedicated directory for the post inside the <code>images</code> directory and
put all the post images in it.</li>
<li>Paste and format the post content in the <em>markdown</em> file.</li>
</ol>
<p>Any newer posts that are created after the porting can live in the <code>posts</code>
directory, there is no need to keep the <code>year/month/post.html</code> scheme any more.</p>
<h1 id="the-migration">The migration</h1>
<p>The only thing left is the actual migration by pointing the domain name to the
new site.</p>
<p>At this point a bigger problem arises. Given that we are serving the blog from
<code>sillybytes/docs</code> we’ll need a <em>URL Redirect</em> record pointing to
<code>sillybytes.github.io/sillybytes</code> rather than a <em>CNAME</em> to just
<code>sillybytes.github.io</code>. If you’re fine with that, then you’re done.</p>
<p>I really wanted a proper <em>CNAME</em> record though, so I had to change the setup a
bit:</p>
<ul>
<li>Have two repositories: <code>sillybytes</code> for the sources, and
<code>sillybytes.github.io</code> for the generated page.</li>
<li>A <em>deployment</em> consists of copying the content of the <code>docs</code> directory to the
<code>sillybytes.github.io</code> repository.</li>
<li>Point the domain name with a <em>CNAME</em> record to <code>sillybytes.github.io</code>.</li>
</ul>
<h1 id="new-cli-tool">New CLI tool</h1>
<p><img src="/img/bloggerhakyll/shot.png" class="img-responsive" /></p>
<p>The <a href="https://github.com/sillybytes/sillybytes_tool">CLI tool</a> I was using before
for Blogger deployment is no longer useful, but I can still adapt it to the new
deployment schema:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cp</span> <span class="at">-rfv</span> _site/<span class="pp">*</span> ../sillybytes.github.io/</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> ../sillybytes.github.io</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ex">display_info</span> <span class="st">&quot;Deploying...&quot;</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> add .</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> commit <span class="at">-m</span> <span class="st">&quot;Deploy&quot;</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> push origin master</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ex">display_success</span> <span class="st">&quot;Deployed!&quot;</span></span></code></pre></div>
<p>As well as aliasing common <em>Hakyll</em> commands:</p>
<p><img src="/img/bloggerhakyll/shot1.png" class="img-responsive" /></p>
<p>That’s some comfy blogging right there.</p>]]></summary>
</entry>
<entry>
    <title>Blogger posts from markdown and CLI</title>
    <link href="http://www.sillybytes.net/2016/09/how-do-i-blog-blogger-posts-from.html" />
    <id>http://www.sillybytes.net/2016/09/how-do-i-blog-blogger-posts-from.html</id>
    <published>2016-09-23</published>
    <updated>2016-09-23T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>There are plans to migrate Silly Bytes to <a href="https://jaspervdj.be/hakyll/">Hakyll</a>
and GitHub pages, but till then I’m still stuck with Blogger and wanted to make
the posting process as painless and automatic as possible.</p>
<p>Every post I write is currently a separate git repo hosted on the <a href="https://github.com/sillybytes">Silly Bytes
GitHub organization</a>. The post is written and
maintained in Markdown using Pandoc and a convenient Makefile generated by the
<a href="https://github.com/alx741/made">made script</a>.</p>
<p>Writing posts in Markdown is nice but is not that advantageous if you still have to
mess around with Blogger’s web interface, so here is the plan:</p>
<ul>
<li>Write posts in <em>Markdown</em></li>
<li>Use <em>made</em> to generate a <em>Makefile</em></li>
<li>Generate HTML with <code>$ make</code></li>
<li>Push the HTML post to Blogger using Google’s APIs</li>
</ul>
<!--more-->
<p>The first 3 steps are already covered so lets dig into the Blogger negotiation
part.</p>
<h2 id="api-script">API script</h2>
<p><a href="https://developers.google.com/api-client-library/python/start/installation">Google’s
APIs</a>
come in handy here, the best language option was Python (<a href="https://sillybytes.net/2016/03/why-do-i-hate-java.html">I refuse tu use
Java</a>). So starting from
an
<a href="https://github.com/google/google-api-python-client/tree/master/samples/blogger">example</a>
I came up with this helper script:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/env python</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="co"># -*- coding: utf-8 -*-</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> __future__ <span class="im">import</span> print_function</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> googleapiclient <span class="im">import</span> discovery</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> oauth2client <span class="im">import</span> client</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> oauth2client <span class="im">import</span> <span class="bu">file</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> oauth2client <span class="im">import</span> tools</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> sys</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> os</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> httplib2</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> argparse</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>SILLYBYTESID<span class="op">=</span><span class="st">&quot;1318550761233559867&quot;</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> main(argv):</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="bu">len</span>(argv) <span class="op">&lt;</span> <span class="dv">3</span>):</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(<span class="st">&quot;Post title must be provided as the first argument and html file as the second&quot;</span>)</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>        exit(<span class="dv">1</span>)</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    post_title <span class="op">=</span> argv[<span class="dv">1</span>]</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    input_file <span class="op">=</span> argv[<span class="dv">2</span>]</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>    scope <span class="op">=</span> <span class="st">&#39;https://www.googleapis.com/auth/blogger&#39;</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>    parent_parsers <span class="op">=</span> [tools.argparser]</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>    parent_parsers.extend([])</span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>    parser <span class="op">=</span> argparse.ArgumentParser(</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>        description<span class="op">=</span>__doc__,</span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>        formatter_class<span class="op">=</span>argparse.RawDescriptionHelpFormatter,</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>        parents<span class="op">=</span>parent_parsers)</span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>    flags <span class="op">=</span> parser.parse_args(<span class="st">&quot;&quot;</span>)</span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span>:</span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>        client_secrets <span class="op">=</span> os.path.join(os.path.expanduser(<span class="st">&quot;~&quot;</span>) <span class="op">+</span> <span class="st">&#39;/.sillybytes/&#39;</span>,</span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>                                    <span class="st">&#39;secrets.json&#39;</span>)</span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>    <span class="cf">except</span>:</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(<span class="st">&quot;Can&#39;t find secrets.json file maybe?&quot;</span>)</span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>        exit(<span class="dv">1</span>)</span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>    flow <span class="op">=</span> client.flow_from_clientsecrets(client_secrets,</span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>                                        scope<span class="op">=</span>scope,</span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>                                        message<span class="op">=</span>tools.message_if_missing(client_secrets))</span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>    storage <span class="op">=</span> <span class="bu">file</span>.Storage(<span class="st">&#39;auth_data&#39;</span> <span class="op">+</span> <span class="st">&#39;.dat&#39;</span>)</span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a>    credentials <span class="op">=</span> storage.get()</span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> credentials <span class="kw">is</span> <span class="va">None</span> <span class="kw">or</span> credentials.invalid:</span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a>        credentials <span class="op">=</span> tools.run_flow(flow, storage, flags)</span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a>    http <span class="op">=</span> credentials.authorize(http <span class="op">=</span> httplib2.Http())</span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a>    service <span class="op">=</span> discovery.build(<span class="st">&#39;blogger&#39;</span>, <span class="st">&#39;v3&#39;</span>, http<span class="op">=</span>http)</span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span>:</span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a>        content <span class="op">=</span> <span class="bu">open</span>(input_file, <span class="st">&#39;r&#39;</span>).read()</span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a>    <span class="cf">except</span> <span class="pp">FileNotFoundError</span>:</span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(<span class="st">&quot;Input file not found&quot;</span>)</span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a>        exit(<span class="dv">1</span>)</span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a>    body <span class="op">=</span> {</span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;kind&quot;</span>: <span class="st">&quot;blogger#post&quot;</span>,</span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;title&quot;</span>: post_title,</span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;content&quot;</span>: content</span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span>:</span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a>        posts <span class="op">=</span> service.posts()</span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a>        request <span class="op">=</span> posts.insert(blogId<span class="op">=</span>SILLYBYTESID, body<span class="op">=</span>body, isDraft<span class="op">=</span><span class="va">False</span>)</span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a>        result <span class="op">=</span> request.execute()</span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(<span class="st">&quot;Live: &quot;</span> <span class="op">+</span> result[<span class="st">&#39;url&#39;</span>])</span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a>    <span class="cf">except</span>:</span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(<span class="st">&quot;Can&#39;t execute request&quot;</span>)</span>
<span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a>        exit(<span class="dv">1</span>)</span>
<span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a>main(sys.argv)</span></code></pre></div>
<p>The script will initiate an OAuth negotiation when needed and store the
authentication tokens in the <code>auth_data.dat</code> file.</p>
<h2 id="api-project">API project</h2>
<p>Before we’re able to use this we need to create a new <em>API project</em>, configure
it and get the <code>client_secrets.json</code> that the script will use to start the OAuth
negotiation.</p>
<p>First, enable the <em>Blogger</em> API at:
https://console.developers.google.com/apis/library</p>
<p>Then create a new project, a new set of credentials and download the JSON file
from it. From the script above you’ll gather my <code>client_secrets.json</code> file will
be located at <code>~/.sillybytes</code>.</p>
<p>Now, running:</p>
<pre><code>$ python deploy.py &quot;post title&quot; &quot;post HTML&quot;</code></pre>
<p>Will push the post to Blogger!</p>
<h2 id="cli-tool">CLI tool</h2>
<p>This is good enough already, we could just invoke <code>deploy.py</code> from the Makefile,
but we can still do better:</p>
<p><a href="https://github.com/sillybytes/sillybytes_tool/tree/blogger">silly</a>.</p>
<pre><code>$ silly help</code></pre>
<p><img src="/img/blogger/shot.png" class="img-responsive" /></p>
<p>Now I can create all the post boilerplate by doing <code>silly new</code> and deploying the
current post with <code>silly deploy</code>. Much better.</p>]]></summary>
</entry>
<entry>
    <title>Gentle introduction to STM32 ARM Cortex microcontrollers and boards programming</title>
    <link href="http://www.sillybytes.net/2016/09/gentle-introduction-to-stm32-arm-cortex.html" />
    <id>http://www.sillybytes.net/2016/09/gentle-introduction-to-stm32-arm-cortex.html</id>
    <published>2016-09-11</published>
    <updated>2016-09-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>So you’ve been using AVR, PIC or some other microcontroller for a while and
would like to try 32-bit ARM chips like the <a href="http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus.html?querycriteria=productId=SC1169">STM32
line</a>.
Want to start playing with them but don’t know how or where to start; I’m here
to help.</p>
<p><a href="https://en.wikipedia.org/wiki/ARM_architecture">ARM</a> has taken over the
embedded world, they’re ubiquitous in smartphones, tablets, laptops, computers
inside computers, cars, refrigerators, microwave ovens, monitors, printers, you
name it.</p>
<p>Note: Be aware that <em>ARM</em> is an <strong>architecture</strong> that manufacturers can
<em>implement</em>. Is a common mistake to think <em>ARM</em> is a microcontroller on
itself, it is not.</p>
<!--more-->
<p>ST Microelectronics’s implementation of ARM are the STM32 microcontrollers:
inexpensive, powerful and with great free software/hardware support.</p>
<p>Various series are available: F0, F1, F2, …, F7. You can identify your chip
series after the <em>STM32</em> prefix, I’m using a board with the “STM32F103C8” chip,
so the series is <em>F1</em>.</p>
<h2 id="hardware">Hardware</h2>
<p>These chips are relatively inexpensive and widely available, often mounted in
convenient development or breakout boards.</p>
<p>Individual chips can be bought from electronic stores like Digi-Key or Mouser.
For the current purpose though, making your own PCB to mount them is quite
inconvenient.</p>
<p>The other option is to get one of the nice development boards ST offers:</p>
<ul>
<li><a href="http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-eval-boards.html?querycriteria=productId=LN1199">Eval</a></li>
<li><a href="http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-nucleo.html?querycriteria=productId=LN1847">Nucleo</a></li>
<li><a href="http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits.html?querycriteria=productId=LN1848">Discovery</a></li>
</ul>
<p><img src="/img/stm32/shot1.png" /></p>
<p>Although these are cheap and amazing, we can go even cheaper with some breakout
boards available on Ebay and others. You can get a STM32F103 chip in a nice
board for less than $ 5 USD.</p>
<p><img src="/img/stm32/shot2.png" />
<img src="/img/stm32/shot3.png" /></p>
<h3 id="programmer">Programmer</h3>
<p>STM32 chips are programmed using a
<a href="https://en.wikipedia.org/wiki/ARM_architecture">ST-LINK</a> device, which is an
in-circuit debugger and programmer that interfaces with the chip using JTAG or
Serial Wire Debugging
(<a href="http://www.arm.com/products/system-ip/debug-trace/coresight-soc-components/serial-wire-debug.php">SWD</a>).
This is similar to the USBASP for AVR or the PICkit for PIC.</p>
<p>Development boards like the <em>Nucleo</em> include the st-link hardware right on the
board, so you can connect it to a host computer using USB and program/debug the
target chip without any additional external hardware.</p>
<p><img src="/img/stm32/shot4.png" /></p>
<p>If you’re using breakout boards (like the Ebay ones) or if you mounted a chip in
a custom PCB, you will need an external st-link hardware. Fortunately they are
also available for cheap on Ebay, or you can buy the official one for a few
extra bucks if you prefer, they both will work exactly the same with the
flashing software.</p>
<p><img src="/img/stm32/shot5.png" />
<img src="/img/stm32/shot6.png" /></p>
<h4 id="connections">Connections</h4>
<p>If you’re using an ST development board with the st-link built-in just connect
it to your computer and you’re ready to go, but for breakout boards and a dongle
st-link you’ll need to connect four wires to it:</p>
<ul>
<li>VCC (3.3V)</li>
<li>GND</li>
<li>SWCLK</li>
<li>SWDIO</li>
</ul>
<p><strong>WARNING:</strong> STM32 chips run on 3.3V, most breakout boards will include a
voltage regulator, so it can be powered from USB, and st-link dongles will
provide a 3.3V VCC PIN to power the chip. <em>DON’T</em> Connect the board to the PC
using USB while the chip is powered up using the st-link programmer! Connect one
or the other but not both simultaneously. The st-link dongle provides a 5V PIN
as well, <em>DON’T</em> use it, the STM32 chips are not 5V tolerant, use the 3.3V PIN
only.</p>
<p>ST-Link dongles have labeling on the front, just connect the right pins. On the
board side, follow the labeling printed on the pins or use a pin out diagram.
The connections for the st-link on the breakout board I’m using look like this:</p>
<p><img src="/img/stm32/scheme1.jpg" />
<img src="/img/stm32/shot7.jpg" />
<img src="/img/stm32/shot8.jpg" /></p>
<h2 id="software">Software</h2>
<h3 id="host-pc">Host PC</h3>
<p>You’ll need a compiler, a debugger, some utilities to manage your binaries and
the necessary software to flash your firmware using the ST-LINK device (dongle
or built-in):</p>
<ul>
<li>arm-none-eabi-gcc</li>
<li>arm-none-eabi-gdb</li>
<li>arm-none-eabi-binutils</li>
<li>stlink</li>
</ul>
<p>You should be able to install them all of from your distribution repositories.
In case you can’t find <code>stlink</code> on them, get it from the <a href="https://github.com/texane/stlink">GitHub
repository</a>.</p>
<p>The <code>stlink</code> package provides these executables:</p>
<ul>
<li><code>st-flash</code> - Write and Read a program from the target chip</li>
<li><code>st-util</code> - Creates a GDB server, so you can load, run and debug a program on the target chip</li>
<li><code>st-info</code> - Search and provides information about the st-link device and the target chip</li>
<li><code>st-term</code> - Gives you log-like reports from the program on the target chip</li>
</ul>
<h4 id="test-the-setup">Test the setup</h4>
<p>With the hardware connected and the PC software installed we can try it out and
see if everything is working. No example program yet though.</p>
<p>Connect your st-link device (connected to the breakout board) or your
development board to the host PC using USB and run:</p>
<pre><code>$ st-info --probe</code></pre>
<p>You’ll get some neat information about the chip that is hooked up to the st-link
device:</p>
<pre><code>Found 1 stlink programmers
serial: 543f6a06663f505130531567
openocd: &quot;\x54\x3f\x6a\x06\x66\x3f\x50\x51\x30\x53\x15\x67&quot;
flash: 65536 (pagesize: 1024)
sram: 20480
chipid: 0x0410
descr: F1 Medium-density device</code></pre>
<p>Fantastic! Everything is working fine, lets move on.</p>
<h3 id="chip">Chip</h3>
<p>ARM provides a Cortex Microcontroller Software Interface Standard
(<a href="http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php">SMSIS</a>)
as an abstraction layer for the ARM Cortex core to increase software
portability. Think of it as a standard API that you can use to interface with
ARM chips in a vendor independent way.</p>
<p>On top of that you might want to have a Hardware Abstraction Layer (HAL) to
interface with the peripherals each particular chip provides (UART, USB, I2C,
SPI, TIMERS, etc).</p>
<p>We have two options of libraries that provide those abstraction layers:</p>
<ul>
<li><a href="http://libopencm3.github.io/">LibOpenCM3</a> (The one we are going to use)</li>
<li><a href="http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef1.html">STM32Cube</a></li>
</ul>
<p>LibOpenCM3 uses the LGPL licence (which I prefer), and STM32Cube uses the lax
BSD licence. Balau covered the licensing topic in more detail in his <a href="https://balau82.wordpress.com/2015/04/12/libopencm3-for-the-license-sensitive-cortex-m-developer/">blog
post</a>.</p>
<h4 id="stm32cube">STM32Cube</h4>
<p>ST provides the so called “STM32Cube”, which is a bundle of software and
libraries for STM32 development. It contains a graphical software for basic C
code generation, software layers of abstraction like HAL and middleware,
software layers for built-in peripherals on ST’s development boards and
examples.</p>
<p>The <em>STM32Cube</em> is available per chip series, so for development boards with
STM32F4xx chips you’ll need the <em>STM32CubeF4</em>. I have a breakout board with the
STM32F103C8 chip, so I would use the
<a href="http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef1.html"><em>STM32CubeF1</em></a>,
you get the idea.</p>
<p>STM32Cube provides 3 layers:</p>
<h5 id="level-0">Level 0</h5>
<ul>
<li>Board Support Package (BSP) for interfacing with devices on the board that are
not in the STM32 chip.</li>
<li>Hardware Abstraction Layer (HAL) for low-level hardware interfacing (UART,
USB, I2C, SPI, TIMERS, etc).</li>
</ul>
<h5 id="level-1">Level 1</h5>
<p>Middleware software components like USB Host and Device libraries or FAT file
system for SD cards interfacing</p>
<h5 id="level-2">Level 2</h5>
<p>Graphical demonstration that uses the level 1 Middleware.</p>
<p>You can read more about it on the STM32Cube user manual. Here is the STM32CubeF1
<a href="http://www.st.com/content/ccc/resource/technical/document/user_manual/a4/ae/25/45/76/ca/40/b1/DM00151047.pdf/files/DM00151047.pdf/jcr:content/translations/en.DM00151047.pdf">manual</a>
to get you started.</p>
<h4 id="libopencm3">LibOpenCM3</h4>
<p>LibOpenCM3 aims to provide a free (as in freedom) library for various ARM
Cortex-M3 microcontrollers, including the STM32 chips.</p>
<p>Using this library is more or less straight forward, there are no (explicit)
layers here. You can read more about it in the
<a href="http://libopencm3.org/wiki/Main_Page">wiki</a>. They have some fantastic Doxygen
documentation for the <a href="http://libopencm3.github.io/docs/latest/html/">API</a> as
well.</p>
<h2 id="first-program">First program</h2>
<p>The LibOpenCM3 project provides very useful examples, lets use one of those as
the first program. I’m Using the STM32F103C8T6, so I need the <em>F1</em> series
examples and libraries, adjust the steps to use the appropriate one for your
chip/board.</p>
<p>Notice that the examples are organized to correspond to various development
boards, but it doesn’t really matter, the reason for this is the distribution of
LED’s and Push buttons in those boards, but as long as you’re using the same
chip series you just need to pick up one and connect LED’s, buttons, etc in the
right pins as needed. I’m going to use the examples for the <em>“stm32-h103”</em> board
from Olimex, even though I’m using a breakout board from Ebay; The <strong>F1</strong> is the
important thing here.</p>
<pre><code>$ git clone --recursive &#39;https://github.com/libopencm3/libopencm3-examples&#39;
$ cd libopencm3-examples
$ make
$ cd examples/stm32
$ cd f1
$ cd stm32-h103/miniblink</code></pre>
<p>This example will BLINK an LED connected to PIN 12 of the GPIO port C, but my
chip doesn’t have it! No problem, I’m going to change it (you can use your
favorite editor here):</p>
<pre><code>$ vim miniblink.c</code></pre>
<p>Now change all appearances of <code>GPIOC</code> to <code>GPIOB</code> so the program uses the GPIO
port B instead. (Use an available pin in your specific chip/board).</p>
<p>In Vim:</p>
<pre><code>:%s/GPIOC/GPIOB</code></pre>
<p>Save the file and compile:</p>
<pre><code>$ make</code></pre>
<p>Generate the binary:</p>
<pre><code>$ arm-none-eabi-objcopy -O binary miniblink.elf miniblink.bin</code></pre>
<p>Flash it:</p>
<pre><code>$ st-flash write miniblink.bin 0x8000000</code></pre>
<p>Connect an LED to the GND and PB12 pins through a 330 Ohm resistor and rejoice
with it’s blinkiness.</p>
<h2 id="using-gdb">Using GDB</h2>
<p>You can also interface with the target device using GDB: Debug, Upload firmware,
run, stop, set break points, etc. I’m going to assume you know how to use GDB
and only going to explain how to upload the firmware from it.</p>
<p>Create a GDB server to interface with the connected target:</p>
<pre><code>$ st-util -p 4444</code></pre>
<p>Run ARM GDB:</p>
<pre><code>$ arm-none-eabi-gdb</code></pre>
<p>Connect to the server</p>
<pre><code>(gdb) target extended-remote localhost:4444</code></pre>
<p>Flash the firmware (notice we’re using the ELF file here not the BIN one):</p>
<pre><code>(gdb) load miniblink.elf</code></pre>
<p>Run the firmware:</p>
<pre><code>(gdb) continue</code></pre>
<p>You can stop it with <code>C-c</code>.</p>
<p><img src="/img/stm32/shot9.jpg" /></p>]]></summary>
</entry>
<entry>
    <title>TDD (Test-Driven Development) Physical Traffic Light</title>
    <link href="http://www.sillybytes.net/2016/08/tdd-test-driven-development-physical.html" />
    <id>http://www.sillybytes.net/2016/08/tdd-test-driven-development-physical.html</id>
    <published>2016-08-28</published>
    <updated>2016-08-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Robert C. Martin <em>(Uncle Bob)</em> said in a talk:</p>
<blockquote>
<p>Imagine you have a button that you can push, it will test your code and if
everything is working a green light will come up, but if something is broken,
a red light will come up […]</p>
</blockquote>
<p>He was of course talking about TDD. It got me inspired to build this little
tool.</p>
<p>Hardware schematics, firmware and host software is available in <a href="https://github.com/alx741/tdd_traffic-light">this GitHub
repository</a>. Along with information
on how to compile and use.</p>
<blockquote>
<p>This is a physical toy traffic light to be used with software development TDD
(and testing in general) tools. It will not boost your productivity nor make
you a better programmer or TDD practitioner, but it looks cool :)</p>
</blockquote>
<!--more-->
<h1 id="hardware">Hardware</h1>
<p>The <em>atmega328p</em> AVR chip is very popular and cheap, so much so, that chances
are high you got it with the Arduino bootloader, which gets in the way as we can
perfectly use the internal oscillator at 1Mhz instead of an external 16Mhz
crystal. Fix this by changing the fuses:</p>
<pre class="shell"><code># avrdude -p m328p -c usbasp -U lfuse:w:0x62:m -U hfuse:w:0xd9:m</code></pre>
<p>The circuit is simple enough to mount in some perfboard. Additionally, I added
some small neodymium magnets in the back for mounting purposes.</p>
<p><img src="/img/tddlight/img1.jpg" class="img-responsive" />
<img src="/img/tddlight/img2.jpg" class="img-responsive" />
<img src="/img/tddlight/img3.jpg" class="img-responsive" />
<img src="/img/tddlight/img4.jpg" class="img-responsive" />
<img src="/img/tddlight/img5.jpg" class="img-responsive" />
<img src="/img/tddlight/img6.jpg" class="img-responsive" />
<img src="/img/tddlight/img7.jpg" class="img-responsive" />
<img src="/img/tddlight/img8.jpg" class="img-responsive" /></p>
<h1 id="software">Software</h1>
<p>The firmware is no more than some UART boilerplate with a <code>4800</code> baud rate so
that it’s stable at 1MHz.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;avr/io.h&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;util/delay.h&gt;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="pp">#define F_CPU </span><span class="dv">1000000</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="pp">#define BAUD </span><span class="dv">4800</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#define BAUD_PRESCALE </span><span class="op">((((</span><span class="pp">F_CPU</span><span class="op">/</span><span class="dv">16</span><span class="op">)</span><span class="pp"> </span><span class="op">+</span><span class="pp"> </span><span class="op">(</span><span class="pp">BAUD</span><span class="op">/</span><span class="dv">2</span><span class="op">))</span><span class="pp"> </span><span class="op">/</span><span class="pp"> </span><span class="op">(</span><span class="pp">BAUD</span><span class="op">))</span><span class="pp"> </span><span class="op">-</span><span class="pp"> </span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="dt">char</span> getchar<span class="op">(</span><span class="dt">void</span><span class="op">)</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">((</span>UCSR0A <span class="op">&amp;</span> <span class="op">(</span><span class="dv">1</span> <span class="op">&lt;&lt;</span> RXC0<span class="op">))</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{}</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> UDR0<span class="op">;</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The main loop will wait for a command <code>r</code>, <code>y</code> or <code>g</code> and turn on the pin
corresponding to the color LED.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;avr/io.h&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;util/delay.h&gt;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="pp">#define F_CPU </span><span class="dv">1000000</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="pp">#define BAUD </span><span class="dv">4800</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#define BAUD_PRESCALE </span><span class="op">((((</span><span class="pp">F_CPU</span><span class="op">/</span><span class="dv">16</span><span class="op">)</span><span class="pp"> </span><span class="op">+</span><span class="pp"> </span><span class="op">(</span><span class="pp">BAUD</span><span class="op">/</span><span class="dv">2</span><span class="op">))</span><span class="pp"> </span><span class="op">/</span><span class="pp"> </span><span class="op">(</span><span class="pp">BAUD</span><span class="op">))</span><span class="pp"> </span><span class="op">-</span><span class="pp"> </span><span class="dv">1</span><span class="op">)</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="dt">char</span> getchar<span class="op">(</span><span class="dt">void</span><span class="op">)</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">((</span>UCSR0A <span class="op">&amp;</span> <span class="op">(</span><span class="dv">1</span> <span class="op">&lt;&lt;</span> RXC0<span class="op">))</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{}</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> UDR0<span class="op">;</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Notice how if any other character is received the output gets cleared.</p>
<p>The host software configures the serial port with a <code>4800</code> baud rate:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> serial_init<span class="op">(</span><span class="dt">char</span><span class="op">*</span> port<span class="op">)</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>COM_FD <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span><span class="op">;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Open serial port file</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> fd <span class="op">=</span> open<span class="op">(</span>port<span class="op">,</span> O_RDWR <span class="op">|</span> O_NOCTTY <span class="op">|</span> O_NDELAY<span class="op">);</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Configure serial port</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> termios config<span class="op">;</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>tcgetattr<span class="op">(</span>fd<span class="op">,</span> <span class="op">&amp;</span>config<span class="op">)</span> <span class="op">!=</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>        COM_FD <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>        printf<span class="op">(</span><span class="st">&quot;Error while configing serial port&quot;</span><span class="op">);</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>        exit<span class="op">(</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>    cfsetispeed<span class="op">(&amp;</span>config<span class="op">,</span> B4800<span class="op">);</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>    cfsetospeed<span class="op">(&amp;</span>config<span class="op">,</span> B4800<span class="op">);</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_cflag <span class="op">|=</span> <span class="op">(</span>CLOCAL <span class="op">|</span> CREAD <span class="op">|</span> CS8<span class="op">);</span></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_cflag <span class="op">&amp;=</span> <span class="op">~(</span>PARENB <span class="op">|</span> PARODD<span class="op">);</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_iflag <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_oflag <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_lflag <span class="op">&amp;=</span> <span class="op">~(</span>ICANON <span class="op">|</span> ECHO <span class="op">|</span> ECHOE <span class="op">|</span> ISIG<span class="op">);</span></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_cc<span class="op">[</span>VTIME<span class="op">]</span> <span class="op">=</span> <span class="dv">5</span><span class="op">;</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>    config<span class="op">.</span>c_cc<span class="op">[</span>VMIN<span class="op">]</span> <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>tcsetattr<span class="op">(</span>fd<span class="op">,</span> TCSANOW<span class="op">,</span> <span class="op">&amp;</span>config<span class="op">)</span> <span class="op">!=</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a>        COM_FD <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb4-34"><a href="#cb4-34" aria-hidden="true" tabindex="-1"></a>        printf<span class="op">(</span><span class="st">&quot;Error while configing serial port&quot;</span><span class="op">);</span></span>
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true" tabindex="-1"></a>        exit<span class="op">(</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-37"><a href="#cb4-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-38"><a href="#cb4-38" aria-hidden="true" tabindex="-1"></a>    COM_FD <span class="op">=</span> fd<span class="op">;</span></span></code></pre></div>
<p>With that, controlling the LEDs is as simple as:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>write<span class="op">(</span>COM_FD<span class="op">,</span> <span class="st">&quot;r&quot;</span><span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span></code></pre></div>
<p>Find more information about how to use it in the <a href="https://github.com/alx741/tdd_traffic-light">GitHub
repository</a>.</p>]]></summary>
</entry>
<entry>
    <title>Vim + Haskell</title>
    <link href="http://www.sillybytes.net/2016/08/vim-haskell_11.html" />
    <id>http://www.sillybytes.net/2016/08/vim-haskell_11.html</id>
    <published>2016-08-11</published>
    <updated>2016-08-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>So you’re writing in the right language using the right tool already, let’s put
some extra magic under your sleeves.</p>
<p>This is what we expect to accomplish:</p>
<ul>
<li>Omnicompletion</li>
<li>Compilation and testing
<ul>
<li>Building</li>
<li>Testing</li>
</ul></li>
<li>GHCI integration</li>
<li>Hoogle integration</li>
<li>Convenient mappings
<ul>
<li>Argument text object</li>
<li>Jump to importations</li>
<li>Jump between functions</li>
</ul></li>
<li>Ghc-mod integration
<ul>
<li>Type inserting</li>
<li>Case splitting</li>
<li>Type asserting</li>
</ul></li>
<li>Hlint integration
<ul>
<li>Linting</li>
<li>Managing the location list</li>
</ul></li>
<li>Code formatting
<ul>
<li>Hindent integration</li>
<li>Trailing white space</li>
<li>Trailing blank lines</li>
<li>Spaces over tabs</li>
</ul></li>
<li>Easy arrows generation</li>
<li>Types abbreviations</li>
<li>Yesod Haskell web framework</li>
</ul>
<!--more-->
<p>Most of this functionality is achieved by using already available tools and
already available Vim plugins for those tools. So I’ll assume you have your way
to install the plugins (I’m using
<a href="https://github.com/junegunn/vim-plug">vim-plug</a>).</p>
<p>Here is my complete
<a href="https://github.com/alx741/dotfiles/blob/master/nvim/.config/nvim/init.vim">.vimrc</a>.</p>
<p><strong>Important</strong>: Every line of vimrc used should be enclosed in an <code>:h :augroup</code>:</p>
<pre class="vim"><code>augroup ft_haskell
    au!

    ...

augroup END</code></pre>
<h3 id="omnicompletion">Omnicompletion</h3>
<p>The <a href="https://github.com/eagletmt/neco-ghc">neco-ghc</a> plugin declares a complete
omnifunction. Use it by defining the local <code>omnifunc</code>:</p>
<pre class="vim"><code>au FileType haskell setlocal omnifunc=necoghc#omnifunc</code></pre>
<p><img src="/img/vimhask/shot1.gif" /></p>
<h3 id="compilation-and-testing">Compilation and testing</h3>
<p>I’ve contributed the GHC compiler plugin to upstream Vim recently, but it may
take a while before you get the latest vim runtime from your distribution. So in
the meantime you can install it like any other plugin from the GitHub repository
here: https://github.com/alx741/ghc.vim. <strong>Update:</strong> It’s been merged into vim’s
runtime, you should have it by default now.</p>
<p>Then load it for the Haskell <em>filetype</em> in you <em>vimrc</em>:</p>
<pre class="vim"><code>au FileType haskell compiler ghc</code></pre>
<p>Taking advantage of vim 8 asynchronous job control using the
<a href="https://github.com/skywind3000/asyncrun.vim">asyncrun.vim</a> plugin, we can
define some convenient mappings for building and testing using Haskell <em>stack</em>:</p>
<pre class="vim"><code>au FileType haskell setlocal makeprg=stack
au FileType haskell nnoremap &lt;buffer&gt; gj :write&lt;CR&gt; :exec &quot;AsyncRun &quot; . &amp;makeprg . &quot; build&quot;&lt;CR&gt;
au FileType haskell nnoremap &lt;buffer&gt; gk :write&lt;CR&gt; :exec &quot;AsyncRun &quot; . &amp;makeprg . &quot; test&quot;&lt;CR&gt;</code></pre>
<p>After running one of those the results will be loaded into the <em>quickfix</em> list.</p>
<h3 id="ghci-integration">GHCI integration</h3>
<p>There are plugins that offer much more tight integration but for me, it is
enough to start GHCI from the current vim instance in a Tmux pane loaded with
the current project or Haskell source, so taking advantage of the
<a href="https://github.com/benmills/vimux">vimux</a> Tmux integration plugin, lets define
a function:</p>
<pre class="vim"><code>function! RunGhci(type)
    call VimuxRunCommand(&quot; stack ghci &amp;&amp; exit&quot;)
    if a:type
        call VimuxSendText(&quot;:l &quot; . bufname(&quot;%&quot;))
        call VimuxSendKeys(&quot;Enter&quot;)
    endif
endfunction</code></pre>
<p>And some mappings:</p>
<pre class="vim"><code>au FileType haskell nmap &lt;silent&gt;&lt;buffer&gt; &lt;leader&gt;gg :call RunGhci(1)&lt;CR&gt;
au FileType haskell nmap &lt;silent&gt;&lt;buffer&gt; &lt;leader&gt;gs :call RunGhci(0)&lt;CR&gt;</code></pre>
<p>So doing <code>\gg</code> will start a GHCI session loaded with the current file and <code>\gs</code>
will load a GHCI session for the current stack project.</p>
<h3 id="hoogle-integration">Hoogle integration</h3>
<p>Vim uses <code>K</code> (upper case k) to look up a keyword under the cursor, so we can
leverage that and just define the right <code>keywordprg</code>:</p>
<pre class="vim"><code>au FileType haskell set kp=hoogle</code></pre>
<p>Or, if you prefer having your results within Vim, you can use the
[vim-hoogle](https://github.com/Twinside/vim-hoogle] plugin, and remap <code>K</code>:</p>
<pre class="vim"><code>au FileType haskell nnoremap K :HoogleInfo&lt;CR&gt;</code></pre>
<h3 id="convenient-mappings">Convenient mappings</h3>
<p>When editing a function’s arguments we would like to have a text object so doing
<code>cia</code> (change inner argument) or <code>daa</code> (delete all argument) will work; These
will to the trick:</p>
<pre class="vim"><code>au FileType haskell onoremap &lt;silent&gt; ia :&lt;c-u&gt;silent execute &quot;normal! ?-&gt;\r:nohlsearch\rwvf-ge&quot;&lt;CR&gt;
au FileType haskell onoremap &lt;silent&gt; aa :&lt;c-u&gt;silent execute &quot;normal! ?-&gt;\r:nohlsearch\rhvEf-ge&quot;&lt;CR&gt;</code></pre>
<p>In order to easily jump between functions we could define a function:</p>
<pre class="vim"><code>function! JumpHaskellFunction(reverse)
    call search(&#39;\C[[:alnum:]]*\s*::&#39;, a:reverse ? &#39;bW&#39; : &#39;W&#39;)
endfunction</code></pre>
<p>And some mappings such that <code>[[</code> or <code>]]</code> will take us to the previous and next
function:</p>
<pre class="vim"><code>au FileType haskell nnoremap &lt;buffer&gt;&lt;silent&gt; ]] :call JumpHaskellFunction(0)&lt;CR&gt;
au FileType haskell nnoremap &lt;buffer&gt;&lt;silent&gt; [[ :call JumpHaskellFunction(1)&lt;CR&gt;</code></pre>
<p>Let’s add some extra convenience and use <code>gI</code> for jumping to the first <em>import</em>
statement and <code>gC</code> to edit the <em>.cabal</em> file:</p>
<pre class="vim"><code>au FileType haskell nnoremap &lt;buffer&gt; gI gg /\cimport&lt;CR&gt;&lt;ESC&gt;:noh&lt;CR&gt;
au FileType haskell nnoremap &lt;buffer&gt; gC :e *.cabal&lt;CR&gt;</code></pre>
<h3 id="ghc-mod-integration">Ghc-mod integration</h3>
<p><a href="https://hackage.haskell.org/package/ghc-mod">ghc-mod</a> is the <em>Happy Haskell
Programming package</em>! With a bunch of functionality, here we will be using
just a few:</p>
<ul>
<li>Type inserting</li>
<li>Case splitting</li>
<li>Type asserting</li>
</ul>
<p>You need the <em>ghc-mod</em> package: <code>stack install ghc-mod</code> and the <a href="https://github.com/eagletmt/ghcmod-vim">ghcmod-vim
plugin</a>.</p>
<pre class="vim"><code>au FileType haskell nnoremap &lt;silent&gt;&lt;buffer&gt; git :GhcModTypeInsert&lt;CR&gt;
au FileType haskell nnoremap &lt;silent&gt;&lt;buffer&gt; gfs :GhcModSplitFunCase&lt;CR&gt;
au FileType haskell nnoremap &lt;silent&gt;&lt;buffer&gt; gtt :GhcModType&lt;CR&gt;</code></pre>
<p><code>git</code> (<em>g insert type</em>) will insert the missing type declaration of an
expression, take for instance this Haskell code:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Hello</span> <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>f (<span class="dt">Just</span> a) <span class="ot">=</span> <span class="dt">Left</span> a</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>f <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Right</span> ()</span></code></pre></div>
<p>With the cursor in the first <code>f</code> (the function name) using the <code>tt</code> mapping will
produce:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Hello</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Maybe</span> a <span class="ot">-&gt;</span> <span class="dt">Either</span> a ()</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>f (<span class="dt">Just</span> a) <span class="ot">=</span> <span class="dt">Left</span> a</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>f <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Right</span> ()</span></code></pre></div>
<p><img src="/img/vimhask/shot2.gif" /></p>
<p>Neat!, go ahead and play around with the other mappings, you won’t be
disappointed.</p>
<h3 id="hlint-integration">Hlint integration</h3>
<p>By default, <a href="https://github.com/neomake/neomake">Neomake</a> will use <em>hlint</em> on
the current file when the <code>:Neomake</code> command is invoked on a Haskell source
file, so by adding a mapping:</p>
<pre class="vim"><code>au FileType haskell nnoremap &lt;buffer&gt; gll :Neomake&lt;CR&gt;</code></pre>
<p><code>gll</code> will open the location list with the lints, which takes us to some
convenience mappings:</p>
<pre class="vim"><code>au FileType haskell nnoremap &lt;buffer&gt;&lt;silent&gt; gl&lt;space&gt; :call ToggleLocationList()&lt;CR&gt;
au FileType haskell nnoremap &lt;buffer&gt;&lt;silent&gt; glc :sign unplace *&lt;CR&gt;</code></pre>
<p>So now is possible to toggle the location list with <code>gl&lt;space&gt;</code> and clear it
with <code>glc</code>.</p>
<p>You will need the Stack tool of course, and <em>hlint</em> that you can install with
<code>stack install hlint</code>.</p>
<h3 id="code-formatting-and-beautifying">Code formatting and beautifying</h3>
<p><em>Hindent</em> allows beautifying Haskell code, you could use it by setting the
<code>formatprg</code> option and then trigger it with the <code>=</code> command, but there is a
problem: if your code happens to have any syntax errors, it will be replaced
with a nasty error message. To handle this we’re going to use the
<a href="https://github.com/alx741/vim-hindent">vim-hindent</a> plugin instead, so each
time we save a Haskell source file it will be automatically beatified.</p>
<p>Don’t forget to configure it:</p>
<pre class="vim"><code>let g:hindent_on_save = 1
let g:hindent_line_length = 80
let g:hindent_indent_size = 4</code></pre>
<p>One extra thing left is to align stuff in the code so it looks nicer</p>
<pre class="vim"><code>au FileType haskell nmap &lt;silent&gt;&lt;buffer&gt; g&lt;space&gt; vii&lt;ESC&gt;:silent!&#39;&lt;,&#39;&gt; EasyAlign /-&gt;/&lt;CR&gt;</code></pre>
<p>Take for instance this simple example for the sake of the argument:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Test</span> <span class="kw">where</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>f x <span class="ot">=</span> <span class="kw">case</span> x <span class="kw">of</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span>   <span class="ot">-&gt;</span> <span class="st">&quot;1&quot;</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span> <span class="ot">-&gt;</span>   <span class="st">&quot;2&quot;</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> <span class="ot">-&gt;</span> <span class="st">&quot;3&quot;</span></span></code></pre></div>
<p>Using <code>g&lt;space&gt;</code> we got:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Test</span> <span class="kw">where</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>f x <span class="ot">=</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">case</span> x <span class="kw">of</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span> <span class="ot">-&gt;</span> <span class="st">&quot;1&quot;</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    <span class="dv">2</span> <span class="ot">-&gt;</span> <span class="st">&quot;2&quot;</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>    <span class="dv">3</span> <span class="ot">-&gt;</span> <span class="st">&quot;3&quot;</span></span></code></pre></div>
<p><img src="/img/vimhask/shot3.gif" /></p>
<p>So much better!</p>
<h3 id="easy-arrows-generation">Easy arrows generation</h3>
<p>In Haskell, operators like <code>-&gt;</code> and <code>=&gt;</code> are very common, and I find it
cumbersome to type them manually. Let’s define a function:</p>
<pre class="vim"><code>function! Make_arrow(type)
    if a:type
        if (matchstr(getline(&#39;.&#39;), &#39;\%&#39; . col(&#39;.&#39;) . &#39;c.&#39;) ==? &#39; &#39;)
            exe &quot;norm! a-&gt;  &quot;
        else
            exe &quot;norm! a -&gt;  &quot;
        endif
        exe &quot;startreplace&quot;
    else
        if (matchstr(getline(&#39;.&#39;), &#39;\%&#39; . col(&#39;.&#39;) . &#39;c.&#39;) ==? &#39; &#39;)
            exe &quot;norm! a=&gt;  &quot;
        else
            exe &quot;norm! a =&gt;  &quot;
        endif
        exe &quot;startreplace&quot;
    endif
endfunction</code></pre>
<p>And some insert mode mappings:</p>
<pre class="vim"><code>au FileType haskell inoremap &lt;buffer&gt; ;; &lt;ESC&gt;:call Make_arrow(1)&lt;CR&gt;
au FileType haskell inoremap &lt;buffer&gt; ;: &lt;ESC&gt;:call Make_arrow(0)&lt;CR&gt;</code></pre>
<p>So while in insert mode typing <code>;;</code> or <code>;:</code> will insert <code>-&gt;</code> or <code>=&gt;</code>
respectively. Additionally, it will avoid duplicated spaces between the types
and the arrows.</p>
<h3 id="types-abbreviations">Types abbreviations</h3>
<p>Maybe I’m a terrible typist, but writing the first upper case letter of the most
common types hurts my pinkie. So by using some insert mode abbreviations:</p>
<pre class="vim"><code>au FileType haskell inoreab &lt;buffer&gt; int Int
au FileType haskell inoreab &lt;buffer&gt; integer Integer
au FileType haskell inoreab &lt;buffer&gt; string String
au FileType haskell inoreab &lt;buffer&gt; double Double
au FileType haskell inoreab &lt;buffer&gt; float Float
au FileType haskell inoreab &lt;buffer&gt; true True
au FileType haskell inoreab &lt;buffer&gt; false False
au FileType haskell inoreab &lt;buffer&gt; maybe Maybe
au FileType haskell inoreab &lt;buffer&gt; just Just
au FileType haskell inoreab &lt;buffer&gt; nothing Nothing
au FileType haskell inoreab &lt;buffer&gt; io IO ()</code></pre>
<p>Now I can type all lower case without having to bother with the <em>shift</em> key and
the capitalized version will be inserted instead.</p>
<h3 id="yesod-haskell-web-framework">Yesod Haskell web framework</h3>
<p>Some neat integration with Yesod can be achieved by using the
<a href="https://github.com/alx741/vim-yesod">vim-yesod</a> plugin which, by default, it
gives you some mappings:</p>
<p><code>gh</code> - Jump to the handler of the route under the cursor in the <code>config/routes</code>
file.</p>
<p><code>gH</code> - Create a new handler for the route under the cursor in the
<code>config/routes</code> file.</p>
<p><code>gm</code> - Jump to or create the i18n message under the cursor in a template file.</p>
<p><em>vim-yesod</em> gives you <code>config/routes</code>, <code>config/models</code> and i18n <code>messages/</code>
syntax highlighting, but it doesn’t support shakesperean templates syntax so be
sure to install the
<a href="https://github.com/pbrisbin/vim-syntax-shakespeare">vim-syntax-shakespeare</a> as
well.</p>]]></summary>
</entry>
<entry>
    <title>PIC16F876A conversión analógica digital + UART (Ensamblador)</title>
    <link href="http://www.sillybytes.net/2016/07/pic16f876a-conversion-analogica-digital.html" />
    <id>http://www.sillybytes.net/2016/07/pic16f876a-conversion-analogica-digital.html</id>
    <published>2016-07-14</published>
    <updated>2016-07-14T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><em>Note:</em> This post is available in Spanish only. Please use a software
translator.</p>
<p>He dejado de usar microcontroladores PIC por los motivos explicados
<a href="https://sillybytes.net/2016/06/from-pic-to-avr.html">aquí</a>, pero voy a
dedicar este post para escribir y explicar un programa sencillo escrito en
ensamblador para el <em>PIC16F876A</em>.</p>
<p>El objetivo es el siguiente:</p>
<p>Se pretende usar el microcontrolador para llevar a cabo la conversión
analógica-digital de una tensión variable (un LDR o un potenciómetro por
ejemplo) y transmitir el resultado usando la UART. Además debe ser posible
recibir por la UART un byte que debe alterar la configuración del Conversor
Análogo Digital (DAC) interno del microcontrolador para, por ejemplo, cambiar el
canal de entrada de la señal analógica o modificar la velocidad del reloj de
conversión.</p>
<!--more-->
<p>El código ha sido ensamblado con el “ensamblador de GNU” (<em>gpasm</em>) del juego de
herramientas <a href="http://gputils.sourceforge.net/">gputils</a>, pero debería ser
perfectamente compatible con las herramientas MPLAB de Microchip. En cualquier
caso, la explicación y el 99% del código debería ser útil sin modificación
alguna.</p>
<p>Este post se debería leer en paralelo junto con el <em>datasheet</em> del
microcontrolador en cuestión <em>PIC16F876A</em> que se puede encontrar aquí:
http://ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf</p>
<p>El código completo <a href="https://github.com/Silly-Bytes/pic_asm_uart-adc/blob/master/code.asm">se encuentra
aquí</a>.</p>
<h2 id="declaración-de-registros-y-variables">Declaración de registros y variables</h2>
<p>Empezamos examinando y explicando el código:</p>
<pre><code>list p=16f876A</code></pre>
<p>La primera linea le dirá al ensamblador los mapas de memoria que el enlazador
deberá usar.</p>
<pre><code>; Declaración de direcciones de memoria
; Datasheet pagina 17, figura 2-3
PORTA      EQU 0x05
PORTB      EQU 0x06
TRISA      EQU H&#39;85&#39;
TRISB      EQU H&#39;86&#39;
TRISC      EQU H&#39;87&#39;
RP0        EQU H&#39;05&#39;
RP1        EQU H&#39;06&#39;
STATUS     EQU H&#39;03&#39;
DATO       EQU H&#39;21&#39;
ADCON0     EQU H&#39;1F&#39;
ADCON1     EQU H&#39;9F&#39;
PIR1       EQU H&#39;0C&#39;
INTCON     EQU H&#39;0B&#39;
PIE1       EQU H&#39;8C&#39;
ADRESH     EQU H&#39;1E&#39;
ADRESL     EQU H&#39;9E&#39;
SPBRG      EQU H&#39;99&#39;
TXSTA      EQU H&#39;98&#39;
RCSTA      EQU H&#39;18&#39;
TXREG      EQU H&#39;19&#39;
RCREG      EQU H&#39;1A&#39;
OPTION_REG EQU H&#39;81&#39;
IRP        EQU H&#39;07&#39;</code></pre>
<p>En el <em>datasheet</em>, pagina 17, figura 2-3 se puede encontrar el mapa completo de
memoria del microcontrolador. En estas lineas declaramos los nombres y
direcciones (en hexadecimal) de los mismos, para usarlos en el código con más
facilidad. El mnemónico <code>EQU</code> asigna el nombre de la izquierda al valor de la
derecha. Para declarar un valor hexadecimal se usa el prefijo <code>0x</code>.</p>
<h2 id="inicialización-y-configuración">Inicialización y configuración</h2>
<pre><code>INIT
    org 0

    ; Selección BANCO 1
    ; Datasheet pagina 16, sección 2.2
    BSF STATUS,RP0
    BCF STATUS,RP1</code></pre>
<p>el mnemónico <code>INIT</code> es la declaración de una <em>etiqueta</em> (la misma que se puede
cambiar por cualquier palabra que se desee), es el nombre con el cual nos vamos
a referir a esta sección de código desde otras partes del programa.</p>
<p>La directiva <code>org 0</code> indica al enlazador que el código a continuación deberá ser
colocado desde la dirección <em>0</em> de la memoria de programa.</p>
<p>Las instrucciones <code>BSF STATUS,RP0</code> y <code>BCF STATUS,RP1</code> hacen un cambio al <em>banco
de memoria 1</em>. La memoria del microcontrolador está dividida en <em>bancos</em> y es
necesario <em>cambiarnos</em> al banco donde reside el registro que queremos modificar
en cada momento.</p>
<h3 id="configuración-de-los-puertos-de-entradasalida">Configuración de los puertos de entrada/salida</h3>
<pre><code>;;; Configuración de puertos IO
;;; Datasheet pagina 41
; El puerto A es de entrada
MOVLW   B&#39;00111111&#39;
MOVWF   TRISA
; El puerto B es de salida
MOVLW   B&#39;00000000&#39;
MOVWF   TRISB
; Puerto C: pin TX es salida, pin RX es entrada
MOVLW   B&#39;10001111&#39;
MOVWF   TRISC</code></pre>
<p>La instrucción <code>MOVLW</code> se usa para mover un valor literal al registro de trabajo
<code>W</code>.</p>
<p>La instrucción <code>MOVWF</code> se usa para mover el valor que se encuentra en el
registro de trabajo <code>W</code> a un registro.</p>
<p>De esta forma, para colocar un valor arbitrario en un registro es necesario
colocarlo primero en el registro de trabajo <code>W</code> usando la instrucción <code>MOVLW</code>
y luego moverlo al registro deseado con la instrucción <code>MOVWF</code>.</p>
<p>Para indicar que el valor usado es binario se usa como prefijo una <code>B</code>.</p>
<p>El <code>puerto A</code> contiene los pines del conversor ADC, por lo que se configuran
como entradas. El <code>puerto B</code> se configura como salida para, opcionalmente,
colocar LEDs que sirvan como indicadores visuales. El <code>puerto C</code> contiene los
pines <code>TX</code> y <code>RX</code> usados para la comunicación UART, de forma que se configuran
para salida y entrada respectivamente.</p>
<h3 id="configuración-del-conversor-adc">Configuración del conversor ADC</h3>
<pre><code>;;; Configuración de puerto ADC
; Todas las entradas son analógicas
; Datasheet pagina 128
MOVLW   B&#39;10000000&#39;
MOVWF   ADCON1</code></pre>
<p>La configuración del conversor ADC será recibida usando la comunicación UART,
sin embargo, es necesario configurar de antemano qué pines serán analógicos y
qué pines serán digitales. No usaremos pines digitales en este puerto, así que
se configuran todos como analógicos según la tabla de la pagina 128 del
<em>datasheet</em>.</p>
<h3 id="configuración-de-la-uart">Configuración de la UART</h3>
<p>La comunicación serial UART puede usarse para comunicar el microcontrolador con
una computadora u otro dispositivo que a su vez se puede usar para comunicar con
un teléfono inteligente. El dispositivo con el que se comunique es irrelevante
para este post y el código es el mismo en cualquier caso.</p>
<p>Nótese que los registros que se configuran se encuentran en bancos distintos con
lo cual es necesario hacer el <em>cambio de banco</em> en cada paso.</p>
<pre><code>;;; Configuración UART
; Banco 1
BSF STATUS,RP0
BCF STATUS,RP1
; 19200 Baudios
; Datasheet pagina 114, tabla 10-4
MOVLW   .12
MOVWF   SPBRG</code></pre>
<p>El registro <code>SPBRG</code> o “Generador de baudios” recibe un valor (listado en la
tabla) dependiendo de la velocidad a la cual nos queremos comunicar, de la
frecuencia a la que se use el microcontrolador y el porcentaje de error que
estamos dispuestos a tolerar en la comunicación. Dada la frecuencia de un reloj
de 4Mhz usado y la necesidad de una comunicación a 19200 Baudios, la tabla
indica usar un valor decimal de <code>12</code>. Para indicar que el valor usado es decimal
se usa como prefijo un punto <code>.</code>.</p>
<pre><code>; Registro de transmisión
MOVLW   B&#39;10100100&#39;
MOVWF   TXSTA</code></pre>
<p>El registro <code>TXSTA</code> de la pagina 111 se configura con los valores adecuados para
configurar una comunicación de 8 bits de alta velocidad, asíncrona y para
activar los mecanismos de transmisión.</p>
<pre><code>; Banco 0
BCF STATUS,RP0
BCF STATUS,RP1
; Registro de recepción
MOVLW   B&#39;10010000&#39;
MOVWF   RCSTA
BSF RCSTA,4</code></pre>
<p>El registro <code>RCSTA</code> (en el banco 0) de la pagina 112 se configura para una
comunicación de 8 bits, asíncrona y se activan los mecanismos de recepción.</p>
<h2 id="programa-principal">Programa principal</h2>
<p>El programa principal deberá esperar a que un byte para configurar el conversor
ADC llegue por la UART, tomar un valor de tensión y llevar a cabo la conversión
para finalmente transmitir el resultado por la UART, enviando primero el byte
bajo <code>ADRESL</code> y luego el byte alto <code>ADRESH</code>.</p>
<h3 id="configuración">Configuración</h3>
<pre><code>;;; Esperar primer byte de configuración
ESPERAR_CONFIG
    BTFSS   PIR1,5
    GOTO    ESPERAR_CONFIG</code></pre>
<p>El pin numero <code>5</code> del registro <code>PIR1</code> indicará que un dato ha llegado por la
UART.</p>
<p>La instrucción <code>BTFSS</code> verificará el bit numero <code>5</code> del registro <code>PIR1</code> y se
<em>saltará</em> la siguiente instrucción si el bit es igual a <code>1</code>. De esta forma
mientras no llegue el dato necesario la instrucción <code>GOTO</code> se ejecuta y el
microcontrolador se queda en un bucle, pero cuando un dato es recibido la
instrucción <code>GOTO</code> es <em>saltada</em> y el programa puede continuar.</p>
<pre><code>    ; Colocar byte recibido en la configuración ADCON0 del conversor ADC
    BCF   STATUS,RP0
    BCF   STATUS,RP1
    MOVF  RCREG,W
    MOVWF ADCON0
    ; Vaciar el bit de recepción
    BCF   PIR1,6</code></pre>
<p>El registro <code>RCREG</code> contiene el dato recibido por la UART, el cual se coloca en
el registro de trabajo <code>W</code> para luego llevarse al registro de configuración
<code>ADCON0</code> del conversor ADC. Así el conversor quedará configurado con el canal y
velocidad que se haya indicado en el dato que recibió y se puede proceder a la
conversión. Usando la instrucción <code>BCF</code> se vacía el contenido del bit numero <code>6</code>
del registro <code>PIR1</code> para indicar que hemos leído el dato recibido.</p>
<h3 id="conversión">Conversión</h3>
<pre><code>;;; Esperar tiempo de adquisición e iniciar conversión
CONVERTIR
    ; Instrucciones de espera
    NOP
    NOP
    NOP
    NOP
    NOP</code></pre>
<p>Antes de realizar la conversión es necesario esperar un tiempo para que el
microcontrolador pueda recoger el valor de tensión en el pin, acorde a la pagina
129 del <em>datasheet</em>. Se puede lograr esto usando la instrucción <code>NOP</code>, aunque
sería más adecuado usar un bucle que espere un tiempo más prudente, pero se
mantiene de esta forma por simplicidad.</p>
<pre><code>    ; Activar conversor
    BSF ADCON0,2</code></pre>
<p>Activando el bit numero <code>2</code> del registro <code>ADCON0</code> usando la instrucción <code>BSF</code>
inicia la conversión.</p>
<pre><code>ESPERAR_CONVERSION
    BTFSS   PIR1,6
    GOTO    ESPERAR_CONVERSION
    BCF PIR1,6</code></pre>
<p>La conversión toma tiempo, por lo que se entra en un bucle hasta que el bit
numero 6 del registro <code>PIR1</code> indique que se ha finalizado.</p>
<h3 id="transmitir-el-resultado">Transmitir el resultado</h3>
<pre><code>; Transmitir el resultado mediante la UART
TRANSMITIR_RESULTADO
    BSF STATUS,RP0
    BCF STATUS,RP1
    ; Transmitir byte bajo del resultado (ADRESL)
    MOVF    ADRESL,W
    BCF STATUS,RP0
    BCF STATUS,RP1
    MOVWF   TXREG
    BSF STATUS,RP0
    BCF STATUS,RP1</code></pre>
<p>El resultado de la conversión se encuentra repartido en dos bytes: <code>ADRESL</code> y
<code>ADRESH</code>.</p>
<p>Colocamos el byte <code>ADRESL</code> en el registro de trabajo <code>W</code> para luego colocarlo en
el registro <code>TXREG</code>, lo cual causará que sea transmitido usando al UART.</p>
<pre><code>; Esperar que el primer byte se transmita
ESPERAR_1
    BTFSS   TXSTA,1
    GOTO    ESPERAR_1
    BCF STATUS,RP0
    BCF STATUS,RP1
    ; Transmitir byte alto del resultado (ADRESH)
    MOVF    ADRESH,W
    MOVWF   TXREG
    BSF STATUS,RP0
    BCF STATUS,RP1

; Esperar que el segundo byte se transmita
ESPERAR_2
    BTFSS   TXSTA,1
    GOTO    ESPERAR_2
    BCF TXSTA,1</code></pre>
<p>El bit numero <code>1</code> del registro <code>TXSTA</code> indica que el dato se ha transmitido.</p>
<p>Esperamos en un bucle hasta que el byte bajo termine de ser transmitido y
podemos repetirlo para el byte alto.</p>
<pre><code>GOTO    CONVERTIR

END</code></pre>
<p>Finalmente se salta a la etiqueta <code>CONVERTIR</code> para convertir y transmitir datos
infinitamente. El programa se termina con la directiva <code>END</code>.</p>]]></summary>
</entry>
<entry>
    <title>Ratpoison, Fuzzy window selection</title>
    <link href="http://www.sillybytes.net/2016/07/ratpoison-fuzzy-window-selection.html" />
    <id>http://www.sillybytes.net/2016/07/ratpoison-fuzzy-window-selection.html</id>
    <published>2016-07-13</published>
    <updated>2016-07-13T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>A nice feature to have is the ability to jump to an arbitrary window by
performing a quick fuzzy search with just a few characters. We can achieve
this by using Ratpoison’s flexibility and the fantastic <a href="https://github.com/junegunn/fzf">FZF
tool</a>.</p>
<p>The
<a href="https://github.com/alx741/dotfiles/blob/master/scripts/.scripts/ratpoison/window_select.sh">window_select.sh</a>
script will do the trick using <strong>FZF</strong></p>
<!--more-->
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> fzf_select</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">pattern</span><span class="op">=</span><span class="va">$(</span><span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;prompt &gt; &quot;</span><span class="va">)</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$pattern</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="bu">exit</span> 0</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="va">window_list</span><span class="op">=</span><span class="va">$(</span><span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;windows %c&quot;</span><span class="va">)</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="va">selected</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$window_list</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="ex">fzf</span> <span class="at">-q</span> <span class="st">&quot;</span><span class="va">$pattern</span><span class="st">&quot;</span> <span class="at">-1</span> <span class="at">-0</span><span class="va">)</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$selected</span><span class="st">&quot;</span> <span class="ot">!=</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;select </span><span class="va">$selected</span><span class="st">&quot;</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;echo [!] There is no a matching window for </span><span class="dt">\&quot;</span><span class="va">$pattern</span><span class="dt">\&quot;</span><span class="st">&quot;</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="va">$1</span> <span class="kw">in</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;ratmen&#39;</span><span class="kw">)</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratmen_select</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;fzf&#39;</span><span class="kw">)</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>        <span class="ex">fzf_select</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="cf">esac</span></span></code></pre></div>
<p>This will use Ratpoison to prompt for a fuzzy string and will take you
immediately to the matched window.</p>
<p>In order to invoke this, a Ratpoison mapping is required:</p>
<pre><code>bind w exec window_select.sh fzf</code></pre>]]></summary>
</entry>
<entry>
    <title>Aprende Haskell rápido y difícil</title>
    <link href="http://www.sillybytes.net/2016/06/aprende-haskell-rapido-y-dificil_29.html" />
    <id>http://www.sillybytes.net/2016/06/aprende-haskell-rapido-y-dificil_29.html</id>
    <published>2016-06-29</published>
    <updated>2016-06-29T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Esta es la traducción al español del artículo <a href="http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/">“Haskell the hard
way”</a> por Yann
Esposito.</p>
<p>TL;DR*: Un corto y denso tutorial para aprender Haskell.</p>
<p>Asómbrate con Haskell. De verdad pienso que todos los desarrolladores deberían
aprender Haskell. No creo que todos necesitan convertirse en ninjas de Haskell,
pero deberían al menos descubrir que es lo que Haskell tiene para ofrecer.
Aprender Haskell abre tu mente.</p>
<!--more-->
<p><img src="/img/haskellhard/thumbnail.jpg" /></p>
<p>Los lenguajes comunes comparten los mismos fundamentos:</p>
<ul>
<li>variables</li>
<li>loops</li>
<li>punteros[^1]</li>
<li>estructuras de datos, objetos y clases</li>
</ul>
<p>Haskell es muy diferente. El lenguaje usa muchos conceptos que nunca he
escuchado antes. Muchos de esos conceptos te ayudarán a convertirte en un mejor
programador.</p>
<p>Pero aprender Haskell puede ser difícil. Lo fue para mi. En este artículo
intentaré proveer lo que me faltó durante mi aprendizaje.</p>
<p>Este artículo será ciertamente difícil de seguir. Esto es intencional. No hay
atajo alguno para aprender Haskell. Es difícil y retador. Pero creo que es algo
bueno. Debido a que es difícil es que Haskell es interesante.</p>
<p>El método convencional de aprender Haskell es leer dos libros. Primero <a href="http://learnyouahaskell.com/">“Learn
You a Haskell”</a> y justo después <a href="http://www.realworldhaskell.org/">“Real World
Haskell”</a>. También pienso que esta es la forma
correcta. Pero aprender de que se trata Haskell, deberás leerlos en detalle.</p>
<p>En contraste, este artículo es un resumen muy breve y denso de los principales
aspectos de Haskell. También he agregado información que a mi me faltó mientras
aprendía Haskell.</p>
<p>El artículo contiene cinco partes:</p>
<ul>
<li>Introducción: un corto ejemplo para mostrar que Haskell puede ser amigable.</li>
<li>Haskell básico: sintaxis de Haskell, y algunas nociones esenciales.</li>
<li>Parte muy difícil:
<ul>
<li>Estilo funcional; un ejemplo progresivo, desde estilo imperativo al</li>
<li>funcional</li>
<li>Tipos; tipos y el ejemplo estándar del árbol binario</li>
<li>Estructuras infinitas; manipulando un árbol binario infinito!</li>
</ul></li>
<li>Parte infernalmente difícil:
<ul>
<li>Lidiar con IO; un ejemplo reducido</li>
<li>El truco de IO explicado; el detalle ocultó que yo no tuve para entender
IO</li>
<li>Monads; increíble como podemos generalizar</li>
</ul></li>
<li>Apéndice:
<ul>
<li>Más sobre arboles infinitos; una discusión más matemática sobre arboles</li>
<li>infinitos</li>
</ul>
Nota: El código de ejemplo se almacena en ficheros con un nombre
específico que termina en la extensión <code>.hs</code> (Haskell), y por eso en los
ejemplos se escribe la ejecución de los mismos como <code>$ runhaskell   algo.hs</code> pero el nombre puede ser cualquiera.</li>
</ul>
<h1 id="introducción">Introducción</h1>
<h2 id="instalación">Instalación</h2>
<p><img src="/img/haskellhard/shot1.jpg" /></p>
<ul>
<li><a href="https://www.haskell.org/platform/">La plataforma de Haskell</a> es la forma
estándar de instalar Haskell.</li>
</ul>
<p>Herramientas:</p>
<p><code>ghc</code>: Compilador similar a <em>gcc</em> para <code>C</code>.
<code>ghci</code>: Haskell interactivo (REPL)
<code>runhaskell</code>: Ejecutar un programa sin compilarlo. Conveniente pero muy lento
comparado a programas compilados</p>
<h2 id="no-tengas-miedo">No tengas miedo</h2>
<p><img src="/img/haskellhard/shot2.jpg" /></p>
<p>Muchos libros/artículos sobre Haskell empiezan por introducir alguna formula
esotérica (quick sort, Fibonacci, etc…). Yo lo haré justamente al revés. Al
principio no mostraré ningún super poder de Haskell. Empezaré por las
similaridades entre Haskell y otros lenguajes de programación. Saltemos al “Hola
Mundo” obligatorio.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">putStrLn</span> <span class="st">&quot;Hola Mundo!&quot;</span></span></code></pre></div>
<p>Para ejecutarlo, puedes guardar el código en un fichero <code>hola.hs</code> y:</p>
<pre><code>$ runhaskell ./hola.hs
Hola Mundo!</code></pre>
<p>Ahora, un programa que pregunte tu nombre y responda “Hola” usando el nombre
ingresado:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">print</span> <span class="st">&quot;Cuál es tu nombre?&quot;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    name <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">print</span> (<span class="st">&quot;Hola &quot;</span> <span class="op">++</span> name <span class="op">++</span> <span class="st">&quot;!&quot;</span>)</span></code></pre></div>
<p>Primero, comparemos esto con programas similares en algunos lenguajes
imperativos:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Python</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span> <span class="st">&quot;What is your name?&quot;</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>name <span class="op">=</span> <span class="bu">raw_input</span>()</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span> <span class="st">&quot;Hello </span><span class="sc">%s</span><span class="st">!&quot;</span> <span class="op">%</span> name</span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Ruby</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">puts</span> <span class="st">&quot;What is your name?&quot;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>name <span class="kw">=</span> <span class="fu">gets</span><span class="at">.chomp</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="fu">puts</span> <span class="st">&quot;Hello </span><span class="sc">#{</span>name<span class="sc">}</span><span class="st">!&quot;</span></span></code></pre></div>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">// In C</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;stdio.h&gt;</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main <span class="op">(</span><span class="dt">int</span> argc<span class="op">,</span> <span class="dt">char</span> <span class="op">**</span>argv<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">char</span> name<span class="op">[</span><span class="dv">666</span><span class="op">];</span> <span class="co">// &lt;- An Evil Number!</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// What if my name is more than 665 character long?</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    printf<span class="op">(</span><span class="st">&quot;What is your name?</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">);</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    scanf<span class="op">(</span><span class="st">&quot;</span><span class="sc">%s</span><span class="st">&quot;</span><span class="op">,</span> name<span class="op">);</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    printf<span class="op">(</span><span class="st">&quot;Hello </span><span class="sc">%s</span><span class="st">!</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> name<span class="op">);</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>La estructura es la misma, pero hay diferencias en la sintaxis. La parte
principal de este tutorial será dedicada a explicar por qué.</p>
<p>En Haskell hay una función <code>main</code> y todo elemento tiene un tipo. El tipo de
<code>main</code> es <code>IO ()</code>. Esto significa que <code>main</code> causará efectos
secundarios.</p>
<p>Solamente recuerda que Haskell puede lucir mucho como los lenguajes
imperativos populares.</p>
<h2 id="haskell-básico">Haskell básico</h2>
<p><img src="/img/haskellhard/shot3.jpg" /></p>
<p>Antes de continuar debes ser advertido sobre algunas propiedades
esenciales de Haskell.</p>
<p><strong>Funcional</strong></p>
<p>Haskell es un lenguaje funcional. Si tienes experiencia con lenguajes
imperativos, deberás aprender muchas cosas nuevas. Con suerte muchos de estos
nuevos conceptos te ayudarán a programas incluso en lenguajes
imperativos.</p>
<p><strong>Tipado estático inteligente</strong></p>
<p>En lugar de meterse en tu camino como en <code>C</code>, <code>C++</code> o <code>Java</code>, el sistema de
tipos está aquí para ayudarte.</p>
<p><strong>Pureza</strong></p>
<p>Generalmente tus funciones no modificarán nada en el mundo exterior. Esto
significa que no pueden modificar el valor de una variable, no pueden obtener
entrada del usuario, no pueden escribir en la pantalla, no pueden lanzar un
misil. Por otro lado, el paralelismo será muy fácil de lograr. Haskell
hace deja claro donde los efectos secundarios pueden ocurrir y donde el código
es puro. También, será mucho más fácil razonar sobre el programa. La mayoría de
los errores serán prevenidos en las partes puras del programa.</p>
<p>Además, las funciones puras siguen una ley fundamental en Haskell:</p>
<pre><code>Aplicar una funcion con los mismos parámetros siempre producirá los
mismos valores.</code></pre>
<p><strong>Perezoso (laziness)</strong></p>
<p>Laziness por defecto es un diseño de lenguaje muy poco común. Por defecto,
Haskell evalúa algo solamente cuando lo necesita. En consecuencia, provee una
forma muy elegante de manipular estructuras infinitas, por ejemplo.</p>
<p>Una ultima advertencia sobre como deberías leer código Haskell. Para mi, es
como leer artículos científicos. Algunas partes son muy claras, pero cuando vez
una formula, enfócate y lee más despacio. También, mientras se lee código
Haskell, en realidad no importa mucho si no se comprenden los detalles
de la sintaxis. Si encuentras algo como <code>&gt;&gt;=</code>, <code>&lt;$&gt;</code>, <code>&lt;-</code> o cualquier
símbolo extraño, solamente ignóralos y continua el flujo del código.</p>
<h3 id="declaración-de-funciones">Declaración de funciones</h3>
<p>Seguramente estarás acostumbrado a funciones como:</p>
<p>En <code>C</code>:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> f<span class="op">(</span><span class="dt">int</span> x<span class="op">,</span> <span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y<span class="op">;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>En <code>JavaScript</code>:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">f</span>(x<span class="op">,</span>y) {</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y<span class="op">;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>En Python:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> f(x,y):</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span></code></pre></div>
<p>En Ruby:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="cf">def</span> f(x,y)</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    x<span class="kw">*</span>x <span class="kw">+</span> y<span class="kw">*</span>y</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="cf">end</span></span></code></pre></div>
<p>En Scheme:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode scheme"><code class="sourceCode scheme"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>(<span class="ex">define</span><span class="fu"> </span>(f x y)</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    (<span class="op">+</span> (<span class="op">*</span> x x) (<span class="op">*</span> y y)))</span></code></pre></div>
<p>Finalmente, en Haskell es:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span></code></pre></div>
<p>Muy limpio. No paréntesis, no <code>def.</code></p>
<p>No olvides, Haskell usa funciones y tipos un montón. Por lo que es muy fácil
definirlos. La sintaxis fuer particularmente pensada para estos elementos.</p>
<h3 id="un-ejemplo-de-tipo">Un ejemplo de tipo</h3>
<p>Aunque no es obligatorio, la información sobre los tipos para las funciones
usualmente se hace explicita. No es obligatorio por que el compilador es lo
bastante inteligente para descubrirlo por ti. Es una buena idea hacerlo de
todas formas por que indica la intensión y facilita la comprensión.</p>
<p>Juguemos un poco. Declaramos el tipo usando <code>::</code></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> (f <span class="dv">2</span> <span class="dv">3</span>)</span></code></pre></div>
<pre><code>$ runhaskell 20_very_basic.lhs
13</code></pre>
<p>Ahora intenta</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> (f <span class="fl">2.3</span> <span class="fl">4.2</span>)</span></code></pre></div>
<p>Deberías obtener este error:</p>
<pre><code>21_very_basic.lhs:6:23:
    No instance for (Fractional Int)
    arising from the literal `4.2&#39;
    Possible fix: add an instance declaration for (Fractional Int)
    In the second argument of `f&#39;, namely `4.2&#39;
    In the first argument of `print&#39;, namely `(f 2.3 4.2)&#39;
    In the expression: print (f 2.3 4.2)</code></pre>
<p>El problema: 4.2 no es un <code>Int</code>.</p>
<p>La solución: No declarar un tipo para <code>f</code> por el momento y dejar a Haskell
inferir el tipo más general por nosotros:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> (f <span class="fl">2.3</span> <span class="fl">4.2</span>)</span></code></pre></div>
<p>Funciona! Afortunadamente, no tenemos que declarar una nueva función para cada
tipo. Por ejemplo, in <code>C</code>, deberíamos declarar una función para <code>int</code>,
para <code>float</code> para <code>long</code>, para <code>double</code>, etc…</p>
<p>Pero, que tipo deberíamos declarar? Para descubrir el tipo que Haskell a
usado por nosotros ejecutaremos <strong>ghci</strong>:</p>
<pre><code>% ghci

GHCi, version 7.0.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude&gt;</code></pre>
<p>Y escribimos:</p>
<pre><code>let f x y = x*x + y*y
Prelude&gt;
:type f
f :: Num a =&gt; a -&gt; a -&gt; a</code></pre>
<p>Uh? Que es ese tipo extraño?</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>Primero, enfoquémonos en la parte de la derecha <code>a -&gt; a -&gt; a</code>. Para
comprenderlo, solo mira una lista de ejemplos progresivos:</p>
<table>
<thead>
<tr>
<th>El tipo</th>
<th>Su significado</th>
</tr>
</thead>
<tbody>
<tr>
<td>Int</td>
<td>El tipo Int</td>
</tr>
<tr>
<td>Int -&gt; Int</td>
<td>El tipo de función de Int a Int</td>
</tr>
<tr>
<td>Float -&gt; Int</td>
<td>El tipo de función de Float a Int</td>
</tr>
<tr>
<td>a -&gt; Int</td>
<td>El tipo de función de cualquier tipo a Int</td>
</tr>
<tr>
<td>a -&gt; a</td>
<td>El tipo de función de cualquier tipo al mismo tipo a</td>
</tr>
<tr>
<td>a -&gt; a -&gt; a</td>
<td>El tipo de función de dos argumentos de cualquier tipo a al</td>
</tr>
<tr>
<td>mismo tipo a</td>
<td></td>
</tr>
</tbody>
</table>
<p>En el tipo <code>a -&gt; a -&gt; a</code>, la letra <code>a</code> es una <em>variable de tipo</em>. Significa que
<code>f</code> es una función con dos argumentos y esos dos argumentos y el resultado
tienen que ser del mismo tipo, La variable de tipo <code>a</code> puede ser cualquier tipo.
Por ejemplo <code>Int</code>, <code>Integer</code>, <code>Float</code>…</p>
<p>Así que en lugar de forzar un tipo en particular como en <code>C</code> y tener que
declarar una función para <code>int</code>, <code>long</code>, <code>float</code>, <code>double</code>, etc., podemos
declarar una sola función como en un lenguaje de tipado dinámico.</p>
<p>Esto es algunas veces llamado polimorfismo paramétrico.</p>
<p>Generalmente <code>a</code> puede ser cualquier tipo, por ejemplo un <code>String</code> a un <code>Int</code>,
pero también puede ser tipos más complejos, como <code>Trees</code>, otras funciones,
etc. Pero en este caso nuestro tipo tiene como prefijo <code>Num a =&gt;</code>.</p>
<p><code>Num</code> es una <em>clase de tipo</em> (type class). Una clase de tipo puede ser vista
como un conjunto de tipos. <code>Num</code> contiene solamente los tipos que pueden
comportarse como números. Más concretamente, <code>Num</code> es una clase que contiene
tipos que implementan una lista especifica de funciones, en particular
<code>(+)</code> y <code>(*)</code>.</p>
<p>Las clases de tipos son un aspecto muy potente del lenguaje. Podemos hacer
cosas increíbles con esto. Más sobre el tema luego.</p>
<p>Finalmente, <code>Num a =&gt; a -&gt; a -&gt; a</code> significa:</p>
<p>Sea <code>a</code> un tipo que pertenece a la clase de tipo <code>Num</code>. Esto es una función de
tipo <code>a</code> a (<code>a -&gt; a</code>).</p>
<p>Si, extraño. De hecho, en Haskell ninguna función tiene dos argumentos.
En lugar de eso todas las funciones pueden tener un solo argumento. Pero
notaremos que tomar dos argumentos es equivalente a tomar un argumento
y retornar una función que toma el segundo argumento como parámetro.</p>
<p>Más concretamente <code>f 3 4</code> es equivalente a <code>(f 3) 4</code>. Nótese que <code>f 3</code> es una
función:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="ot">g ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>g <span class="ot">=</span> f <span class="dv">3</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>g y ⇔ <span class="dv">3</span><span class="op">*</span><span class="dv">3</span> <span class="op">+</span> y<span class="op">*</span>y</span></code></pre></div>
<p>Existe otra notación para funciones. La notación <em>lambda</em> nos permite crear
funciones sin asignarles un nombre. Llamamos a estas funciones anónimas.
Podemos escribirlas como:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>g <span class="ot">=</span> \y <span class="ot">-&gt;</span> <span class="dv">3</span><span class="op">*</span><span class="dv">3</span> <span class="op">+</span> y<span class="op">*</span>y</span></code></pre></div>
<p>El <code>\\</code> es usado por que se parece a <code>λ</code> (símbolo lambda) y es ASCII.</p>
<p>Si no estás acostumbrado a la programación funcional tu cerebro debería
estar empezando a calentarse. Es tiempo de hacer una aplicación real.</p>
<p>Pero antes de eso, deberíamos verificar que el sistema de tipos funciona
según lo esperado.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> (f <span class="dv">3</span> <span class="fl">2.4</span>)</span></code></pre></div>
<p>Funciona, porque, <code>3</code> es una representación valida para números
fraccionarios como <code>Float</code> así como para <code>Integer</code>. Como <code>2.4</code> es una numero
fraccionario, <code>3</code> es interpretado también como un numero fraccionario.</p>
<p>Si forzamos nuestra función a trabajar con tipos diferentes, fallará.</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>f x y <span class="ot">=</span> x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a><span class="ot">x ::</span> <span class="dt">Int</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>x <span class="ot">=</span> <span class="dv">3</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="ot">y ::</span> <span class="dt">Float</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>y <span class="ot">=</span> <span class="fl">2.4</span></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- No funcionará por que el tipo x ≠ tipo y</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> (f x y)</span></code></pre></div>
<p>El compilador se queja. Los dos parámetros deben ser del mismo tipo.</p>
<p>Si piensas que esto es una mala idea, y que el compilador debería hacer la
transformación de un tipo al otro por ti, deberías ver este fantástico
(y divertido) vídeo: <a href="https://www.destroyallsoftware.com/talks/wat">WAT</a></p>
<h1 id="haskell-esencial">Haskell esencial</h1>
<p><img src="/img/haskellhard/shot4.jpg" /></p>
<p>Sugiero que leas con ligereza esta parte. Mírala como una referencia. Haskell
tiene un montón de características. Regresa aquí cada vez que la notación
te parezca extraña.</p>
<p>Uso el símbolo <code>⇔</code> para indicar que dos expresiones son equivalentes. Es una
meta notación, <code>⇔</code> no existe en Haskell. También usaré <code>⇒</code> para indicar
cual es el valor de retorno de una expresión.</p>
<h2 id="notaciones">Notaciones</h2>
<p><strong>Aritmética</strong></p>
<pre><code>3 + 2 * 6 / 3 ⇔ 3 + ((2*6)/3)</code></pre>
<p><strong>Lógica</strong></p>
<pre><code>True || False ⇒ True
True &amp;&amp; False ⇒ False
True == False ⇒ False
True /= False ⇒ True  (/=) es el operador diferencia</code></pre>
<p><strong>Potencias</strong></p>
<pre><code>x^n     para un n entero (Int o Integer)
x**y    para cualquier tipo de numero y (como un Float)</code></pre>
<p><code>Integer</code> no tiene ningún limite además de la capacidad de tu máquina.</p>
<pre><code>4^103
102844034832575377634685573909834406561420991602098741459288064</code></pre>
<p>Si! También hay números racionales! Pero hay que importar el modulo
<code>Data.Ratio</code>:</p>
<pre><code>$ ghci
....
Prelude&gt; :m Data.Ratio
Data.Ratio&gt; (11 % 15) * (5 % 3)
11 % 9</code></pre>
<p><strong>Listas</strong></p>
<pre><code>[]                      ⇔ Lista vacia
[1,2,3]                 ⇔ Lista de enteros
[&quot;foo&quot;,&quot;bar&quot;,&quot;baz&quot;]     ⇔ Lista de cadenas
1:[2,3]                 ⇔ [1,2,3], (:) anteponer un elemento
1:2:[]                  ⇔ [1,2]
[1,2] ++ [3,4]          ⇔ [1,2,3,4], (++) concatenar
[1,2,3] ++ [&quot;foo&quot;]      ⇔ ERROR String ≠ Integral
[1..4]                  ⇔ [1,2,3,4]
[1,3..10]               ⇔ [1,3,5,7,9]
[2,3,5,7,11..100]       ⇔ ERROR! No soy tan inteligente!
[10,9..1]               ⇔ [10,9,8,7,6,5,4,3,2,1]</code></pre>
<p><strong>Cadenas</strong></p>
<p>En Haskell las cadenas son listas de <code>Char</code>.</p>
<pre><code>&#39;a&#39; :: Char
&quot;a&quot; :: [Char]
&quot;&quot;  ⇔ []
&quot;ab&quot; ⇔ [&#39;a&#39;,&#39;b&#39;] ⇔  &#39;a&#39;:&quot;b&quot; ⇔ &#39;a&#39;:[&#39;b&#39;] ⇔ &#39;a&#39;:&#39;b&#39;:[]
&quot;abc&quot; ⇔ &quot;ab&quot;++&quot;c&quot;


En código real no se debería usar una lista de `Char` para
representar texto. Se debería usar `Data.Text`. Si quieres
representar un flujo de caracteres ASCII, deberías usar
`Data.ByteString`.</code></pre>
<p><strong>Tuplas</strong></p>
<p>El tipo de una tupla es <code>(a,b)</code>. Los elementos dentro de una tupla pueden
tener diferentes tipos.</p>
<pre><code>-- Todas estas tuplas son validas
(2,&quot;foo&quot;)
(3,&#39;a&#39;,[2,3])
((2,&quot;a&quot;),&quot;c&quot;,3)

fst (x,y)       ⇒  x
snd (x,y)       ⇒  y

fst (x,y,z)     ⇒  ERROR: fst :: (a,b) -&gt; a
snd (x,y,z)     ⇒  ERROR: snd :: (a,b) -&gt; b</code></pre>
<p><strong>Controlar los paréntesis</strong></p>
<p>Para remover algunos paréntesis se pueden usar dos funciones: <code>($)</code> y <code>(.)</code>.</p>
<pre><code>-- Por defecto:
f g h x         ⇔  (((f g) h) x)

-- el $ reemplaza los paréntessis desde el $
-- hasta el final de la expresión
f g $ h x       ⇔  f g (h x) ⇔ (f g) (h x)
f $ g h x       ⇔  f (g h x) ⇔ f ((g h) x)
f $ g $ h x     ⇔  f (g (h x))

-- (.) composición de funciones
(f . g) x       ⇔  f (g x)
(f . g . h) x   ⇔  f (g (h x))</code></pre>
<h2 id="notaciones-útiles-para-funciones">Notaciones útiles para funciones</h2>
<p>Solo un recordatorio:</p>
<pre><code>x :: Int            ⇔ x es de tipo Int
x :: a              ⇔ x puede ser de cualquier tipo
x :: Num a =&gt; a     ⇔ x puede ser cualquier tipo a
                    que pertenezca a la class de typo Num
f :: a -&gt; b         ⇔ f es una función de a hacia b
f :: a -&gt; b -&gt; c    ⇔ f es una función de a hacia (b→c)
f :: (a -&gt; b) -&gt; c  ⇔ f es una función de (a→b) hacia c</code></pre>
<p>Recuerda que definir el tipo de una función antes de su declaración no es
obligatorio. Haskell infiere el tipo más general por ti. Pero es
considerado una buena practica hacerlo de todos modos.</p>
<p><strong>Notación infijo</strong></p>
<div class="sourceCode" id="cb36"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ot">square ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>square x <span class="ot">=</span> x<span class="op">^</span><span class="dv">2</span></span></code></pre></div>
<p>Nótese que <code>^</code> usa notación infijo. Para cada operador infijo hay una notación
prefijo asociada. Solo debe ponerse entre paréntesis.</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>square&#39; x <span class="ot">=</span> (<span class="op">^</span>) x <span class="dv">2</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>square&#39;&#39; x <span class="ot">=</span> (<span class="op">^</span><span class="dv">2</span>) x</span></code></pre></div>
<p>Podemos remover <code>x</code> en el lado izquierdo y derecho!
Eso se llama reducción η.</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a>square&#39;&#39;&#39; <span class="ot">=</span> (<span class="op">^</span><span class="dv">2</span>)</span></code></pre></div>
<p>Nótese que podemos declarar funciones con un <code>'</code> en su nombre:</p>
<pre><code>square ⇔ square&#39; ⇔ square&#39;&#39; ⇔ square&#39;&#39;&#39;</code></pre>
<p><strong>Tests</strong></p>
<div class="sourceCode" id="cb40"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="ot">absolute ::</span> (<span class="dt">Ord</span> a, <span class="dt">Num</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>absolute x <span class="ot">=</span> <span class="kw">if</span> x <span class="op">&gt;=</span> <span class="dv">0</span> <span class="kw">then</span> x <span class="kw">else</span> <span class="op">-</span>x</span></code></pre></div>
<p>Nota: el <code>if .. then .. else</code> en Haskell es como el <code>algo ? algo : algo</code> en C.
No puedes olvidar el <code>else</code></p>
<p>Otra versión equivalente:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a>absolute&#39; x</span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> x <span class="op">&gt;=</span> <span class="dv">0</span> <span class="ot">=</span> x</span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="op">-</span>x</span></code></pre></div>
<pre><code>Advertencia: la indentación es importante en Haskell. Como en
Python, una mala indentación pueden dañar el código!</code></pre>
<h1 id="parte-difícil">Parte difícil</h1>
<p>La parte difícil puede empezar ahora.</p>
<h2 id="estilo-funcional">Estilo funcional</h2>
<p><img src="/img/haskellhard/shot5.jpg" /></p>
<p>En esta sección, proporcionaré un ejemplo corto de la impresionante habilidad
para refactorizar de Haskell. Seleccionaremos un problema y los resolveremos en
la forma imperativa estándar. Luego desarrollaremos el código. Al final el
resultado será más elegante y más sencillo de adaptar.</p>
<p>Solucionemos el siguiente problema:</p>
<pre><code>Dada una lista de enteros, retornar la suma de numeros pares en la lita.
ejemplo: `[1,2,3,4,5] ⇒ 2 + 4 ⇒ 6`</code></pre>
<p>Para mostrar las diferencias entre los enfoques funcional e imperativo, Empezaré
con la solución imperativa (en JavaScript):</p>
<div class="sourceCode" id="cb44"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">evenSum</span>(list) {</span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> result <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> (<span class="kw">var</span> i<span class="op">=</span><span class="dv">0</span><span class="op">;</span> i<span class="op">&lt;</span> list<span class="op">.</span><span class="at">length</span> <span class="op">;</span> i<span class="op">++</span>) {</span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> (list[i] <span class="op">%</span> <span class="dv">2</span> <span class="op">==</span><span class="dv">0</span>) {</span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a>            result <span class="op">+=</span> list[i]<span class="op">;</span></span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result<span class="op">;</span></span>
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>En Haskell, en contraste, no tenemos variables ni un loop <code>for</code>. Una solución
para lograr el mismo resultado sin loops es usando recursión.</p>
<pre><code>Nota: La recursión es generalmente persivida como lenta en los lengajes
imperativos. Pero generalmente no es el caso en la programación funcional.
La mayor parte del tiempo Haskell manejará funciones recursivas de forma
eficiente.</code></pre>
<p>Aquí esta la versión en <code>C</code> de la función recursiva. Por simplicidad asumí que
la lista de <code>int</code> termina con el primer valor de <code>0</code>.</p>
<div class="sourceCode" id="cb46"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> evenSum<span class="op">(</span><span class="dt">int</span> <span class="op">*</span>list<span class="op">)</span> <span class="op">{</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> accumSum<span class="op">(</span><span class="dv">0</span><span class="op">,</span>list<span class="op">);</span></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> accumSum<span class="op">(</span><span class="dt">int</span> n<span class="op">,</span> <span class="dt">int</span> <span class="op">*</span>list<span class="op">)</span> <span class="op">{</span></span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> x<span class="op">;</span></span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="op">*</span>xs<span class="op">;</span></span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(*</span>list <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span> <span class="co">// si la lista está vacia</span></span>
<span id="cb46-9"><a href="#cb46-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> n<span class="op">;</span></span>
<span id="cb46-10"><a href="#cb46-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb46-11"><a href="#cb46-11" aria-hidden="true" tabindex="-1"></a>        x <span class="op">=</span> list<span class="op">[</span><span class="dv">0</span><span class="op">];</span> <span class="co">// x es el primer elemento de la lista</span></span>
<span id="cb46-12"><a href="#cb46-12" aria-hidden="true" tabindex="-1"></a>        xs <span class="op">=</span> list<span class="op">+</span><span class="dv">1</span><span class="op">;</span> <span class="co">// xs es la lista sin el elemento x</span></span>
<span id="cb46-13"><a href="#cb46-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span> <span class="dv">0</span> <span class="op">==</span> <span class="op">(</span>x<span class="op">%</span><span class="dv">2</span><span class="op">)</span> <span class="op">)</span> <span class="op">{</span> <span class="co">// si x es par</span></span>
<span id="cb46-14"><a href="#cb46-14" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> accumSum<span class="op">(</span>n<span class="op">+</span>x<span class="op">,</span> xs<span class="op">);</span></span>
<span id="cb46-15"><a href="#cb46-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb46-16"><a href="#cb46-16" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> accumSum<span class="op">(</span>n<span class="op">,</span> xs<span class="op">);</span></span>
<span id="cb46-17"><a href="#cb46-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb46-18"><a href="#cb46-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb46-19"><a href="#cb46-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Mantén este código en mente. Lo vamos a traducir a Haskell. Sin embargo, vamos a
necesitar primero introducir tres simples pero útiles funciones que usaremos:</p>
<div class="sourceCode" id="cb47"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="fu">even</span><span class="ot"> ::</span> <span class="dt">Integrall</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a><span class="fu">tail</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [a]</span></code></pre></div>
<p><code>even</code> verifica si un numero es par.</p>
<div class="sourceCode" id="cb48"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="fu">even</span><span class="ot"> ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a><span class="fu">even</span> <span class="dv">3</span>  ⇒ <span class="dt">False</span></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a><span class="fu">even</span> <span class="dv">2</span>  ⇒ <span class="dt">True</span></span></code></pre></div>
<p><code>head</code> retorna el primer elemento de la lista:</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>] ⇒ <span class="dv">1</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span> []      ⇒ <span class="dt">ERROR</span></span></code></pre></div>
<p><code>tail</code> retorna todos los elementos de la lista, excepto el primero:</p>
<div class="sourceCode" id="cb50"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="fu">tail</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a><span class="fu">tail</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>] ⇒ [<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a><span class="fu">tail</span> [<span class="dv">3</span>]     ⇒ []</span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true" tabindex="-1"></a><span class="fu">tail</span> []      ⇒ <span class="dt">ERROR</span></span></code></pre></div>
<p>Nótese que para cualquier lista no vacía <code>l</code>, <code>l ⇔ (head l):(tail l)</code></p>
<p>La primera solución en Haskell. La función <code>evenSum</code> retorna la suma de todos
los números pares en la lista:</p>
<div class="sourceCode" id="cb51"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 1</span></span>
<span id="cb51-2"><a href="#cb51-2" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb51-3"><a href="#cb51-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-4"><a href="#cb51-4" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> accumSum <span class="dv">0</span> l</span>
<span id="cb51-5"><a href="#cb51-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-6"><a href="#cb51-6" aria-hidden="true" tabindex="-1"></a>accumSum n l <span class="ot">=</span> <span class="kw">if</span> l <span class="op">==</span> []</span>
<span id="cb51-7"><a href="#cb51-7" aria-hidden="true" tabindex="-1"></a>                  <span class="kw">then</span> n</span>
<span id="cb51-8"><a href="#cb51-8" aria-hidden="true" tabindex="-1"></a>                  <span class="kw">else</span> <span class="kw">let</span> x <span class="ot">=</span> <span class="fu">head</span> l</span>
<span id="cb51-9"><a href="#cb51-9" aria-hidden="true" tabindex="-1"></a>                           xs <span class="ot">=</span> <span class="fu">tail</span> l</span>
<span id="cb51-10"><a href="#cb51-10" aria-hidden="true" tabindex="-1"></a>                       <span class="kw">in</span> <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb51-11"><a href="#cb51-11" aria-hidden="true" tabindex="-1"></a>                              <span class="kw">then</span> accumSum (n<span class="op">+</span>x) xs</span>
<span id="cb51-12"><a href="#cb51-12" aria-hidden="true" tabindex="-1"></a>                              <span class="kw">else</span> accumSum n xs</span></code></pre></div>
<p>Para probar la función puedes usar <code>ghci</code>:</p>
<pre><code>% ghci
GHCi, version 7.0.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude&gt; :load 11_Functions.lhs
[1 of 1] Compiling Main             ( 11_Functions.lhs, interpreted )
Ok, modules loaded: Main.
*Main&gt; evenSum [1..5]
6</code></pre>
<p>Aquí un ejemplo de la ejecución[^2]:</p>
<pre><code>*Main&gt; evenSum [1..5]
accumSum 0 [1,2,3,4,5]
1 is odd
accumSum 0 [2,3,4,5]
2 is even
accumSum (0+2) [3,4,5]
3 is odd
accumSum (0+2) [4,5]
2 is even
accumSum (0+2+4) [5]
5 is odd
accumSum (0+2+4) []
l == []
0+2+4
0+6
6</code></pre>
<p>Viniendo de un lenguaje imperativo todo debería parecer correcto. De hecho,
muchas cosas se pueden mejorar. Primero, podemos generalizar el tipo.</p>
<div class="sourceCode" id="cb54"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>Luego, podemos usar sub-funciones usando <code>where</code> o <code>let</code>. De esta forma la
función <code>accumSum</code> no llenará el espacio de nombres de nuestro modulo.</p>
<div class="sourceCode" id="cb55"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 2</span></span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb55-3"><a href="#cb55-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-4"><a href="#cb55-4" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> accumSum <span class="dv">0</span> l</span>
<span id="cb55-5"><a href="#cb55-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span> accumSum n l <span class="ot">=</span></span>
<span id="cb55-6"><a href="#cb55-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> l <span class="op">==</span> []</span>
<span id="cb55-7"><a href="#cb55-7" aria-hidden="true" tabindex="-1"></a>                <span class="kw">then</span> n</span>
<span id="cb55-8"><a href="#cb55-8" aria-hidden="true" tabindex="-1"></a>                <span class="kw">else</span> <span class="kw">let</span> x <span class="ot">=</span> <span class="fu">head</span> l</span>
<span id="cb55-9"><a href="#cb55-9" aria-hidden="true" tabindex="-1"></a>                         xs <span class="ot">=</span> <span class="fu">tail</span> l</span>
<span id="cb55-10"><a href="#cb55-10" aria-hidden="true" tabindex="-1"></a>                     <span class="kw">in</span> <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb55-11"><a href="#cb55-11" aria-hidden="true" tabindex="-1"></a>                            <span class="kw">then</span> accumSum (n<span class="op">+</span>x) xs</span>
<span id="cb55-12"><a href="#cb55-12" aria-hidden="true" tabindex="-1"></a>                            <span class="kw">else</span> accumSum n xs</span></code></pre></div>
<p>Luego podemos usar pattern matching.</p>
<div class="sourceCode" id="cb56"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 3</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> accumSum <span class="dv">0</span> l</span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a>        accumSum n [] <span class="ot">=</span> n</span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a>        accumSum n (x<span class="op">:</span>xs) <span class="ot">=</span></span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a>             <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb56-7"><a href="#cb56-7" aria-hidden="true" tabindex="-1"></a>                <span class="kw">then</span> accumSum (n<span class="op">+</span>x) xs</span>
<span id="cb56-8"><a href="#cb56-8" aria-hidden="true" tabindex="-1"></a>                <span class="kw">else</span> accumSum n xs</span></code></pre></div>
<p>Qué es pattern matching? Usar valores en lugar de nombres de
parámetro generales[^3].</p>
<p>En lugar de decir: <code>foo l = if l == [] then &lt;x&gt; else &lt;y&gt;</code> simplemente se
declara:</p>
<div class="sourceCode" id="cb57"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a>foo [] <span class="ot">=</span>  <span class="op">&lt;</span>x<span class="op">&gt;</span></span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a>foo l  <span class="ot">=</span>  <span class="op">&lt;</span>y<span class="op">&gt;</span></span></code></pre></div>
<p>Pero el pattern matching va más lejos. También es capaz de inspeccionar el
elemento interno de un valor complejo. Podemos reemplazar</p>
<div class="sourceCode" id="cb58"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a>foo l <span class="ot">=</span>  <span class="kw">let</span> x  <span class="ot">=</span> <span class="fu">head</span> l</span>
<span id="cb58-2"><a href="#cb58-2" aria-hidden="true" tabindex="-1"></a>             xs <span class="ot">=</span> <span class="fu">tail</span> l</span>
<span id="cb58-3"><a href="#cb58-3" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb58-4"><a href="#cb58-4" aria-hidden="true" tabindex="-1"></a>             <span class="kw">then</span> foo (n<span class="op">+</span>x) xs</span>
<span id="cb58-5"><a href="#cb58-5" aria-hidden="true" tabindex="-1"></a>             <span class="kw">else</span> foo n xs</span></code></pre></div>
<p>Con</p>
<div class="sourceCode" id="cb59"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a>foo (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a>                 <span class="kw">then</span> foo (n<span class="op">+</span>x) xs</span>
<span id="cb59-3"><a href="#cb59-3" aria-hidden="true" tabindex="-1"></a>                 <span class="kw">else</span> foo n xs</span></code></pre></div>
<p>Esto es una característica muy útil. Hace nuestro código más conciso y fácil de
leer.</p>
<p>En Haskell se puede simplificar las definiciones de las funciones usando
reducción η. Por ejemplo, en lugar de escribir:</p>
<div class="sourceCode" id="cb60"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a>f x <span class="ot">=</span> (una expresion) x</span></code></pre></div>
<p>Se puede escribir</p>
<div class="sourceCode" id="cb61"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a>f <span class="ot">=</span> una expression</span></code></pre></div>
<p>Usamos este método para remover el <code>l</code>:</p>
<div class="sourceCode" id="cb62"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 4</span></span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb62-3"><a href="#cb62-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb62-4"><a href="#cb62-4" aria-hidden="true" tabindex="-1"></a>evenSum <span class="ot">=</span> accumSum <span class="dv">0</span></span>
<span id="cb62-5"><a href="#cb62-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb62-6"><a href="#cb62-6" aria-hidden="true" tabindex="-1"></a>        accumSum n [] <span class="ot">=</span> n</span>
<span id="cb62-7"><a href="#cb62-7" aria-hidden="true" tabindex="-1"></a>        accumSum n (x<span class="op">:</span>xs) <span class="ot">=</span></span>
<span id="cb62-8"><a href="#cb62-8" aria-hidden="true" tabindex="-1"></a>             <span class="kw">if</span> <span class="fu">even</span> x</span>
<span id="cb62-9"><a href="#cb62-9" aria-hidden="true" tabindex="-1"></a>                <span class="kw">then</span> accumSum (n<span class="op">+</span>x) xs</span>
<span id="cb62-10"><a href="#cb62-10" aria-hidden="true" tabindex="-1"></a>                <span class="kw">else</span> accumSum n xs</span></code></pre></div>
<h3 id="funciones-de-orden-superior">Funciones de orden superior</h3>
<p><img src="/img/haskellhard/shot6.jpg" /></p>
<p>Para mejorarlo aún más podemos usar funciones de orden superior. Qué son esas
bestias? Las funciones de orden superior son funciones que toman funciones
como parámetros.</p>
<p>Aquí algunos ejemplos:</p>
<div class="sourceCode" id="cb63"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="fu">filter</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a><span class="fu">foldl</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>Procedamos con pequeños pasos.</p>
<div class="sourceCode" id="cb64"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 5</span></span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> mysum <span class="dv">0</span> (<span class="fu">filter</span> <span class="fu">even</span> l)</span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb64-4"><a href="#cb64-4" aria-hidden="true" tabindex="-1"></a>      mysum n [] <span class="ot">=</span> n</span>
<span id="cb64-5"><a href="#cb64-5" aria-hidden="true" tabindex="-1"></a>      mysum n (x<span class="op">:</span>xs) <span class="ot">=</span> mysum (n<span class="op">+</span>x) xs</span></code></pre></div>
<p>Donde</p>
<div class="sourceCode" id="cb65"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a><span class="fu">filter</span> <span class="fu">even</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>] ⇔  [<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">8</span>,<span class="dv">10</span>]</span></code></pre></div>
<p>La función <code>filter</code> toma una función de tipo (<code>a -&gt; Bool</code>) y una lista de
tipo <code>[a]</code>. Retorna una lista que contiene solamente los elementos para los
cuales la función retornó <code>true</code>.</p>
<p>El siguiente paso es usar otra técnica para lograr el mismo resultado que un
loop. Usaremos la función <code>foldl</code> para acumular los valores mientras recorremos
la lista. La función <code>foldl</code> captura un patrón común:</p>
<div class="sourceCode" id="cb66"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a>myfunc list <span class="ot">=</span> foo initialValue list</span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true" tabindex="-1"></a>foo accumulated []     <span class="ot">=</span> accumulated</span>
<span id="cb66-3"><a href="#cb66-3" aria-hidden="true" tabindex="-1"></a>foo tmpValue    (x<span class="op">:</span>xs) <span class="ot">=</span> foo (bar tmpValue x) xs</span></code></pre></div>
<p>Que se puede reemplazar con:</p>
<div class="sourceCode" id="cb67"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a>myfunc list <span class="ot">=</span> <span class="fu">foldl</span> bar initialValue list</span></code></pre></div>
<p>Si realmente quieres saber como funciona la magia, aquí está la definición
de <code>foldl</code>:</p>
<div class="sourceCode" id="cb68"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldl</span> f z [] <span class="ot">=</span> z</span>
<span id="cb68-2"><a href="#cb68-2" aria-hidden="true" tabindex="-1"></a><span class="fu">foldl</span> f z (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="fu">foldl</span> f (f z x) xs</span></code></pre></div>
<div class="sourceCode" id="cb69"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldl</span> f z [x1,<span class="op">...</span>xn]</span>
<span id="cb69-2"><a href="#cb69-2" aria-hidden="true" tabindex="-1"></a>⇔  f (<span class="op">...</span> (f (f z x1) x2) <span class="op">...</span>) xn</span></code></pre></div>
<p>Pero como Haskell es <em>perezoso</em>, no evalúa <code>(f z x)</code> y simplemente lo empuja en
la pila. Por eso generalmente usamos <code>foldl'</code> en lugar de <code>foldl</code>; <code>foldl'</code>
es una versión estricta de <code>foldl</code>. Si no comprendes que significa <em>perezoso</em>
o <em>estricto</em>, no te preocupes, solo sigue el código como si <code>fold</code> y <code>foldl'</code>
fueran idénticos.</p>
<p>Ahora la nueva versión de <code>evenSum</code> será:</p>
<div class="sourceCode" id="cb70"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 6</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- foldl&#39; isn&#39;t accessible by default</span></span>
<span id="cb70-3"><a href="#cb70-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- we need to import it from the module Data.List</span></span>
<span id="cb70-4"><a href="#cb70-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span></span>
<span id="cb70-5"><a href="#cb70-5" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> foldl&#39; mysum <span class="dv">0</span> (<span class="fu">filter</span> <span class="fu">even</span> l)</span>
<span id="cb70-6"><a href="#cb70-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span> mysum acc value <span class="ot">=</span> acc <span class="op">+</span> value</span></code></pre></div>
<p>También podemos simplificar eso usando notación lambda. Así no tendremos
que crear un nombre temporal <code>mysum</code>.</p>
<div class="sourceCode" id="cb71"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 7</span></span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Generally it is considered a good practice</span></span>
<span id="cb71-3"><a href="#cb71-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- to import only the necessary function(s)</span></span>
<span id="cb71-4"><a href="#cb71-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (foldl&#39;)</span>
<span id="cb71-5"><a href="#cb71-5" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> foldl&#39; (\x y <span class="ot">-&gt;</span> x<span class="op">+</span>y) <span class="dv">0</span> (<span class="fu">filter</span> <span class="fu">even</span> l)</span></code></pre></div>
<p>Y por supuesto, notamos que</p>
<p><code>(\x y -&gt; x+y) ⇔ (+)</code></p>
<p>Finalmente</p>
<div class="sourceCode" id="cb72"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 8</span></span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (foldl&#39;)</span>
<span id="cb72-3"><a href="#cb72-3" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb72-4"><a href="#cb72-4" aria-hidden="true" tabindex="-1"></a>evenSum l <span class="ot">=</span> foldl&#39; (<span class="op">+</span>) <span class="dv">0</span> (<span class="fu">filter</span> <span class="fu">even</span> l)</span></code></pre></div>
<p><code>foldl'</code> no es la función más sencilla de comprender. Si no estas
acostumbrado, deberías estudiarlo un poco.</p>
<p>Para ayudar a comprender que está sucediendo aquí, miremos la evaluación
paso por paso:</p>
<pre><code>evenSum [1,2,3,4]
⇒ foldl&#39; (+) 0 (filter even [1,2,3,4])
⇒ foldl&#39; (+) 0 [2,4]
⇒ foldl&#39; (+) (0+2) [4]
⇒ foldl&#39; (+) 2 [4]
⇒ foldl&#39; (+) (2+4) []
⇒ foldl&#39; (+) 6 []
⇒ 6</code></pre>
<p>Otra función de orden superior útil es <code>(.)</code>. La función <code>(.)</code> corresponde
a la composición matemática de funciones.</p>
<p><code>(f . g . h) x ⇔  f ( g (h x))</code></p>
<p>Podemos tomar ventaja de este operador para hacer una reducción η en nuestra
función:</p>
<div class="sourceCode" id="cb74"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 9</span></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (foldl&#39;)</span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true" tabindex="-1"></a>evenSum <span class="ot">=</span> (foldl&#39; (<span class="op">+</span>) <span class="dv">0</span>) <span class="op">.</span> (<span class="fu">filter</span> <span class="fu">even</span>)</span></code></pre></div>
<p>También, podemos renombrar algunas partes para hacerlo más claro:</p>
<div class="sourceCode" id="cb75"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Version 10</span></span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (foldl&#39;)</span>
<span id="cb75-3"><a href="#cb75-3" aria-hidden="true" tabindex="-1"></a><span class="ot">sum&#39; ::</span> (<span class="dt">Num</span> a) <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb75-4"><a href="#cb75-4" aria-hidden="true" tabindex="-1"></a>sum&#39; <span class="ot">=</span> foldl&#39; (<span class="op">+</span>) <span class="dv">0</span></span>
<span id="cb75-5"><a href="#cb75-5" aria-hidden="true" tabindex="-1"></a><span class="ot">evenSum ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb75-6"><a href="#cb75-6" aria-hidden="true" tabindex="-1"></a>evenSum <span class="ot">=</span> sum&#39; <span class="op">.</span> (<span class="fu">filter</span> <span class="fu">even</span>)</span></code></pre></div>
<p>Es tiempo de hablar sobre la dirección hacia la cual se ha movido nuestro
código mientras introducimos más de la forma funcional. Qué hemos ganado al
usar funciones de orden superior?</p>
<p>Al principio podrías pensar que la principal diferencia es la brevedad.
Pero en realidad tiene más que ver con la forma en la que se piensa. Supongamos
que se quiere modificar un poco la función, por ejemplo, para obtener la
suma de los cuadrados de los elementos pares de la lista.</p>
<div class="sourceCode" id="cb76"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>] ▷ [<span class="dv">1</span>,<span class="dv">4</span>,<span class="dv">9</span>,<span class="dv">16</span>] ▷ [<span class="dv">4</span>,<span class="dv">16</span>] ▷ <span class="dv">20</span></span></code></pre></div>
<p>Actualizar la versión 10 es muy fácil:</p>
<div class="sourceCode" id="cb77"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true" tabindex="-1"></a>squareEvenSum <span class="ot">=</span> sum&#39; <span class="op">.</span> (<span class="fu">filter</span> <span class="fu">even</span>) <span class="op">.</span> (<span class="fu">map</span> (<span class="op">^</span><span class="dv">2</span>))</span>
<span id="cb77-2"><a href="#cb77-2" aria-hidden="true" tabindex="-1"></a>squareEvenSum&#39; <span class="ot">=</span> evenSum <span class="op">.</span> (<span class="fu">map</span> (<span class="op">^</span><span class="dv">2</span>))</span></code></pre></div>
<p>Solamente agregamos otra “función de transformación”.</p>
<div class="sourceCode" id="cb78"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span> (<span class="op">^</span><span class="dv">2</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>] ⇔ [<span class="dv">1</span>,<span class="dv">4</span>,<span class="dv">9</span>,<span class="dv">16</span>]</span></code></pre></div>
<p>La función <code>map</code> simplemente aplica una función sobre todos los elementos
de una lista.</p>
<p>No tuvimos que modificar nada <em>dentro</em> de la definición de la función.
Esto hace el código más modular. Pero también permite pensar en la función de
forma más matemática. También se puede usar la función
intercambiablemente con otras, según se necesite. Esto es, se puede hacer
compose, map, fold, filter usando la nueva función.</p>
<p>Modificar la versión 1 se deja como ejercicio para el lector ☺.</p>
<p>Si piensas que hemos llegado al final de la generalización, entonces enterate
que estas muy equivocado. Por ejemplo, hay una forma de usar esta fucnion no
solo en listas, sino ademas sobre cualquier tipo recursivo. Si quieres
saber como, recomiendo que leas este
<a href="http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf">artículo</a></p>
<p>Este ejemplo debería demostrar cuan genial es la programación funcional.
Desafortunadamente, usar programación funcional pura no es adecuado para todos
los usos. O al menos un lenguaje que lo permite no se a logrado aún.</p>
<p>Uno de los mayores poderes de Haskell es la habilidad de crear DSLs (Lenguaje
de dominio específico) haciendo sencillo cambiar el paradigma de
programación.</p>
<p>De hecho, Haskell también es grandioso cuando se quiere escribir en estilo
imperativo. Comprender esto fue muy difícil para mi cuando aprendía Haskell.
Gran parte del esfuerzo se va intentando explicar la superioridad del enfoque
funcional. Luego cuando empiezas a usar estilo imperativo con Haskell,
puede ser difícil entender dónde y cómo usarlo.</p>
<p>Pero antes de hablar sobre este super poder de Haskell, debemos hablar
sobre otro aspecto esencial de Haskell: Tipos.</p>
<h2 id="tipos">Tipos</h2>
<p><img src="/img/haskellhard/shot7.jpg" /></p>
<p>TL;DR*:</p>
<ul>
<li><p><code>type Nombre = OtroTipo</code> es solamente un alias y no hay ninguna diferencia
entre <code>Nombre</code> y <code>OtroTipo</code>.</p></li>
<li><p><code>data Nombre = NombreConstructor OtroTipo</code> tiene diferencia</p></li>
<li><p><code>data</code> puede construir estructuras que pueden ser recursivas</p></li>
<li><p><code>deriving</code> es mágico y crea funciones por ti</p></li>
</ul>
<p>En Haskell, los tipos son fuertes y estáticos.</p>
<p>Por qué es importante? Permitirá en <em>gran</em> medida evitar errores. En Haskell, la
mayoría de los errores se capturan durante la compilación del programa. Y
la razón principal es debido a la inferencia de tipos durante la
compilación. La inferencia de tipos hace sencillo detectar donde se usó el
parámetro incorrecto en el lugar incorrecto, por ejemplo.</p>
<h3 id="inferencia-de-tipos">Inferencia de tipos</h3>
<p>El tipado estático es generalmente esencial para la ejecución veloz. Pero
la mayoría de lenguajes estáticamente tipado son malos generalizando
conceptos. La ventaja de Haskell es su capacidad para inferir tipos.</p>
<p>Aquí un ejemplo simple, la función <code>square</code> en Haskell:</p>
<div class="sourceCode" id="cb79"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb79-1"><a href="#cb79-1" aria-hidden="true" tabindex="-1"></a>square x <span class="ot">=</span> x <span class="op">*</span> x</span></code></pre></div>
<p>Esta función puede elevar al cuadrado cualquier tipo Numérico. Se puede pasar
a <code>square</code> un <code>Int</code>, un <code>Integer</code>, un <code>Float</code>, un <code>Fractional</code> e incluso un
<code>Complex</code>. Por ejemplo:</p>
<pre><code>% ghci
GHCi, version 7.0.4:
...
Prelude&gt; let square x = x*x
Prelude&gt; square 2
4
Prelude&gt; square 2.1
4.41
Prelude&gt; -- load the Data.Complex module
Prelude&gt; :m Data.Complex
Prelude Data.Complex&gt; square (2 :+ 1)
3.0 :+ 4.0</code></pre>
<p><code>x :+ y</code> es la notación para el complejo (x + iy).</p>
<p>Ahora compáralo con la cantidad de código necesario en <code>C</code>:</p>
<div class="sourceCode" id="cb81"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb81-1"><a href="#cb81-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span>     int_square<span class="op">(</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x<span class="op">*</span>x<span class="op">;</span> <span class="op">}</span></span>
<span id="cb81-2"><a href="#cb81-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb81-3"><a href="#cb81-3" aria-hidden="true" tabindex="-1"></a><span class="dt">float</span>   float_square<span class="op">(</span><span class="dt">float</span> x<span class="op">)</span> <span class="op">{</span><span class="cf">return</span> x<span class="op">*</span>x<span class="op">;</span> <span class="op">}</span></span>
<span id="cb81-4"><a href="#cb81-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb81-5"><a href="#cb81-5" aria-hidden="true" tabindex="-1"></a><span class="dt">complex</span> complex_square <span class="op">(</span><span class="dt">complex</span> z<span class="op">)</span> <span class="op">{</span></span>
<span id="cb81-6"><a href="#cb81-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">complex</span> tmp<span class="op">;</span></span>
<span id="cb81-7"><a href="#cb81-7" aria-hidden="true" tabindex="-1"></a>    tmp<span class="op">.</span>real <span class="op">=</span> z<span class="op">.</span>real <span class="op">*</span> z<span class="op">.</span>real <span class="op">-</span> z<span class="op">.</span>img <span class="op">*</span> z<span class="op">.</span>img<span class="op">;</span></span>
<span id="cb81-8"><a href="#cb81-8" aria-hidden="true" tabindex="-1"></a>    tmp<span class="op">.</span>img <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> z<span class="op">.</span>img <span class="op">*</span> z<span class="op">.</span>real<span class="op">;</span></span>
<span id="cb81-9"><a href="#cb81-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb81-10"><a href="#cb81-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb81-11"><a href="#cb81-11" aria-hidden="true" tabindex="-1"></a><span class="dt">complex</span> x<span class="op">,</span>y<span class="op">;</span></span>
<span id="cb81-12"><a href="#cb81-12" aria-hidden="true" tabindex="-1"></a>y <span class="op">=</span> complex_square<span class="op">(</span>x<span class="op">);</span></span></code></pre></div>
<p>Para cada tipo, se necesita escribir una nueva función. La única forma de
solucionar esto es usando algún truco de meta-programación, por ejemplo
usando el pre-procesador. En C++ hay una mejor forma usando templates:</p>
<div class="sourceCode" id="cb82"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb82-1"><a href="#cb82-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;iostream&gt;</span></span>
<span id="cb82-2"><a href="#cb82-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;complex&gt;</span></span>
<span id="cb82-3"><a href="#cb82-3" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> <span class="kw">namespace</span> std<span class="op">;</span></span>
<span id="cb82-4"><a href="#cb82-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb82-5"><a href="#cb82-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb82-6"><a href="#cb82-6" aria-hidden="true" tabindex="-1"></a>T square<span class="op">(</span>T x<span class="op">)</span></span>
<span id="cb82-7"><a href="#cb82-7" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb82-8"><a href="#cb82-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">*</span>x<span class="op">;</span></span>
<span id="cb82-9"><a href="#cb82-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb82-10"><a href="#cb82-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb82-11"><a href="#cb82-11" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb82-12"><a href="#cb82-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">// int</span></span>
<span id="cb82-13"><a href="#cb82-13" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sqr_of_five <span class="op">=</span> square<span class="op">(</span><span class="dv">5</span><span class="op">);</span></span>
<span id="cb82-14"><a href="#cb82-14" aria-hidden="true" tabindex="-1"></a>    cout <span class="op">&lt;&lt;</span> sqr_of_five <span class="op">&lt;&lt;</span> endl<span class="op">;</span></span>
<span id="cb82-15"><a href="#cb82-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// double</span></span>
<span id="cb82-16"><a href="#cb82-16" aria-hidden="true" tabindex="-1"></a>    cout <span class="op">&lt;&lt;</span> <span class="op">(</span><span class="dt">double</span><span class="op">)</span>square<span class="op">(</span><span class="fl">5.3</span><span class="op">)</span> <span class="op">&lt;&lt;</span> endl<span class="op">;</span></span>
<span id="cb82-17"><a href="#cb82-17" aria-hidden="true" tabindex="-1"></a>    <span class="co">// complex</span></span>
<span id="cb82-18"><a href="#cb82-18" aria-hidden="true" tabindex="-1"></a>    cout <span class="op">&lt;&lt;</span> square<span class="op">(</span> complex<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;(</span><span class="dv">5</span><span class="op">,</span><span class="dv">3</span><span class="op">)</span> <span class="op">)</span></span>
<span id="cb82-19"><a href="#cb82-19" aria-hidden="true" tabindex="-1"></a>         <span class="op">&lt;&lt;</span> endl<span class="op">;</span></span>
<span id="cb82-20"><a href="#cb82-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb82-21"><a href="#cb82-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>C++ lo hace mucho mejor que C en este aspecto. Pero para funciones más
complejas la sintaxis puede ser difícil de entender: Mira <a href="http://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/">este
artículo</a>
por ejemplo.</p>
<p>En C++ se debe declarar que la función puede trabajar con distintos tipos. En
Haskell, es lo opuesto. La función será lo más general posible por defecto.</p>
<p>La inferencia de tipos le da a Haskell la sensación de libertad de los
lenguajes de tipado dinámico. Pero a diferencia de estos, la mayoría de los
errores se encuentra antes de la ejecución. Generalmente, en Haskell:</p>
<blockquote>
<p>“Si compila entonces hace lo que quieres que haga”</p>
</blockquote>
<h3 id="construcción-de-tipos">Construcción de tipos</h3>
<p>Es posible construir tipos propios. Primero, se pueden usar alias o sinónimos de
tipos.</p>
<div class="sourceCode" id="cb83"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb83-1"><a href="#cb83-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Name</span>   <span class="ot">=</span> <span class="dt">String</span></span>
<span id="cb83-2"><a href="#cb83-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Color</span>  <span class="ot">=</span> <span class="dt">String</span></span>
<span id="cb83-3"><a href="#cb83-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb83-4"><a href="#cb83-4" aria-hidden="true" tabindex="-1"></a><span class="ot">showInfos ::</span> <span class="dt">Name</span> <span class="ot">-&gt;</span>  <span class="dt">Color</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb83-5"><a href="#cb83-5" aria-hidden="true" tabindex="-1"></a>showInfos name color <span class="ot">=</span>  <span class="st">&quot;Name: &quot;</span> <span class="op">++</span> name</span>
<span id="cb83-6"><a href="#cb83-6" aria-hidden="true" tabindex="-1"></a>                        <span class="op">++</span> <span class="st">&quot;, Color: &quot;</span> <span class="op">++</span> color</span>
<span id="cb83-7"><a href="#cb83-7" aria-hidden="true" tabindex="-1"></a><span class="ot">name ::</span> <span class="dt">Name</span></span>
<span id="cb83-8"><a href="#cb83-8" aria-hidden="true" tabindex="-1"></a>name <span class="ot">=</span> <span class="st">&quot;Robin&quot;</span></span>
<span id="cb83-9"><a href="#cb83-9" aria-hidden="true" tabindex="-1"></a><span class="ot">color ::</span> <span class="dt">Color</span></span>
<span id="cb83-10"><a href="#cb83-10" aria-hidden="true" tabindex="-1"></a>color <span class="ot">=</span> <span class="st">&quot;Blue&quot;</span></span>
<span id="cb83-11"><a href="#cb83-11" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">putStrLn</span> <span class="op">$</span> showInfos name color</span></code></pre></div>
<p>Pero esto no te protege mucho. Intenta intercambiar los dos parámetros de
<code>showInfos</code> y ejecuta el programa:</p>
<pre><code>putStrLn $ showInfos color name</code></pre>
<p>Se compilará y ejecutará. De hecho se pueden reemplazar <code>Name</code>, <code>Color</code> y
<code>String</code> con cualquier cosa. El compilador los tratará como si fueran
idénticos.</p>
<p>Otro método es crear tus propios tipos usando la palabra reservada <code>data</code>.</p>
<div class="sourceCode" id="cb85"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb85-1"><a href="#cb85-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Name</span>   <span class="ot">=</span> <span class="dt">NameConstr</span> <span class="dt">String</span></span>
<span id="cb85-2"><a href="#cb85-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Color</span>  <span class="ot">=</span> <span class="dt">ColorConstr</span> <span class="dt">String</span></span>
<span id="cb85-3"><a href="#cb85-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb85-4"><a href="#cb85-4" aria-hidden="true" tabindex="-1"></a><span class="ot">showInfos ::</span> <span class="dt">Name</span> <span class="ot">-&gt;</span>  <span class="dt">Color</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb85-5"><a href="#cb85-5" aria-hidden="true" tabindex="-1"></a>showInfos (<span class="dt">NameConstr</span> name) (<span class="dt">ColorConstr</span> color) <span class="ot">=</span></span>
<span id="cb85-6"><a href="#cb85-6" aria-hidden="true" tabindex="-1"></a>      <span class="st">&quot;Name: &quot;</span> <span class="op">++</span> name <span class="op">++</span> <span class="st">&quot;, Color: &quot;</span> <span class="op">++</span> color</span>
<span id="cb85-7"><a href="#cb85-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb85-8"><a href="#cb85-8" aria-hidden="true" tabindex="-1"></a>name  <span class="ot">=</span> <span class="dt">NameConstr</span> <span class="st">&quot;Robin&quot;</span></span>
<span id="cb85-9"><a href="#cb85-9" aria-hidden="true" tabindex="-1"></a>color <span class="ot">=</span> <span class="dt">ColorConstr</span> <span class="st">&quot;Blue&quot;</span></span>
<span id="cb85-10"><a href="#cb85-10" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">putStrLn</span> <span class="op">$</span> showInfos name color</span></code></pre></div>
<p>Ahora si intercambias los parámetros de <code>showInfos</code>, el compilador se queja!
De forma que nunca más podrás cometer un error de ese tipo y el único
precio es ser un poco más explicito.</p>
<p>También nota que los constructores son funciones:</p>
<div class="sourceCode" id="cb86"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb86-1"><a href="#cb86-1" aria-hidden="true" tabindex="-1"></a><span class="dt">NameConstr</span><span class="ot">  ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Name</span></span>
<span id="cb86-2"><a href="#cb86-2" aria-hidden="true" tabindex="-1"></a><span class="dt">ColorConstr</span><span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Color</span></span></code></pre></div>
<p>La sintaxis de <code>data</code> es principalmente:</p>
<div class="sourceCode" id="cb87"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb87-1"><a href="#cb87-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">TypeName</span> <span class="ot">=</span>   <span class="dt">ConstructorName</span>  [types]</span>
<span id="cb87-2"><a href="#cb87-2" aria-hidden="true" tabindex="-1"></a>                <span class="op">|</span> <span class="dt">ConstructorName2</span> [types]</span>
<span id="cb87-3"><a href="#cb87-3" aria-hidden="true" tabindex="-1"></a>                <span class="op">|</span> <span class="op">...</span></span></code></pre></div>
<p>Generalmente se usa el mismo nombre para el <code>DataTypeName</code> y para el
<code>DataTypeConstructor</code>.</p>
<p>Ejemplo:</p>
<div class="sourceCode" id="cb88"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb88-1"><a href="#cb88-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Complex</span> a <span class="ot">=</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Complex</span> a a</span></code></pre></div>
<p>También se puede usar sintaxis record:</p>
<div class="sourceCode" id="cb89"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb89-1"><a href="#cb89-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">DataTypeName</span> <span class="ot">=</span> <span class="dt">DataConstructor</span> {</span>
<span id="cb89-2"><a href="#cb89-2" aria-hidden="true" tabindex="-1"></a><span class="ot">                      field1 ::</span> [<span class="kw">type</span> <span class="kw">of</span> field1]</span>
<span id="cb89-3"><a href="#cb89-3" aria-hidden="true" tabindex="-1"></a>                    ,<span class="ot"> field2 ::</span> [<span class="kw">type</span> <span class="kw">of</span> field2]</span>
<span id="cb89-4"><a href="#cb89-4" aria-hidden="true" tabindex="-1"></a>                    <span class="op">...</span></span>
<span id="cb89-5"><a href="#cb89-5" aria-hidden="true" tabindex="-1"></a>                    ,<span class="ot"> fieldn ::</span> [<span class="kw">type</span> <span class="kw">of</span> fieldn] }</span></code></pre></div>
<p>Y hay varios accesores disponibles. Además se puede usar otro orden cuando se
asignen valores.</p>
<p>Ejemplo:</p>
<div class="sourceCode" id="cb90"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb90-1"><a href="#cb90-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Complex</span> a <span class="ot">=</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Complex</span> {<span class="ot"> real ::</span> a,<span class="ot"> img ::</span> a}</span>
<span id="cb90-2"><a href="#cb90-2" aria-hidden="true" tabindex="-1"></a>c <span class="ot">=</span> <span class="dt">Complex</span> <span class="fl">1.0</span> <span class="fl">2.0</span></span>
<span id="cb90-3"><a href="#cb90-3" aria-hidden="true" tabindex="-1"></a>z <span class="ot">=</span> <span class="dt">Complex</span> { real <span class="ot">=</span> <span class="dv">3</span>, img <span class="ot">=</span> <span class="dv">4</span> }</span>
<span id="cb90-4"><a href="#cb90-4" aria-hidden="true" tabindex="-1"></a>real c ⇒ <span class="fl">1.0</span></span>
<span id="cb90-5"><a href="#cb90-5" aria-hidden="true" tabindex="-1"></a>img z ⇒ <span class="dv">4</span></span></code></pre></div>
<h3 id="tipos-recursivos">Tipos recursivos</h3>
<p>Ya nos hemos topado con un tipo recursivo: listas. Se pueden re-crear
listas, pero con una sintaxis más explicita:</p>
<div class="sourceCode" id="cb91"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb91-1"><a href="#cb91-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">Empty</span> <span class="op">|</span> <span class="dt">Cons</span> a (<span class="dt">List</span> a)</span></code></pre></div>
<p>Si prefieres usar una sintaxis más simple, se puede usar un nombre infijo para
los constructores.</p>
<div class="sourceCode" id="cb92"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb92-1"><a href="#cb92-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:::</span></span>
<span id="cb92-2"><a href="#cb92-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">Nil</span> <span class="op">|</span> a <span class="op">:::</span> (<span class="dt">List</span> a)</span></code></pre></div>
<p>El numero luego de <code>infixr</code> le da la precedencia.</p>
<p>Si quieres poder imprimir por pantalla (<code>Show</code>), leer (<code>Read</code>), probar
igualdad (<code>Eq</code>) y comparar (<code>Ord</code>) con tu nueva estructura de datos puedes
pedirle a Haskell que derive las funciones apropiadas por ti.</p>
<div class="sourceCode" id="cb93"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb93-1"><a href="#cb93-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:::</span></span>
<span id="cb93-2"><a href="#cb93-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">Nil</span> <span class="op">|</span> a <span class="op">:::</span> (<span class="dt">List</span> a)</span>
<span id="cb93-3"><a href="#cb93-3" aria-hidden="true" tabindex="-1"></a>              <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Read</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>)</span></code></pre></div>
<p>Cuando añades <code>deriving (Show)</code> a tu declaración de datos, Haskell crea una
función <code>show</code> por ti. Ya veremos como se puede usar una función <code>show</code>
propia.</p>
<div class="sourceCode" id="cb94"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb94-1"><a href="#cb94-1" aria-hidden="true" tabindex="-1"></a>convertList [] <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb94-2"><a href="#cb94-2" aria-hidden="true" tabindex="-1"></a>convertList (x<span class="op">:</span>xs) <span class="ot">=</span> x <span class="op">:::</span> convertList xs</span></code></pre></div>
<div class="sourceCode" id="cb95"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb95-1"><a href="#cb95-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb95-2"><a href="#cb95-2" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> (<span class="dv">0</span> <span class="op">:::</span> <span class="dv">1</span> <span class="op">:::</span> <span class="dt">Nil</span>)</span>
<span id="cb95-3"><a href="#cb95-3" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> (convertList [<span class="dv">0</span>,<span class="dv">1</span>])</span></code></pre></div>
<p>Esto imprime:</p>
<div class="sourceCode" id="cb96"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb96-1"><a href="#cb96-1" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span> <span class="op">:::</span> (<span class="dv">1</span> <span class="op">:::</span> <span class="dt">Nil</span>)</span>
<span id="cb96-2"><a href="#cb96-2" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span> <span class="op">:::</span> (<span class="dv">1</span> <span class="op">:::</span> <span class="dt">Nil</span>)</span></code></pre></div>
<h3 id="arboles">Arboles</h3>
<p><img src="/img/haskellhard/shot8.jpg" /></p>
<p>Otro ejemplo estándar: arboles binarios.</p>
<div class="sourceCode" id="cb97"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb97-1"><a href="#cb97-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span></span>
<span id="cb97-2"><a href="#cb97-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb97-3"><a href="#cb97-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BinTree</span> a <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb97-4"><a href="#cb97-4" aria-hidden="true" tabindex="-1"></a>                 <span class="op">|</span> <span class="dt">Node</span> a (<span class="dt">BinTree</span> a) (<span class="dt">BinTree</span> a)</span>
<span id="cb97-5"><a href="#cb97-5" aria-hidden="true" tabindex="-1"></a>                              <span class="kw">deriving</span> (<span class="dt">Show</span>)</span></code></pre></div>
<p>También crearemos una función que convierta una lista en un árbol binario
ordenado.</p>
<div class="sourceCode" id="cb98"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb98-1"><a href="#cb98-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFromList ::</span> (<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">BinTree</span> a</span>
<span id="cb98-2"><a href="#cb98-2" aria-hidden="true" tabindex="-1"></a>treeFromList [] <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb98-3"><a href="#cb98-3" aria-hidden="true" tabindex="-1"></a>treeFromList (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Node</span> x (treeFromList (<span class="fu">filter</span> (<span class="op">&lt;</span>x) xs))</span>
<span id="cb98-4"><a href="#cb98-4" aria-hidden="true" tabindex="-1"></a>                             (treeFromList (<span class="fu">filter</span> (<span class="op">&gt;</span>x) xs))</span></code></pre></div>
<p>Observa cuan elegante es esta función.</p>
<ul>
<li>Una lista vacía será convertida en un árbol vació.</li>
<li>Una lista <code>(x:xs)</code> será convertida en un árbol donde:
** La raíz es <code>x</code>
** El sub-árbol de la izquierda es el árbol creado de los miembros de la lista
** <code>xs</code> que son menores a <code>x</code> y
** El sub-árbol de la derecha es el árbol creado de los miembros de la lista <code>xs</code>
** que son mayores que <code>x</code>.</li>
</ul>
<div class="sourceCode" id="cb99"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb99-1"><a href="#cb99-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> <span class="op">$</span> treeFromList [<span class="dv">7</span>,<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">8</span>]</span></code></pre></div>
<p>Deberías obtener lo siguiente:</p>
<div class="sourceCode" id="cb100"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb100-1"><a href="#cb100-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Node</span> <span class="dv">7</span> (<span class="dt">Node</span> <span class="dv">2</span> <span class="dt">Empty</span> (<span class="dt">Node</span> <span class="dv">4</span> <span class="dt">Empty</span> <span class="dt">Empty</span>)) (<span class="dt">Node</span> <span class="dv">8</span> <span class="dt">Empty</span> <span class="dt">Empty</span>)</span></code></pre></div>
<p>Esta es una forma informativa pero no muy agradable de nuestro árbol.</p>
<p>Solo por diversión, hagamos que nuestros arboles se visualicen de una mejor
forma. Simplemente resulta divertido hacer una función para mostrar arboles en
una forma general. Puedes saltarte esta parta si te parece muy difícil.</p>
<p>Tenemos unos cuantos cambios que hacer. Remover el <code>deriving (Show)</code> de la
declaración del tipo <code>BinTree</code>. Y también sería útil hacer nuestras propias
infancias de (<code>Eq</code> y <code>Ord</code>) de forma que podamos probar igualdad y comprar
arboles.</p>
<div class="sourceCode" id="cb101"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb101-1"><a href="#cb101-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BinTree</span> a <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb101-2"><a href="#cb101-2" aria-hidden="true" tabindex="-1"></a>                 <span class="op">|</span> <span class="dt">Node</span> a (<span class="dt">BinTree</span> a) (<span class="dt">BinTree</span> a)</span>
<span id="cb101-3"><a href="#cb101-3" aria-hidden="true" tabindex="-1"></a>                  <span class="kw">deriving</span> (<span class="dt">Eq</span>,<span class="dt">Ord</span>)</span></code></pre></div>
<p>Sin el <code>deriving (Show)</code>, Haskell no creará una función <code>show</code> por nosotros.
Crearemos nuestra propia versión de <code>show</code>. Para lograrlo, debemos declarar
que nuestro nuevo tipo <code>BinTree a</code> es una instancia de la clase de tipo
<code>Show</code>. La sintaxis general es:</p>
<div class="sourceCode" id="cb102"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb102-1"><a href="#cb102-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> (<span class="dt">BinTree</span> a) <span class="kw">where</span></span>
<span id="cb102-2"><a href="#cb102-2" aria-hidden="true" tabindex="-1"></a>   <span class="fu">show</span> t <span class="ot">=</span> <span class="op">...</span> <span class="co">-- You declare your function here</span></span></code></pre></div>
<p>Aquí está mi versión de como mostrar un árbol binario. No te preocupes
de la aparente complejidad. Hice un montón de mejoras para mostrar incluso
objetos extraños.</p>
<div class="sourceCode" id="cb103"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb103-1"><a href="#cb103-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- declare BinTree a to be an instance of Show</span></span>
<span id="cb103-2"><a href="#cb103-2" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Show</span> a) <span class="ot">=&gt;</span> <span class="dt">Show</span> (<span class="dt">BinTree</span> a) <span class="kw">where</span></span>
<span id="cb103-3"><a href="#cb103-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- will start by a &#39;&lt;&#39; before the root</span></span>
<span id="cb103-4"><a href="#cb103-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- and put a : a begining of line</span></span>
<span id="cb103-5"><a href="#cb103-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">show</span> t <span class="ot">=</span> <span class="st">&quot;&lt; &quot;</span> <span class="op">++</span> replace <span class="ch">&#39;\n&#39;</span> <span class="st">&quot;\n: &quot;</span> (treeshow <span class="st">&quot;&quot;</span> t)</span>
<span id="cb103-6"><a href="#cb103-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb103-7"><a href="#cb103-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- treeshow pref Tree</span></span>
<span id="cb103-8"><a href="#cb103-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">--   shows a tree and starts each line with pref</span></span>
<span id="cb103-9"><a href="#cb103-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- We don&#39;t display the Empty tree</span></span>
<span id="cb103-10"><a href="#cb103-10" aria-hidden="true" tabindex="-1"></a>    treeshow pref <span class="dt">Empty</span> <span class="ot">=</span> <span class="st">&quot;&quot;</span></span>
<span id="cb103-11"><a href="#cb103-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- Leaf</span></span>
<span id="cb103-12"><a href="#cb103-12" aria-hidden="true" tabindex="-1"></a>    treeshow pref (<span class="dt">Node</span> x <span class="dt">Empty</span> <span class="dt">Empty</span>) <span class="ot">=</span></span>
<span id="cb103-13"><a href="#cb103-13" aria-hidden="true" tabindex="-1"></a>                  (pshow pref x)</span>
<span id="cb103-14"><a href="#cb103-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-15"><a href="#cb103-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- Right branch is empty</span></span>
<span id="cb103-16"><a href="#cb103-16" aria-hidden="true" tabindex="-1"></a>    treeshow pref (<span class="dt">Node</span> x left <span class="dt">Empty</span>) <span class="ot">=</span></span>
<span id="cb103-17"><a href="#cb103-17" aria-hidden="true" tabindex="-1"></a>                  (pshow pref x) <span class="op">++</span> <span class="st">&quot;\n&quot;</span> <span class="op">++</span></span>
<span id="cb103-18"><a href="#cb103-18" aria-hidden="true" tabindex="-1"></a>                  (showSon pref <span class="st">&quot;`--&quot;</span> <span class="st">&quot;   &quot;</span> left)</span>
<span id="cb103-19"><a href="#cb103-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-20"><a href="#cb103-20" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- Left branch is empty</span></span>
<span id="cb103-21"><a href="#cb103-21" aria-hidden="true" tabindex="-1"></a>    treeshow pref (<span class="dt">Node</span> x <span class="dt">Empty</span> right) <span class="ot">=</span></span>
<span id="cb103-22"><a href="#cb103-22" aria-hidden="true" tabindex="-1"></a>                  (pshow pref x) <span class="op">++</span> <span class="st">&quot;\n&quot;</span> <span class="op">++</span></span>
<span id="cb103-23"><a href="#cb103-23" aria-hidden="true" tabindex="-1"></a>                  (showSon pref <span class="st">&quot;`--&quot;</span> <span class="st">&quot;   &quot;</span> right)</span>
<span id="cb103-24"><a href="#cb103-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-25"><a href="#cb103-25" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- Tree with left and right children non empty</span></span>
<span id="cb103-26"><a href="#cb103-26" aria-hidden="true" tabindex="-1"></a>    treeshow pref (<span class="dt">Node</span> x left right) <span class="ot">=</span></span>
<span id="cb103-27"><a href="#cb103-27" aria-hidden="true" tabindex="-1"></a>                  (pshow pref x) <span class="op">++</span> <span class="st">&quot;\n&quot;</span> <span class="op">++</span></span>
<span id="cb103-28"><a href="#cb103-28" aria-hidden="true" tabindex="-1"></a>                  (showSon pref <span class="st">&quot;|--&quot;</span> <span class="st">&quot;|  &quot;</span> left) <span class="op">++</span> <span class="st">&quot;\n&quot;</span> <span class="op">++</span></span>
<span id="cb103-29"><a href="#cb103-29" aria-hidden="true" tabindex="-1"></a>                  (showSon pref <span class="st">&quot;`--&quot;</span> <span class="st">&quot;   &quot;</span> right)</span>
<span id="cb103-30"><a href="#cb103-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-31"><a href="#cb103-31" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- shows a tree using some prefixes to make it nice</span></span>
<span id="cb103-32"><a href="#cb103-32" aria-hidden="true" tabindex="-1"></a>    showSon pref before next t <span class="ot">=</span></span>
<span id="cb103-33"><a href="#cb103-33" aria-hidden="true" tabindex="-1"></a>                  pref <span class="op">++</span> before <span class="op">++</span> treeshow (pref <span class="op">++</span> next) t</span>
<span id="cb103-34"><a href="#cb103-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-35"><a href="#cb103-35" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- pshow replaces &quot;\n&quot; by &quot;\n&quot;++pref</span></span>
<span id="cb103-36"><a href="#cb103-36" aria-hidden="true" tabindex="-1"></a>    pshow pref x <span class="ot">=</span> replace <span class="ch">&#39;\n&#39;</span> (<span class="st">&quot;\n&quot;</span><span class="op">++</span>pref) (<span class="fu">show</span> x)</span>
<span id="cb103-37"><a href="#cb103-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb103-38"><a href="#cb103-38" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- replaces one char by another string</span></span>
<span id="cb103-39"><a href="#cb103-39" aria-hidden="true" tabindex="-1"></a>    replace c new string <span class="ot">=</span></span>
<span id="cb103-40"><a href="#cb103-40" aria-hidden="true" tabindex="-1"></a>      <span class="fu">concatMap</span> (change c new) string</span>
<span id="cb103-41"><a href="#cb103-41" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb103-42"><a href="#cb103-42" aria-hidden="true" tabindex="-1"></a>          change c new x</span>
<span id="cb103-43"><a href="#cb103-43" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> x <span class="op">==</span> c <span class="ot">=</span> new</span>
<span id="cb103-44"><a href="#cb103-44" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> x<span class="op">:</span>[] <span class="co">-- &quot;x&quot;</span></span></code></pre></div>
<p>El método <code>treeFromList</code> permanece idéntico.</p>
<div class="sourceCode" id="cb104"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb104-1"><a href="#cb104-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFromList ::</span> (<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">BinTree</span> a</span>
<span id="cb104-2"><a href="#cb104-2" aria-hidden="true" tabindex="-1"></a>treeFromList [] <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb104-3"><a href="#cb104-3" aria-hidden="true" tabindex="-1"></a>treeFromList (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Node</span> x (treeFromList (<span class="fu">filter</span> (<span class="op">&lt;</span>x) xs))</span>
<span id="cb104-4"><a href="#cb104-4" aria-hidden="true" tabindex="-1"></a>                             (treeFromList (<span class="fu">filter</span> (<span class="op">&gt;</span>x) xs))</span></code></pre></div>
<p>Y ahora, podemos jugar:</p>
<div class="sourceCode" id="cb105"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb105-1"><a href="#cb105-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb105-2"><a href="#cb105-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Int binary tree:&quot;</span></span>
<span id="cb105-3"><a href="#cb105-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> treeFromList [<span class="dv">7</span>,<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">8</span>,<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">6</span>,<span class="dv">21</span>,<span class="dv">12</span>,<span class="dv">23</span>]</span></code></pre></div>
<pre><code>Int binary tree:
&lt; 7
: |--2
: |  |--1
: |  `--4
: |     |--3
: |     `--6
: `--8
:    `--21
:       |--12
:       `--23</code></pre>
<p>Ahora es mucho mejor! La raíz se muestra iniciando la linea con <code>&lt;</code>. Y cada
linea que le sigue inicia con <code>:</code>. Pero también podríamos usar otro tipo.</p>
<div class="sourceCode" id="cb107"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb107-1"><a href="#cb107-1" aria-hidden="true" tabindex="-1"></a><span class="fu">putStrLn</span> <span class="st">&quot;\nString binary tree:&quot;</span></span>
<span id="cb107-2"><a href="#cb107-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span> <span class="op">$</span> treeFromList [<span class="st">&quot;foo&quot;</span>,<span class="st">&quot;bar&quot;</span>,<span class="st">&quot;baz&quot;</span>,<span class="st">&quot;gor&quot;</span>,<span class="st">&quot;yog&quot;</span>]</span></code></pre></div>
<pre><code>String binary tree:
&lt; &quot;foo&quot;
: |--&quot;bar&quot;
: |  `--&quot;baz&quot;
: `--&quot;gor&quot;
:    `--&quot;yog&quot;</code></pre>
<p>Como podemos probar igualdad y ordenar arboles, podemos hacer arboles de
arboles!</p>
<div class="sourceCode" id="cb109"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb109-1"><a href="#cb109-1" aria-hidden="true" tabindex="-1"></a><span class="fu">putStrLn</span> <span class="st">&quot;\nBinary tree of Char binary trees:&quot;</span></span>
<span id="cb109-2"><a href="#cb109-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span> ( treeFromList</span>
<span id="cb109-3"><a href="#cb109-3" aria-hidden="true" tabindex="-1"></a>        (<span class="fu">map</span> treeFromList [<span class="st">&quot;baz&quot;</span>,<span class="st">&quot;zara&quot;</span>,<span class="st">&quot;bar&quot;</span>]))</span></code></pre></div>
<pre><code>Binary tree of Char binary trees:
&lt; &lt; &#39;b&#39;
: : |--&#39;a&#39;
: : `--&#39;z&#39;
: |--&lt; &#39;b&#39;
: |  : |--&#39;a&#39;
: |  : `--&#39;r&#39;
: `--&lt; &#39;z&#39;
:    : `--&#39;a&#39;
:    :    `--&#39;r&#39;</code></pre>
<p>Por eso elegí poner un <code>:</code> en cada linea del árbol (excepto en la raíz).</p>
<p><img src="/img/haskellhard/shot9.jpg" /></p>
<div class="sourceCode" id="cb111"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb111-1"><a href="#cb111-1" aria-hidden="true" tabindex="-1"></a><span class="fu">putStrLn</span> <span class="st">&quot;\nTree of Binary trees of Char binary trees:&quot;</span></span>
<span id="cb111-2"><a href="#cb111-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span> <span class="op">$</span> (treeFromList <span class="op">.</span> <span class="fu">map</span> (treeFromList <span class="op">.</span> <span class="fu">map</span> treeFromList))</span>
<span id="cb111-3"><a href="#cb111-3" aria-hidden="true" tabindex="-1"></a>            [ [<span class="st">&quot;YO&quot;</span>,<span class="st">&quot;DAWG&quot;</span>]</span>
<span id="cb111-4"><a href="#cb111-4" aria-hidden="true" tabindex="-1"></a>            , [<span class="st">&quot;I&quot;</span>,<span class="st">&quot;HEARD&quot;</span>]</span>
<span id="cb111-5"><a href="#cb111-5" aria-hidden="true" tabindex="-1"></a>            , [<span class="st">&quot;I&quot;</span>,<span class="st">&quot;HEARD&quot;</span>]</span>
<span id="cb111-6"><a href="#cb111-6" aria-hidden="true" tabindex="-1"></a>            , [<span class="st">&quot;YOU&quot;</span>,<span class="st">&quot;LIKE&quot;</span>,<span class="st">&quot;TREES&quot;</span>] ]</span></code></pre></div>
<p>Que es equivalente a</p>
<div class="sourceCode" id="cb112"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb112-1"><a href="#cb112-1" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span> ( treeFromList (</span>
<span id="cb112-2"><a href="#cb112-2" aria-hidden="true" tabindex="-1"></a>          <span class="fu">map</span> treeFromList</span>
<span id="cb112-3"><a href="#cb112-3" aria-hidden="true" tabindex="-1"></a>             [ <span class="fu">map</span> treeFromList [<span class="st">&quot;YO&quot;</span>,<span class="st">&quot;DAWG&quot;</span>]</span>
<span id="cb112-4"><a href="#cb112-4" aria-hidden="true" tabindex="-1"></a>             , <span class="fu">map</span> treeFromList [<span class="st">&quot;I&quot;</span>,<span class="st">&quot;HEARD&quot;</span>]</span>
<span id="cb112-5"><a href="#cb112-5" aria-hidden="true" tabindex="-1"></a>             , <span class="fu">map</span> treeFromList [<span class="st">&quot;I&quot;</span>,<span class="st">&quot;HEARD&quot;</span>]</span>
<span id="cb112-6"><a href="#cb112-6" aria-hidden="true" tabindex="-1"></a>             , <span class="fu">map</span> treeFromList [<span class="st">&quot;YOU&quot;</span>,<span class="st">&quot;LIKE&quot;</span>,<span class="st">&quot;TREES&quot;</span>] ]))</span></code></pre></div>
<p>Y produce:</p>
<pre><code>Binary tree of Binary trees of Char binary trees:
&lt; &lt; &lt; &#39;Y&#39;
: : : `--&#39;O&#39;
: : `--&lt; &#39;D&#39;
: :    : |--&#39;A&#39;
: :    : `--&#39;W&#39;
: :    :    `--&#39;G&#39;
: |--&lt; &lt; &#39;I&#39;
: |  : `--&lt; &#39;H&#39;
: |  :    : |--&#39;E&#39;
: |  :    : |  `--&#39;A&#39;
: |  :    : |     `--&#39;D&#39;
: |  :    : `--&#39;R&#39;
: `--&lt; &lt; &#39;Y&#39;
:    : : `--&#39;O&#39;
:    : :    `--&#39;U&#39;
:    : `--&lt; &#39;L&#39;
:    :    : `--&#39;I&#39;
:    :    :    |--&#39;E&#39;
:    :    :    `--&#39;K&#39;
:    :    `--&lt; &#39;T&#39;
:    :       : `--&#39;R&#39;
:    :       :    |--&#39;E&#39;
:    :       :    `--&#39;S&#39;</code></pre>
<p>Nota como arboles duplicados no son insertados; solo hay un árbol
correspondiente a <code>"I", "HEARD"</code>. Podemos tener esto (casi)
gratuitamente, por que hemos declarado que el tipo árbol es una instancia
de <code>Eq</code>.</p>
<p>Mira cuan genial es esta estructura: Podemos hacer arboles que contienen
no solo enteros, cadenas y caracteres, sino también arboles. Y podemos
incluso hacer un árbol que contenga arboles de arboles!</p>
<h2 id="estructuras-infinitas">Estructuras infinitas</h2>
<p><img src="/img/haskellhard/shot10.jpg" /></p>
<p>Es común escuchar que Haskell es perezoso.</p>
<p>De hecho, si se es un poco pedante, se debería decir que <a href="http://www.haskell.org/haskellwiki/Lazy_vs._non-strict">Haskell es
no-estricto.</a>. Pereza es
solo una implementación común de lenguajes no-estrictos.</p>
<p>¿Pero qué significa “no-estricto”? Desde la wiki de Haskell:</p>
<pre><code>Reduction (the mathematical term for evaluation) proceeds from the outside in.

so if you have (a+(b*c)) then you first reduce + first, then you reduce the inner (b*c)</code></pre>
<p>Por ejemplo en Haskell se puede hacer:</p>
<div class="sourceCode" id="cb115"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb115-1"><a href="#cb115-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- numbers = [1,2,..]</span></span>
<span id="cb115-2"><a href="#cb115-2" aria-hidden="true" tabindex="-1"></a><span class="ot">numbers ::</span> [<span class="dt">Integer</span>]</span>
<span id="cb115-3"><a href="#cb115-3" aria-hidden="true" tabindex="-1"></a>numbers <span class="ot">=</span> <span class="dv">0</span><span class="op">:</span><span class="fu">map</span> (<span class="dv">1</span><span class="op">+</span>) numbers</span>
<span id="cb115-4"><a href="#cb115-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb115-5"><a href="#cb115-5" aria-hidden="true" tabindex="-1"></a>take&#39; n [] <span class="ot">=</span> []</span>
<span id="cb115-6"><a href="#cb115-6" aria-hidden="true" tabindex="-1"></a>take&#39; <span class="dv">0</span> l <span class="ot">=</span> []</span>
<span id="cb115-7"><a href="#cb115-7" aria-hidden="true" tabindex="-1"></a>take&#39; n (x<span class="op">:</span>xs) <span class="ot">=</span> x<span class="op">:</span>take&#39; (n<span class="op">-</span><span class="dv">1</span>) xs</span>
<span id="cb115-8"><a href="#cb115-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb115-9"><a href="#cb115-9" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> <span class="op">$</span> take&#39; <span class="dv">10</span> numbers</span></code></pre></div>
<p>Y se detiene.</p>
<p>¿Cómo?</p>
<p>En lugar de intentar evaluar <code>numbers</code> por completo, evalúa los elementos solo
cunado se los necesita.</p>
<p>También, nótese que en Haskell hay una notación para listas infinitas.</p>
<div class="sourceCode" id="cb116"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb116-1"><a href="#cb116-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span><span class="op">..</span>]   ⇔ [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span><span class="op">...</span>]</span>
<span id="cb116-2"><a href="#cb116-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">3</span><span class="op">..</span>] ⇔ [<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">5</span>,<span class="dv">7</span>,<span class="dv">9</span>,<span class="dv">11</span><span class="op">...</span>]</span></code></pre></div>
<p>Y la mayoría de las funciones funcionarán con ellas. También, hay una función
<code>take</code> que es equivalente a nuestro <code>take'</code></p>
<p>Supón que queremos un árbol ordenado binario. Aquí hay una árbol binario
infinito.</p>
<div class="sourceCode" id="cb117"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb117-1"><a href="#cb117-1" aria-hidden="true" tabindex="-1"></a>nullTree <span class="ot">=</span> <span class="dt">Node</span> <span class="dv">0</span> nullTree nullTree</span></code></pre></div>
<p>Un árbol binario completo donde cada nodo es iguala a 0. Ahora probaré que
se puede manipular este objeto usando la siguiente función:</p>
<div class="sourceCode" id="cb118"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb118-1"><a href="#cb118-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- take all element of a BinTree</span></span>
<span id="cb118-2"><a href="#cb118-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- up to some depth</span></span>
<span id="cb118-3"><a href="#cb118-3" aria-hidden="true" tabindex="-1"></a>treeTakeDepth _ <span class="dt">Empty</span> <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb118-4"><a href="#cb118-4" aria-hidden="true" tabindex="-1"></a>treeTakeDepth <span class="dv">0</span> _     <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb118-5"><a href="#cb118-5" aria-hidden="true" tabindex="-1"></a>treeTakeDepth n (<span class="dt">Node</span> x left right) <span class="ot">=</span> <span class="kw">let</span></span>
<span id="cb118-6"><a href="#cb118-6" aria-hidden="true" tabindex="-1"></a>          nl <span class="ot">=</span> treeTakeDepth (n<span class="op">-</span><span class="dv">1</span>) left</span>
<span id="cb118-7"><a href="#cb118-7" aria-hidden="true" tabindex="-1"></a>          nr <span class="ot">=</span> treeTakeDepth (n<span class="op">-</span><span class="dv">1</span>) right</span>
<span id="cb118-8"><a href="#cb118-8" aria-hidden="true" tabindex="-1"></a>          <span class="kw">in</span></span>
<span id="cb118-9"><a href="#cb118-9" aria-hidden="true" tabindex="-1"></a>              <span class="dt">Node</span> x nl nr</span></code></pre></div>
<p>Mira lo que ocurre con este programa:</p>
<div class="sourceCode" id="cb119"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb119-1"><a href="#cb119-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> <span class="op">$</span> treeTakeDepth <span class="dv">4</span> nullTree</span></code></pre></div>
<p>Este código compila, se ejecuta y se detiene dando el siguiente
resultado:</p>
<pre><code>&lt;  0
: |-- 0
: |  |-- 0
: |  |  |-- 0
: |  |  `-- 0
: |  `-- 0
: |     |-- 0
: |     `-- 0
: `-- 0
:    |-- 0
:    |  |-- 0
:    |  `-- 0
:    `-- 0
:       |-- 0
:       `-- 0</code></pre>
<p>Solo para calentar tus neuronas, hagamos un árbol más interesante:</p>
<div class="sourceCode" id="cb121"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb121-1"><a href="#cb121-1" aria-hidden="true" tabindex="-1"></a>iTree <span class="ot">=</span> <span class="dt">Node</span> <span class="dv">0</span> (dec iTree) (inc iTree)</span>
<span id="cb121-2"><a href="#cb121-2" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb121-3"><a href="#cb121-3" aria-hidden="true" tabindex="-1"></a>           dec (<span class="dt">Node</span> x l r) <span class="ot">=</span> <span class="dt">Node</span> (x<span class="op">-</span><span class="dv">1</span>) (dec l) (dec r)</span>
<span id="cb121-4"><a href="#cb121-4" aria-hidden="true" tabindex="-1"></a>           inc (<span class="dt">Node</span> x l r) <span class="ot">=</span> <span class="dt">Node</span> (x<span class="op">+</span><span class="dv">1</span>) (inc l) (inc r)</span></code></pre></div>
<p>Otra forma de crear ese árbol es usar una función de orden superior. Esta
función debería ser similar a <code>map</code>, pero debería funcionar en <code>BinTree</code> en
lugar de una lista.
Aquí está la función:</p>
<div class="sourceCode" id="cb122"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb122-1"><a href="#cb122-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- apply a function to each node of Tree</span></span>
<span id="cb122-2"><a href="#cb122-2" aria-hidden="true" tabindex="-1"></a><span class="ot">treeMap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">BinTree</span> a <span class="ot">-&gt;</span> <span class="dt">BinTree</span> b</span>
<span id="cb122-3"><a href="#cb122-3" aria-hidden="true" tabindex="-1"></a>treeMap f <span class="dt">Empty</span> <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb122-4"><a href="#cb122-4" aria-hidden="true" tabindex="-1"></a>treeMap f (<span class="dt">Node</span> x left right) <span class="ot">=</span> <span class="dt">Node</span> (f x)</span>
<span id="cb122-5"><a href="#cb122-5" aria-hidden="true" tabindex="-1"></a>                                     (treeMap f left)</span>
<span id="cb122-6"><a href="#cb122-6" aria-hidden="true" tabindex="-1"></a>                                     (treeMap f right)</span></code></pre></div>
<p>Nota: No hablaré más de esto aquí. Si estas interesado en la generalización de
<code>map</code> a otras estructuras de datos, busca <em>functor</em> y <code>fmap</code>.</p>
<p>Nuestra definición es ahora:</p>
<div class="sourceCode" id="cb123"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb123-1"><a href="#cb123-1" aria-hidden="true" tabindex="-1"></a><span class="ot">infTreeTwo ::</span> <span class="dt">BinTree</span> <span class="dt">Int</span></span>
<span id="cb123-2"><a href="#cb123-2" aria-hidden="true" tabindex="-1"></a>infTreeTwo <span class="ot">=</span> <span class="dt">Node</span> <span class="dv">0</span> (treeMap (\x <span class="ot">-&gt;</span> x<span class="op">-</span><span class="dv">1</span>) infTreeTwo)</span>
<span id="cb123-3"><a href="#cb123-3" aria-hidden="true" tabindex="-1"></a>                    (treeMap (\x <span class="ot">-&gt;</span> x<span class="op">+</span><span class="dv">1</span>) infTreeTwo)</span></code></pre></div>
<p>Observa el resultado de</p>
<div class="sourceCode" id="cb124"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb124-1"><a href="#cb124-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> <span class="op">$</span> treeTakeDepth <span class="dv">4</span> infTreeTwo</span></code></pre></div>
<pre><code>&lt;  0
: |-- -1
: |  |-- -2
: |  |  |-- -3
: |  |  `-- -1
: |  `-- 0
: |     |-- -1
: |     `-- 1
: `-- 1
:    |-- 0
:    |  |-- -1
:    |  `-- 1
:    `-- 2
:       |-- 1
:       `-- 3</code></pre>
<h1 id="parte-infernalmente-difícil">Parte infernalmente difícil</h1>
<p>Felicitaciones por llegar tan lejos! Ahora, algunas de las cosas realmente
difíciles pueden empezar.</p>
<p>Si eres como yo, ya deberías comprender el estilo funcional. También deberías
entender un poco más de las ventajas de la <em>pereza</em> (Laziness) por
defecto. Pero también deberías NO comprender aún como empezar a escribir un
programa real. Y en particular:</p>
<ul>
<li>¿Cómo se lidia con los efectos?</li>
<li>¿Por qué hay una notación extraña parecida a la imperativa para lidiar con
Entrada/Salida (IO)?</li>
</ul>
<p>Prepárate, las respuestas pueden ser complejas. Pero son realmente
gratificantes.</p>
<h2 id="lidiando-con-io-entradasalida">Lidiando con IO (Entrada/Salida)</h2>
<p><img src="/img/haskellhard/shot11.jpg" /></p>
<p><em>TL;DR</em>:</p>
<p>Una función típica haciendo IO es muy parecida a un programa imperativo:</p>
<div class="sourceCode" id="cb126"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb126-1"><a href="#cb126-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">IO</span> a</span>
<span id="cb126-2"><a href="#cb126-2" aria-hidden="true" tabindex="-1"></a>f <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb126-3"><a href="#cb126-3" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> action1</span>
<span id="cb126-4"><a href="#cb126-4" aria-hidden="true" tabindex="-1"></a>  action2 x</span>
<span id="cb126-5"><a href="#cb126-5" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> action3</span>
<span id="cb126-6"><a href="#cb126-6" aria-hidden="true" tabindex="-1"></a>  action4 x y</span></code></pre></div>
<ul>
<li>Para asignar un valor a un objeto se usa <code>&lt;-</code>.</li>
<li>El tipo de cada linea es <code>IO *</code>; en este ejemplo:</li>
<li><code>action1 :: IO b</code></li>
<li><code>action2 x :: IO ()</code></li>
<li><code>action3 :: IO c</code></li>
<li><code>action4 x y :: IO a</code></li>
<li><code>x :: b</code>, <code>y :: c</code></li>
<li>Algunos objetos tienen el tipo <code>IO a</code>, esto debería ayudar a elegir. En
particular no se deberían usar funciones puras aquí. Para usar funciones
se puede hacer <code>action2 (purefunction x)</code> por ejemplo.</li>
</ul>
<p>En esta sección,, explicaré como usar IO, no como funciona. Se verá como
Haskell separa la partes puras del programa de las impuras.</p>
<p>No te detengas por que intentas comprender los detalles de la sintaxis. Las
respuestas vendrán en la siguiente sección.</p>
<p>Qué queremos lograr?</p>
<pre><code>Pedir al usuario que ingrese una lista de números. Imprimir la suma de los
números.</code></pre>
<div class="sourceCode" id="cb128"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb128-1"><a href="#cb128-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> [<span class="dt">Integer</span>]</span>
<span id="cb128-2"><a href="#cb128-2" aria-hidden="true" tabindex="-1"></a>toList input <span class="ot">=</span> <span class="fu">read</span> (<span class="st">&quot;[&quot;</span> <span class="op">++</span> input <span class="op">++</span> <span class="st">&quot;]&quot;</span>)</span>
<span id="cb128-3"><a href="#cb128-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb128-4"><a href="#cb128-4" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb128-5"><a href="#cb128-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (separated by comma):&quot;</span></span>
<span id="cb128-6"><a href="#cb128-6" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb128-7"><a href="#cb128-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> <span class="fu">sum</span> (toList input)</span></code></pre></div>
<p>Debería ser sencillo comprender el comportamiento de este programa.
Analicemos los tipos en más detalle.</p>
<div class="sourceCode" id="cb129"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb129-1"><a href="#cb129-1" aria-hidden="true" tabindex="-1"></a><span class="fu">putStrLn</span><span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb129-2"><a href="#cb129-2" aria-hidden="true" tabindex="-1"></a><span class="fu">getLine</span><span class="ot">  ::</span> <span class="dt">IO</span> <span class="dt">String</span></span>
<span id="cb129-3"><a href="#cb129-3" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span><span class="ot">    ::</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span></code></pre></div>
<p>O más interesante, notamos que cada expresión en el bloque <code>do</code> tiene
el tipo <code>IO a</code></p>
<div class="sourceCode" id="cb130"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb130-1"><a href="#cb130-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb130-2"><a href="#cb130-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter ... &quot;</span><span class="ot"> ::</span> <span class="dt">IO</span> ()</span>
<span id="cb130-3"><a href="#cb130-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  getLine               ::</span> <span class="dt">IO</span> <span class="dt">String</span></span>
<span id="cb130-4"><a href="#cb130-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="dt">Something</span><span class="ot">       ::</span> <span class="dt">IO</span> ()</span></code></pre></div>
<p>También debemos prestar atención a los efectos del símbolo <code>&lt;-</code>.</p>
<div class="sourceCode" id="cb131"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb131-1"><a href="#cb131-1" aria-hidden="true" tabindex="-1"></a><span class="kw">do</span></span>
<span id="cb131-2"><a href="#cb131-2" aria-hidden="true" tabindex="-1"></a>    x <span class="ot">&lt;-</span> something</span></code></pre></div>
<p>Si <code>something :: IO a</code> entonces <code>x :: a</code>.</p>
<p>Otra cosa importante a notar sobre usar <code>IO</code>: Todas las lineas en un
bloque <code>do</code> deben ser de una de dos posibles formas:</p>
<div class="sourceCode" id="cb132"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb132-1"><a href="#cb132-1" aria-hidden="true" tabindex="-1"></a><span class="ot">action1             ::</span> <span class="dt">IO</span> a</span>
<span id="cb132-2"><a href="#cb132-2" aria-hidden="true" tabindex="-1"></a>                    <span class="co">-- in this case, generally a = ()</span></span></code></pre></div>
<p>O</p>
<div class="sourceCode" id="cb133"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb133-1"><a href="#cb133-1" aria-hidden="true" tabindex="-1"></a>value <span class="ot">&lt;-</span> action2    <span class="co">-- where</span></span>
<span id="cb133-2"><a href="#cb133-2" aria-hidden="true" tabindex="-1"></a>                    <span class="co">-- action2 :: IO b</span></span>
<span id="cb133-3"><a href="#cb133-3" aria-hidden="true" tabindex="-1"></a>                    <span class="co">-- value   :: b</span></span></code></pre></div>
<p>Estos dos tipos de linea corresponderán a dos formas diferentes de
secuenciar acciones. El significado de esta sentencia debería quedar clara para
el final de la siguiente sección.</p>
<p>Ahora veamos como se comporta el programa. Por ejemplo, qué ocurre si el
usuario ingresa algo extraño? Intentemos:</p>
<pre><code>% runghc 02_progressive_io_example.lhs
    Enter a list of numbers (separated by comma):
    foo
    Prelude.read: no parse</code></pre>
<p>Un horrible mensaje de error y un fallo! Nuestra primera mejora será
responder con un mensaje más amigable.</p>
<p>Para hacerlo, debemos detectar que algo salió mal. Aquí hay una forma de
hacerlo: usar el tipo <code>Maybe</code>. Este es un tipo muy común en Haskell.</p>
<div class="sourceCode" id="cb135"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb135-1"><a href="#cb135-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span></span></code></pre></div>
<p>¿Qué es esto? <code>Maybe</code> es un tipo que toma un parámetro. Su definición es:</p>
<div class="sourceCode" id="cb136"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb136-1"><a href="#cb136-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Maybe</span> a <span class="ot">=</span> <span class="dt">Nothing</span> <span class="op">|</span> <span class="dt">Just</span> a</span></code></pre></div>
<p>Esta es una forma muy agradable de decir que hubo un error mientras se
intentaba crear/computar un valor. La función <code>maybeRead</code> es un gran ejemplo de
esto. Esta es una función similar a la función <code>read</code>[^4], pero si algo sale mal
el valor retornado es <code>Nothing</code>. Si el valor es correcto, retorna <code>Just &lt;el valor&gt;</code>. No intentes comprender mucho de esta función. Se usa una función de
nivel menor a <code>read</code>; <code>reads</code>.</p>
<div class="sourceCode" id="cb137"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb137-1"><a href="#cb137-1" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeRead ::</span> <span class="dt">Read</span> a <span class="ot">=&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb137-2"><a href="#cb137-2" aria-hidden="true" tabindex="-1"></a>maybeRead s <span class="ot">=</span> <span class="kw">case</span> <span class="fu">reads</span> s <span class="kw">of</span></span>
<span id="cb137-3"><a href="#cb137-3" aria-hidden="true" tabindex="-1"></a>                  [(x,<span class="st">&quot;&quot;</span>)]    <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
<span id="cb137-4"><a href="#cb137-4" aria-hidden="true" tabindex="-1"></a>                  _           <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>Ahora para estar un poco más seguros, definimos una función que va así: Si la
cadena tiene el formato incorrecto, se retorna <code>Nothing</code>. Caso contrario, por
ejemplo “1,2,3”, se retorna <code>Just [1,2,3]</code>.</p>
<div class="sourceCode" id="cb138"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb138-1"><a href="#cb138-1" aria-hidden="true" tabindex="-1"></a><span class="ot">getListFromString ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> [<span class="dt">Integer</span>]</span>
<span id="cb138-2"><a href="#cb138-2" aria-hidden="true" tabindex="-1"></a>getListFromString str <span class="ot">=</span> maybeRead <span class="op">$</span> <span class="st">&quot;[&quot;</span> <span class="op">++</span> str <span class="op">++</span> <span class="st">&quot;]&quot;</span></span></code></pre></div>
<p>Simplemente tenemos que probar el valor en nuestra función principal <code>main</code>.</p>
<div class="sourceCode" id="cb139"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb139-1"><a href="#cb139-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb139-2"><a href="#cb139-2" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb139-3"><a href="#cb139-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (separated by comma):&quot;</span></span>
<span id="cb139-4"><a href="#cb139-4" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb139-5"><a href="#cb139-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb139-6"><a href="#cb139-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb139-7"><a href="#cb139-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Just</span> l  <span class="ot">-&gt;</span> <span class="fu">print</span> (<span class="fu">sum</span> l)</span>
<span id="cb139-8"><a href="#cb139-8" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;Bad format. Good Bye.&quot;</span></span></code></pre></div>
<p>En caso de error, mostramos un mensaje de error amigable.</p>
<p>Nótese que el tipo de cada expresión en el bloque <code>do</code> de main permanece en
la forma <code>IO a</code>. La única construcción extraña es <code>error</code>. Aquí solo diré que
<code>error msg</code> toma el tipo necesario (aquí <code>IO ()</code>).</p>
<p>Una cosa importante es el tipo de todas las funciones definidas hasta ahora.
Solo hay una función que contiene <code>IO</code> en su tipo: <code>main</code>. Esto significa que
main es impura. Pero main usa <code>getListFromString</code> que es pura. Entonces
queda claro solo observando los tipos declarados que funciones son
puras y cuales son impuras.</p>
<p>¿Por qué importa la pureza? Entre las muchas ventajas, aquí hay tres:</p>
<ul>
<li>Es más fácil pensar sobre una pieza de código puro que código impuro</li>
<li>La pureza te protege de los errores difícil de reproducir debido a los efectos
secundarios.</li>
<li>Se pueden evaluar funciones puras en cualquier orden o en paralelo sin riesgo.</li>
</ul>
<p>Por esto se debe poner todo el código posible dentro de funciones puras.</p>
<p>Nuestra siguiente iteración será pedir al usuario una y otra vez hasta que
introduzca una respuesta valida.</p>
<p>Mantenemos la primera parte:</p>
<div class="sourceCode" id="cb140"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb140-1"><a href="#cb140-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span></span>
<span id="cb140-2"><a href="#cb140-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb140-3"><a href="#cb140-3" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeRead ::</span> <span class="dt">Read</span> a <span class="ot">=&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb140-4"><a href="#cb140-4" aria-hidden="true" tabindex="-1"></a>maybeRead s <span class="ot">=</span> <span class="kw">case</span> <span class="fu">reads</span> s <span class="kw">of</span></span>
<span id="cb140-5"><a href="#cb140-5" aria-hidden="true" tabindex="-1"></a>                  [(x,<span class="st">&quot;&quot;</span>)]    <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
<span id="cb140-6"><a href="#cb140-6" aria-hidden="true" tabindex="-1"></a>                  _           <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb140-7"><a href="#cb140-7" aria-hidden="true" tabindex="-1"></a><span class="ot">getListFromString ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> [<span class="dt">Integer</span>]</span>
<span id="cb140-8"><a href="#cb140-8" aria-hidden="true" tabindex="-1"></a>getListFromString str <span class="ot">=</span> maybeRead <span class="op">$</span> <span class="st">&quot;[&quot;</span> <span class="op">++</span> str <span class="op">++</span> <span class="st">&quot;]&quot;</span></span></code></pre></div>
<p>Ahora creamos una función que pregunte al usuario la lista de enteros
hasta que la entrada sea correcta.</p>
<div class="sourceCode" id="cb141"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb141-1"><a href="#cb141-1" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">IO</span> [<span class="dt">Integer</span>]</span>
<span id="cb141-2"><a href="#cb141-2" aria-hidden="true" tabindex="-1"></a>askUser <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb141-3"><a href="#cb141-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (separated by comma):&quot;</span></span>
<span id="cb141-4"><a href="#cb141-4" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb141-5"><a href="#cb141-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb141-6"><a href="#cb141-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb141-7"><a href="#cb141-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Just</span> l  <span class="ot">-&gt;</span> <span class="fu">return</span> l</span>
<span id="cb141-8"><a href="#cb141-8" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Nothing</span> <span class="ot">-&gt;</span> askUser</span></code></pre></div>
<p>Esta función es de tipo <code>IO [Integer]</code>. Este tipo significa que obtendremos
un valor de tipo <code>[Integer]</code> a través de acciones de entrada/salida (IO).
Algunas personas podrían explicar mientras sacuden las manos:</p>
<blockquote>
<p>Esto es un <code>[Integer]</code> dentro de un <code>IO</code></p>
</blockquote>
<p>Si quieres comprender los detalles detrás de todo esto, tendrás que leer la
siguiente sección. Pero en realidad, si solamente quieres saber como <em>usar</em>
IO solo practica un poco y recuerda pensar sobre el tipo.</p>
<p>Finalmente la función main es mucho más simple:</p>
<div class="sourceCode" id="cb142"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb142-1"><a href="#cb142-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb142-2"><a href="#cb142-2" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb142-3"><a href="#cb142-3" aria-hidden="true" tabindex="-1"></a>  list <span class="ot">&lt;-</span> askUser</span>
<span id="cb142-4"><a href="#cb142-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> <span class="fu">sum</span> list</span></code></pre></div>
<p>Hemos terminado con la introducción a la entrada/salida <code>IO</code>. Fue rápido.
Estas son las principales cosas que hay que recordar.</p>
<ul>
<li><p>En el bloque <code>do</code>, cada expresión debe tener el tipo <code>IO a</code>. Así que estas
limitado en el numero de expresiones disponibles. Por ejemplo, <code>getLine</code>,
<code>print</code>, <code>putStrLn</code>, etc…</p></li>
<li><p>Intenta independizar las funciones puras todo lo posible.</p></li>
<li><p>El tipo <code>IO a</code> significa: una <strong>acción</strong> IO que retorna un elemento de
tipo <code>a</code>. <code>IO</code> representa <em>acciones</em>; por dentro, <code>IO a</code> es el tipo de
una función. Lee la siguiente sección si te da curiosidad.</p>
<p>Si practicas un poco, deberías ser capaz de usar <code>IO</code>.</p>
<p>Ejercicios:
* Hacer un programa que sume todos sus argumentos.
Pista: Usa la función <code>getArgs</code>.</p></li>
</ul>
<h2 id="el-truco-de-la-entradasalida-io-explicado">El truco de la entrada/salida (IO) explicado</h2>
<p><img src="/img/haskellhard/shot12.jpg" /></p>
<p>TL;DR*:</p>
<p>Para separar las partes puras de las impuras, <code>main</code> es la función que
modifica el estado del mundo exterior</p>
<div class="sourceCode" id="cb143"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb143-1"><a href="#cb143-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">World</span> <span class="ot">-&gt;</span> <span class="dt">World</span></span></code></pre></div>
<p>Una función garantiza que solo tendrá efectos secundarios si tiene este tipo.
Pero observa una función <code>main</code> típica:</p>
<div class="sourceCode" id="cb144"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb144-1"><a href="#cb144-1" aria-hidden="true" tabindex="-1"></a>main w0 <span class="ot">=</span></span>
<span id="cb144-2"><a href="#cb144-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (v1,w1) <span class="ot">=</span> action1 w0 <span class="kw">in</span></span>
<span id="cb144-3"><a href="#cb144-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (v2,w2) <span class="ot">=</span> action2 v1 w1 <span class="kw">in</span></span>
<span id="cb144-4"><a href="#cb144-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (v3,w3) <span class="ot">=</span> action3 v2 w2 <span class="kw">in</span></span>
<span id="cb144-5"><a href="#cb144-5" aria-hidden="true" tabindex="-1"></a>    action4 v3 w3</span></code></pre></div>
<p>Tenemos varios elementos temporales (<code>w1</code>, <code>w2</code>, <code>w3</code>) que deben ser pasados a
la siguiente sección.</p>
<p>Creamos una función <code>bind</code> o <code>(&gt;&gt;=)</code>. Con <code>bind</code> ya no necesitamos nombres
temporales.</p>
<div class="sourceCode" id="cb145"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb145-1"><a href="#cb145-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span></span>
<span id="cb145-2"><a href="#cb145-2" aria-hidden="true" tabindex="-1"></a>  action1 <span class="op">&gt;&gt;=</span> action2 <span class="op">&gt;&gt;=</span> action3 <span class="op">&gt;&gt;=</span> action4</span></code></pre></div>
<p>Bonus: Haskell tiene azúcar sintáctica para nosotros:</p>
<div class="sourceCode" id="cb146"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb146-1"><a href="#cb146-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb146-2"><a href="#cb146-2" aria-hidden="true" tabindex="-1"></a>  v1 <span class="ot">&lt;-</span> action1</span>
<span id="cb146-3"><a href="#cb146-3" aria-hidden="true" tabindex="-1"></a>  v2 <span class="ot">&lt;-</span> action2 v1</span>
<span id="cb146-4"><a href="#cb146-4" aria-hidden="true" tabindex="-1"></a>  v3 <span class="ot">&lt;-</span> action3 v2</span>
<span id="cb146-5"><a href="#cb146-5" aria-hidden="true" tabindex="-1"></a>  action4 v3</span></code></pre></div>
<p>Por qué usamos esta sintaxis extraña, y qué es exactamente este tipo <code>IO</code>?
Parece algo mágico.</p>
<p>Por ahora vamos a olvidarnos sobre las partes puras de nuestro programa,
y enfocarnos en las partes impuras.</p>
<div class="sourceCode" id="cb147"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb147-1"><a href="#cb147-1" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">IO</span> [<span class="dt">Integer</span>]</span>
<span id="cb147-2"><a href="#cb147-2" aria-hidden="true" tabindex="-1"></a>askUser <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb147-3"><a href="#cb147-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (separated by commas):&quot;</span></span>
<span id="cb147-4"><a href="#cb147-4" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb147-5"><a href="#cb147-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb147-6"><a href="#cb147-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb147-7"><a href="#cb147-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Just</span> l  <span class="ot">-&gt;</span> <span class="fu">return</span> l</span>
<span id="cb147-8"><a href="#cb147-8" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Nothing</span> <span class="ot">-&gt;</span> askUser</span>
<span id="cb147-9"><a href="#cb147-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb147-10"><a href="#cb147-10" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb147-11"><a href="#cb147-11" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb147-12"><a href="#cb147-12" aria-hidden="true" tabindex="-1"></a>  list <span class="ot">&lt;-</span> askUser</span>
<span id="cb147-13"><a href="#cb147-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> <span class="fu">sum</span> list</span></code></pre></div>
<p>Primera cuestión remarcarle: esto parece un programa imperativo. Haskell es
lo suficientemente poderoso para hacer código impuro lucir imperativo.
Por ejemplo, si deseas podrías crear un <code>while</code> en Haskell. De hecho, para
lidiar con entrada/salida, un estilo imperativo es generalmente más apropiado.</p>
<p>Pero deberías haber notado que esta notación es un poco inusual. Aquí el por
qué, en detalle.</p>
<p>En un lenguaje imperativo el estado del mundo puede ser visto como una gran
variable global oculta. Esta variable oculta es accesible por todas las
funciones del lenguaje. Por ejemplo, se pude leer desde un fichero en
cualquier función. Sea que el fichero exista o no es una diferencia en el
posible estado que el mundo puede tomar.</p>
<p>En Haskell este estado no es oculto. Más bien, se dice
<em>explicitamemten</em> que <code>main</code> es una función que puede <em>potencialmente</em>
cambiar el estado del mundo. Su tipo es como:</p>
<div class="sourceCode" id="cb148"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb148-1"><a href="#cb148-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">World</span> <span class="ot">-&gt;</span> <span class="dt">World</span></span></code></pre></div>
<p>No todas las funciones pueden tener acceso a esta variable. Aquellas que tienen
acceso son impuras. Funciones a las que no se les provee esta variable
del mundo son puras[^5].</p>
<p>Haskell considera el estado del mundo exterior como una variable de enterada a
<code>main</code>. Pero el tipo real de main es más parecido a[^6]:</p>
<div class="sourceCode" id="cb149"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb149-1"><a href="#cb149-1" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">World</span> <span class="ot">-&gt;</span> ((),<span class="dt">World</span>)</span></code></pre></div>
<p>El tipo <code>()</code> es el tipo unitario. Nada que ver aquí.</p>
<p>Ahora escribamos nuestra función principal con esto en mente:</p>
<div class="sourceCode" id="cb150"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb150-1"><a href="#cb150-1" aria-hidden="true" tabindex="-1"></a>main w0 <span class="ot">=</span></span>
<span id="cb150-2"><a href="#cb150-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (list,w1) <span class="ot">=</span> askUser w0 <span class="kw">in</span></span>
<span id="cb150-3"><a href="#cb150-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (x,w2) <span class="ot">=</span> <span class="fu">print</span> (<span class="fu">sum</span> list,w1) <span class="kw">in</span></span>
<span id="cb150-4"><a href="#cb150-4" aria-hidden="true" tabindex="-1"></a>    x</span></code></pre></div>
<p>Primero, notamos que todas las funciones que tienen efectos secundarios
deben tener el tipo:</p>
<div class="sourceCode" id="cb151"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb151-1"><a href="#cb151-1" aria-hidden="true" tabindex="-1"></a><span class="dt">World</span> <span class="ot">-&gt;</span> (a,<span class="dt">World</span>)</span></code></pre></div>
<p>Donde <code>a</code> es el tipo del resultado. Por ejemplo, una función <code>getChar</code>
debería tener el tipo <code>World -&gt; (Char, World)</code>.</p>
<p>Otra cosa a notar es el truco para fijar el orden de la evaluación. En
Haskell, para evaluar <code>f a b</code>, tienes varias opciones:</p>
<ul>
<li>primero evaluar <code>a</code> luego <code>b</code> luego <code>f a b</code></li>
<li>primero evaluar <code>b</code> luego <code>a</code> luego <code>f a b</code></li>
<li>evaluar <code>a</code> y <code>b</code> en paralelo y luego <code>f a b</code></li>
</ul>
<p>Esto es verdad por que estamos trabajando en la parte pura del lenguaje.</p>
<p>Ahora, si tomas la función <code>main</code>, está claro que debes evaluar la primera
linea antes de la segunda puesto que para evaluar la segunda linea es
necesario obtener el parámetro dado en la evaluación de la primera linea.</p>
<p>Este truco funciona bien. El compilador proveerá en cada paso un puntero a
un nuevo identificador del mundo real. Por dentro, <code>print</code> se evaluará
como:</p>
<ul>
<li>imprimir algo en la pantalla</li>
<li>modifica el <em>id</em> del mundo exterior</li>
<li>evaluar como <code>((),new world id)</code>.</li>
</ul>
<p>Ahora, si miras el estilo de la función main, es claramente incómodo. Intentemos
hacer lo mismo a la función askUser:</p>
<div class="sourceCode" id="cb152"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb152-1"><a href="#cb152-1" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">World</span> <span class="ot">-&gt;</span> ([<span class="dt">Integer</span>],<span class="dt">World</span>)</span></code></pre></div>
<p>Antes:</p>
<div class="sourceCode" id="cb153"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb153-1"><a href="#cb153-1" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">IO</span> [<span class="dt">Integer</span>]</span>
<span id="cb153-2"><a href="#cb153-2" aria-hidden="true" tabindex="-1"></a>askUser <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb153-3"><a href="#cb153-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers:&quot;</span></span>
<span id="cb153-4"><a href="#cb153-4" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb153-5"><a href="#cb153-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb153-6"><a href="#cb153-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb153-7"><a href="#cb153-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Just</span> l  <span class="ot">-&gt;</span> <span class="fu">return</span> l</span>
<span id="cb153-8"><a href="#cb153-8" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Nothing</span> <span class="ot">-&gt;</span> askUser</span></code></pre></div>
<p>Después:</p>
<div class="sourceCode" id="cb154"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb154-1"><a href="#cb154-1" aria-hidden="true" tabindex="-1"></a>askUser w0 <span class="ot">=</span></span>
<span id="cb154-2"><a href="#cb154-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (_,w1)     <span class="ot">=</span> <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers:&quot;</span> <span class="kw">in</span></span>
<span id="cb154-3"><a href="#cb154-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (input,w2) <span class="ot">=</span> <span class="fu">getLine</span> w1 <span class="kw">in</span></span>
<span id="cb154-4"><a href="#cb154-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (l,w3)     <span class="ot">=</span> <span class="kw">case</span> getListFromString input <span class="kw">of</span></span>
<span id="cb154-5"><a href="#cb154-5" aria-hidden="true" tabindex="-1"></a>                      <span class="dt">Just</span> l   <span class="ot">-&gt;</span> (l,w2)</span>
<span id="cb154-6"><a href="#cb154-6" aria-hidden="true" tabindex="-1"></a>                      <span class="dt">Nothing</span>  <span class="ot">-&gt;</span> askUser w2</span>
<span id="cb154-7"><a href="#cb154-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb154-8"><a href="#cb154-8" aria-hidden="true" tabindex="-1"></a>        (l,w3)</span></code></pre></div>
<p>Esto es similar, pero incómodo. Mira todos esos nombres temporales <code>w?</code>.</p>
<p>La lección es: poner implementación <code>IO</code> en lenguajes funcionales puros es
incómodo!</p>
<p>Afortunadamente, hay una mejor forma de manejar este problema. Observamos
un patrón. Cada linea es de la forma:</p>
<div class="sourceCode" id="cb155"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb155-1"><a href="#cb155-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (y, w&#39;) <span class="ot">=</span> action x w <span class="kw">in</span></span></code></pre></div>
<p>Incluso si para alguna linea el primer argumento <code>x</code> no es necesario.
La salida es de tipo tupla, <code>(answer, newWorldValue)</code>. Cada función <code>f</code> debe
tener un tipo similar a:</p>
<div class="sourceCode" id="cb156"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb156-1"><a href="#cb156-1" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">World</span> <span class="ot">-&gt;</span> (a,<span class="dt">World</span>)</span></code></pre></div>
<p>No solo eso, también podemos notar que siempre seguimos el mismo patrón de
uso:</p>
<div class="sourceCode" id="cb157"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb157-1"><a href="#cb157-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (y,w1) <span class="ot">=</span> action1 w0 <span class="kw">in</span></span>
<span id="cb157-2"><a href="#cb157-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (z,w2) <span class="ot">=</span> action2 w1 <span class="kw">in</span></span>
<span id="cb157-3"><a href="#cb157-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (t,w3) <span class="ot">=</span> action3 w2 <span class="kw">in</span></span>
<span id="cb157-4"><a href="#cb157-4" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span></code></pre></div>
<p>Cada acción puede tomar de 0 a n parámetros. Y en particular, cada acción
puede tomar un parámetro del resultado de la linea anterior.</p>
<p>Por ejemplo, también podríamos tener:</p>
<div class="sourceCode" id="cb158"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb158-1"><a href="#cb158-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (_,w1) <span class="ot">=</span> action1 x w0   <span class="kw">in</span></span>
<span id="cb158-2"><a href="#cb158-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (z,w2) <span class="ot">=</span> action2 w1     <span class="kw">in</span></span>
<span id="cb158-3"><a href="#cb158-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (_,w3) <span class="ot">=</span> action3 x z w2 <span class="kw">in</span></span>
<span id="cb158-4"><a href="#cb158-4" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span></code></pre></div>
<p>Y por supuesto <code>actionN w :: (World) -&gt; (a,World)</code>.</p>
<p>IMPORTANTE: Hay dos patrones importantes a considerar:</p>
<div class="sourceCode" id="cb159"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb159-1"><a href="#cb159-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (x,w1) <span class="ot">=</span> action1 w0 <span class="kw">in</span></span>
<span id="cb159-2"><a href="#cb159-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (y,w2) <span class="ot">=</span> action2 x w1 <span class="kw">in</span></span></code></pre></div>
<p>Y</p>
<div class="sourceCode" id="cb160"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb160-1"><a href="#cb160-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (_,w1) <span class="ot">=</span> action1 w0 <span class="kw">in</span></span>
<span id="cb160-2"><a href="#cb160-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (y,w2) <span class="ot">=</span> action2 w1 <span class="kw">in</span></span></code></pre></div>
<p><img src="/img/haskellhard/shot13.jpg" /></p>
<p>Ahora, haremos un truco de magia. Haremos que el símbolo del mundo temporal
“desaparezca”. Haremos un <code>bind</code> a las dos lineas. Dinamos la función
<code>bind</code>. Su tipo es un poco intimidarte al principio:</p>
<div class="sourceCode" id="cb161"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb161-1"><a href="#cb161-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bind ::</span> (<span class="dt">World</span> <span class="ot">-&gt;</span> (a,<span class="dt">World</span>))</span>
<span id="cb161-2"><a href="#cb161-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> (<span class="dt">World</span> <span class="ot">-&gt;</span> (b,<span class="dt">World</span>)))</span>
<span id="cb161-3"><a href="#cb161-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> (<span class="dt">World</span> <span class="ot">-&gt;</span> (b,<span class="dt">World</span>))</span></code></pre></div>
<p>Pero recuerda que <code>(World -&gt; (a,World))</code> es un tipo para una acción <code>IO</code>. Ahora
renombremoslo por claridad:</p>
<div class="sourceCode" id="cb162"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb162-1"><a href="#cb162-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">IO</span> a <span class="ot">=</span> <span class="dt">World</span> <span class="ot">-&gt;</span> (a, <span class="dt">World</span>)</span></code></pre></div>
<p>Algunos ejemplos de funciones:</p>
<div class="sourceCode" id="cb163"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb163-1"><a href="#cb163-1" aria-hidden="true" tabindex="-1"></a><span class="fu">getLine</span><span class="ot"> ::</span> <span class="dt">IO</span> <span class="dt">String</span></span>
<span id="cb163-2"><a href="#cb163-2" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span><span class="ot"> ::</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span></code></pre></div>
<p><code>getLine</code> es una acción <code>IO</code> que toma el mundo exterior como parámetro
y retorna una tupla <code>(String,World)</code>. Esto se puede resumir como: <code>getLine</code>
es de tipo <code>IO String</code>, que también vemos como una acción IO que retornará
una cadena “embeded inside an IO”.</p>
<p>La función <code>print</code> también es interesante. Toma un argumento que puede ser
mostrado. De hecho puede tomar dos argumentos. El primero es el valor a
imprimir y el otro es el estado del mundo exterior. Luego retorna una tupla
de tipo <code>((),World)</code>. Esto significa que cambia el estado del mundo exterior,
pero no produce más información.</p>
<p>Este tipo nos ayuda a simplificar el tipo de <code>bind</code>:</p>
<div class="sourceCode" id="cb164"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb164-1"><a href="#cb164-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bind ::</span> <span class="dt">IO</span> a</span>
<span id="cb164-2"><a href="#cb164-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">IO</span> b)</span>
<span id="cb164-3"><a href="#cb164-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">IO</span> b</span></code></pre></div>
<p>Dice que <code>bind</code> toma dos acciones IO como parámetros y retorna otra acción IO.</p>
<p>Ahora, recuerda los patrones <em>importantes</em>. El primero era:</p>
<div class="sourceCode" id="cb165"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb165-1"><a href="#cb165-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (x,w1) <span class="ot">=</span> action1 w0 <span class="kw">in</span></span>
<span id="cb165-2"><a href="#cb165-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (y,w2) <span class="ot">=</span> action2 x w1 <span class="kw">in</span></span>
<span id="cb165-3"><a href="#cb165-3" aria-hidden="true" tabindex="-1"></a>(y,w2)</span></code></pre></div>
<p>Observa los tipos:</p>
<div class="sourceCode" id="cb166"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb166-1"><a href="#cb166-1" aria-hidden="true" tabindex="-1"></a><span class="ot">action1  ::</span> <span class="dt">IO</span> a</span>
<span id="cb166-2"><a href="#cb166-2" aria-hidden="true" tabindex="-1"></a><span class="ot">action2  ::</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> b</span>
<span id="cb166-3"><a href="#cb166-3" aria-hidden="true" tabindex="-1"></a>(y,w2)<span class="ot">   ::</span> <span class="dt">IO</span> b</span></code></pre></div>
<p>Resulta familiar?</p>
<div class="sourceCode" id="cb167"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb167-1"><a href="#cb167-1" aria-hidden="true" tabindex="-1"></a>(bind action1 action2) w0 <span class="ot">=</span></span>
<span id="cb167-2"><a href="#cb167-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> (x, w1) <span class="ot">=</span> action1 w0</span>
<span id="cb167-3"><a href="#cb167-3" aria-hidden="true" tabindex="-1"></a>        (y, w2) <span class="ot">=</span> action2 x w1</span>
<span id="cb167-4"><a href="#cb167-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span>  (y, w2)</span></code></pre></div>
<p>La idea es esconder el argumento del mundo exterior con esta función.
Hagamoslo: Como un ejemplo imagina que queremos simular:</p>
<div class="sourceCode" id="cb168"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb168-1"><a href="#cb168-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (line1,w1) <span class="ot">=</span> <span class="fu">getLine</span> w0 <span class="kw">in</span></span>
<span id="cb168-2"><a href="#cb168-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> ((),w2) <span class="ot">=</span> <span class="fu">print</span> line1 <span class="kw">in</span></span>
<span id="cb168-3"><a href="#cb168-3" aria-hidden="true" tabindex="-1"></a>((),w2)</span></code></pre></div>
<p>Ahora, usando la función bind:</p>
<div class="sourceCode" id="cb169"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb169-1"><a href="#cb169-1" aria-hidden="true" tabindex="-1"></a>(res,w2) <span class="ot">=</span> (bind <span class="fu">getLine</span> (\l <span class="ot">-&gt;</span> <span class="fu">print</span> l)) w0</span></code></pre></div>
<p>Como print es de tipo <code>(World -&gt; ((),World))</code>, sabemos que <code>res = ()</code> (tipo
nulo). Si no te diste cuenta de la magia aquí, intentemos con tres lineas esta
vez:</p>
<div class="sourceCode" id="cb170"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb170-1"><a href="#cb170-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (line1,w1) <span class="ot">=</span> <span class="fu">getLine</span> w0 <span class="kw">in</span></span>
<span id="cb170-2"><a href="#cb170-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (line2,w2) <span class="ot">=</span> <span class="fu">getLine</span> w1 <span class="kw">in</span></span>
<span id="cb170-3"><a href="#cb170-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> ((),w3) <span class="ot">=</span> <span class="fu">print</span> (line1 <span class="op">++</span> line2) <span class="kw">in</span></span>
<span id="cb170-4"><a href="#cb170-4" aria-hidden="true" tabindex="-1"></a>((),w3)</span></code></pre></div>
<p>Que es equivalente a:</p>
<div class="sourceCode" id="cb171"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb171-1"><a href="#cb171-1" aria-hidden="true" tabindex="-1"></a>(res,w3) <span class="ot">=</span> (bind <span class="fu">getLine</span> (\line1 <span class="ot">-&gt;</span></span>
<span id="cb171-2"><a href="#cb171-2" aria-hidden="true" tabindex="-1"></a>             (bind <span class="fu">getLine</span> (\line2 <span class="ot">-&gt;</span></span>
<span id="cb171-3"><a href="#cb171-3" aria-hidden="true" tabindex="-1"></a>               <span class="fu">print</span> (line1 <span class="op">++</span> line2))))) w0</span></code></pre></div>
<p>Notaste algo? Si, nada de variables temporales del mundo exterior en ninguna
parte! Esto es MÁGICO.</p>
<p>Podemos usar una mejor notación. Usemos <code>(&gt;&gt;=)</code> en lugar de <code>bind</code>. <code>(&gt;&gt;=)</code> es
una función infijo como <code>(+)</code>; Recuerda <code>3 + 4 ⇔ (+) 3 4</code></p>
<div class="sourceCode" id="cb172"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb172-1"><a href="#cb172-1" aria-hidden="true" tabindex="-1"></a>(res,w3) <span class="ot">=</span> (<span class="fu">getLine</span> <span class="op">&gt;&gt;=</span></span>
<span id="cb172-2"><a href="#cb172-2" aria-hidden="true" tabindex="-1"></a>           (\line1 <span class="ot">-&gt;</span> <span class="fu">getLine</span> <span class="op">&gt;&gt;=</span></span>
<span id="cb172-3"><a href="#cb172-3" aria-hidden="true" tabindex="-1"></a>           (\line2 <span class="ot">-&gt;</span> <span class="fu">print</span> (line1 <span class="op">++</span> line2)))) w0</span></code></pre></div>
<p>Haskell tiene azúcar sintáctica para nosotros:</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb173-1"><a href="#cb173-1" aria-hidden="true" tabindex="-1"></a><span class="kw">do</span></span>
<span id="cb173-2"><a href="#cb173-2" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> action1</span>
<span id="cb173-3"><a href="#cb173-3" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> action2</span>
<span id="cb173-4"><a href="#cb173-4" aria-hidden="true" tabindex="-1"></a>  z <span class="ot">&lt;-</span> action3</span>
<span id="cb173-5"><a href="#cb173-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span></span></code></pre></div>
<p>Se reemplaza con:</p>
<div class="sourceCode" id="cb174"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb174-1"><a href="#cb174-1" aria-hidden="true" tabindex="-1"></a>action1 <span class="op">&gt;&gt;=</span> (\x <span class="ot">-&gt;</span></span>
<span id="cb174-2"><a href="#cb174-2" aria-hidden="true" tabindex="-1"></a>action2 <span class="op">&gt;&gt;=</span> (\y <span class="ot">-&gt;</span></span>
<span id="cb174-3"><a href="#cb174-3" aria-hidden="true" tabindex="-1"></a>action3 <span class="op">&gt;&gt;=</span> (\z <span class="ot">-&gt;</span></span>
<span id="cb174-4"><a href="#cb174-4" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span>
<span id="cb174-5"><a href="#cb174-5" aria-hidden="true" tabindex="-1"></a>)))</span></code></pre></div>
<p>Nota que se puede usar <code>x</code> en <code>action2</code> y <code>x</code> y <code>y</code> en <code>action3</code>.</p>
<p>Pero qué pasa con las lineas que no usan <code>&lt;-</code>?
Fácil, otra función <code>blindBind</code>:</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb175-1"><a href="#cb175-1" aria-hidden="true" tabindex="-1"></a><span class="ot">blindBind ::</span> <span class="dt">IO</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> b <span class="ot">-&gt;</span> <span class="dt">IO</span> b</span>
<span id="cb175-2"><a href="#cb175-2" aria-hidden="true" tabindex="-1"></a>blindBind action1 action2 w0 <span class="ot">=</span></span>
<span id="cb175-3"><a href="#cb175-3" aria-hidden="true" tabindex="-1"></a>    bind action (\_ <span class="ot">-&gt;</span> action2) w0</span></code></pre></div>
<p>No simplifiqué esta definición por propósitos de claridad. Pero claro que
podemos usar una mejor notación, usaremos el operador <code>(&gt;&gt;)</code>.</p>
<p>Y</p>
<div class="sourceCode" id="cb176"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb176-1"><a href="#cb176-1" aria-hidden="true" tabindex="-1"></a><span class="kw">do</span></span>
<span id="cb176-2"><a href="#cb176-2" aria-hidden="true" tabindex="-1"></a>    action1</span>
<span id="cb176-3"><a href="#cb176-3" aria-hidden="true" tabindex="-1"></a>    action2</span>
<span id="cb176-4"><a href="#cb176-4" aria-hidden="true" tabindex="-1"></a>    action3</span></code></pre></div>
<p>Se transforma en</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb177-1"><a href="#cb177-1" aria-hidden="true" tabindex="-1"></a>action1 <span class="op">&gt;&gt;</span></span>
<span id="cb177-2"><a href="#cb177-2" aria-hidden="true" tabindex="-1"></a>action2 <span class="op">&gt;&gt;</span></span>
<span id="cb177-3"><a href="#cb177-3" aria-hidden="true" tabindex="-1"></a>action3</span></code></pre></div>
<p>También, otra función útil.</p>
<div class="sourceCode" id="cb178"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb178-1"><a href="#cb178-1" aria-hidden="true" tabindex="-1"></a><span class="ot">putInIO ::</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> a</span>
<span id="cb178-2"><a href="#cb178-2" aria-hidden="true" tabindex="-1"></a>putInIO x <span class="ot">=</span> <span class="dt">IO</span> (\w <span class="ot">-&gt;</span> (x,w))</span></code></pre></div>
<p>Esto es en general la forma de poner variables dentro de un “contexto
de IO”. El nombre general para <code>ponerEnIO</code> es <code>return</code>. Que es un mal nombre
cuando aprendes Haskell. <code>return</code> es muy distinto de lo que puedes estar
acostumbrado.</p>
<p>Para finalizar, traduzcamos nuestro ejemplo:</p>
<div class="sourceCode" id="cb179"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb179-1"><a href="#cb179-1" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">IO</span> [<span class="dt">Integer</span>]</span>
<span id="cb179-2"><a href="#cb179-2" aria-hidden="true" tabindex="-1"></a>askUser <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb179-3"><a href="#cb179-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (separated by commas):&quot;</span></span>
<span id="cb179-4"><a href="#cb179-4" aria-hidden="true" tabindex="-1"></a>  input <span class="ot">&lt;-</span> <span class="fu">getLine</span></span>
<span id="cb179-5"><a href="#cb179-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb179-6"><a href="#cb179-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb179-7"><a href="#cb179-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Just</span> l  <span class="ot">-&gt;</span> <span class="fu">return</span> l</span>
<span id="cb179-8"><a href="#cb179-8" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Nothing</span> <span class="ot">-&gt;</span> askUser</span>
<span id="cb179-9"><a href="#cb179-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb179-10"><a href="#cb179-10" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb179-11"><a href="#cb179-11" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb179-12"><a href="#cb179-12" aria-hidden="true" tabindex="-1"></a>  list <span class="ot">&lt;-</span> askUser</span>
<span id="cb179-13"><a href="#cb179-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> <span class="fu">sum</span> list</span></code></pre></div>
<p>Se traduce a:</p>
<div class="sourceCode" id="cb180"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb180-1"><a href="#cb180-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span></span>
<span id="cb180-2"><a href="#cb180-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb180-3"><a href="#cb180-3" aria-hidden="true" tabindex="-1"></a><span class="ot">maybeRead ::</span> <span class="dt">Read</span> a <span class="ot">=&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb180-4"><a href="#cb180-4" aria-hidden="true" tabindex="-1"></a>maybeRead s <span class="ot">=</span> <span class="kw">case</span> <span class="fu">reads</span> s <span class="kw">of</span></span>
<span id="cb180-5"><a href="#cb180-5" aria-hidden="true" tabindex="-1"></a>                  [(x,<span class="st">&quot;&quot;</span>)]    <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
<span id="cb180-6"><a href="#cb180-6" aria-hidden="true" tabindex="-1"></a>                  _           <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb180-7"><a href="#cb180-7" aria-hidden="true" tabindex="-1"></a><span class="ot">getListFromString ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> [<span class="dt">Integer</span>]</span>
<span id="cb180-8"><a href="#cb180-8" aria-hidden="true" tabindex="-1"></a>getListFromString str <span class="ot">=</span> maybeRead <span class="op">$</span> <span class="st">&quot;[&quot;</span> <span class="op">++</span> str <span class="op">++</span> <span class="st">&quot;]&quot;</span></span>
<span id="cb180-9"><a href="#cb180-9" aria-hidden="true" tabindex="-1"></a><span class="ot">askUser ::</span> <span class="dt">IO</span> [<span class="dt">Integer</span>]</span>
<span id="cb180-10"><a href="#cb180-10" aria-hidden="true" tabindex="-1"></a>askUser <span class="ot">=</span></span>
<span id="cb180-11"><a href="#cb180-11" aria-hidden="true" tabindex="-1"></a>    <span class="fu">putStrLn</span> <span class="st">&quot;Enter a list of numbers (sep. by commas):&quot;</span> <span class="op">&gt;&gt;</span></span>
<span id="cb180-12"><a href="#cb180-12" aria-hidden="true" tabindex="-1"></a>    <span class="fu">getLine</span> <span class="op">&gt;&gt;=</span> \input <span class="ot">-&gt;</span></span>
<span id="cb180-13"><a href="#cb180-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> maybeList <span class="ot">=</span> getListFromString input <span class="kw">in</span></span>
<span id="cb180-14"><a href="#cb180-14" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> maybeList <span class="kw">of</span></span>
<span id="cb180-15"><a href="#cb180-15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Just</span> l <span class="ot">-&gt;</span> <span class="fu">return</span> l</span>
<span id="cb180-16"><a href="#cb180-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nothing</span> <span class="ot">-&gt;</span> askUser</span></code></pre></div>
<p>main :: IO ()
main = askUser &gt;&gt;=
-&gt; print $ sum list</p>
<p>Puedes compilar este código y verificar que funciona.</p>
<p>Imagina como se vería sin el <code>(&gt;&gt;)</code> y <code>(&gt;&gt;=)</code>.</p>
<h2 id="monads">Monads</h2>
<p><img src="/img/haskellhard/shot14.jpg" /></p>
<p>Ahora el secreto puede ser revelado: <code>IO</code> es un <em>monad</em>.
Ser un monad significa que se tiene acceso a azúcar sintáctica con la
notación <code>do</code>. Pero principalmente, se tiene acceso al patrón que facilitará
el flujo del código.</p>
<pre><code>Aclaraciones importantes:

* Los monads no tratan necesariamente efectos secundarios!
Hay varios Monads puros.
* Los monads se tratan se secuenciar.</code></pre>
<p>En Haskell, <code>Monad</code> es una clase de tipo. Para crear una instancia de esta
clase de tipo, se deben proveer las funciones <code>(&gt;&gt;=)</code> y <code>return</code>. La función
<code>(&gt;&gt;)</code> se deriva de <code>(&gt;&gt;=)</code>. Aquí se muestra como la clase de tipo <code>Monad</code>
está declarada (básicamente):</p>
<div class="sourceCode" id="cb182"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb182-1"><a href="#cb182-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monad</span> m  <span class="kw">where</span></span>
<span id="cb182-2"><a href="#cb182-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&gt;&gt;=) ::</span> m a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b</span>
<span id="cb182-3"><a href="#cb182-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  return ::</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb182-4"><a href="#cb182-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb182-5"><a href="#cb182-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&gt;&gt;) ::</span> m a <span class="ot">-&gt;</span> m b <span class="ot">-&gt;</span> m b</span>
<span id="cb182-6"><a href="#cb182-6" aria-hidden="true" tabindex="-1"></a>  f <span class="op">&gt;&gt;</span> g <span class="ot">=</span> f <span class="op">&gt;&gt;=</span> \_ <span class="ot">-&gt;</span> g</span>
<span id="cb182-7"><a href="#cb182-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb182-8"><a href="#cb182-8" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- You should generally safely ignore this function</span></span>
<span id="cb182-9"><a href="#cb182-9" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- which I believe exists for historical reasons</span></span>
<span id="cb182-10"><a href="#cb182-10" aria-hidden="true" tabindex="-1"></a><span class="ot">  fail ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> m a</span>
<span id="cb182-11"><a href="#cb182-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fail</span> <span class="ot">=</span> <span class="fu">error</span></span></code></pre></div>
<pre><code>Aclaraciones:

* La palabra `class` no es tu amiga. En Haskell *class* no es una clase del
tipo que encontraras en lenguajes orientados a objetos. En Haskell una clase
tiene más bien similitudes con las interfaces de Java. Una mejor palabra
hubiera sido `typeclass`, pues eso significa un conjunto de tipos. Para que un
tipo pertenezca a una clase, todas las funciones de la clase debe ser
proporcionadas por el tipo.

* En este ejemplo en particular de clase de tipo, el tipo `m` debe ser un tipo
que tome un argumento. Por ejemplo `IO a`, pero también `Maybe a`, `[a]`,
etc...

* Para que un monad sea útil, la función debe obedecer algunas reglas. Si
tu construcción no las obedece cosas extrañas pueden ocurrir:

* Return a &gt;&gt;= k == K a m &gt;&gt;= return == m m &gt;&gt;= (-&gt; k x &gt;&gt;= h) == (m &gt;&gt;= k) &gt;&gt;=
h ~</code></pre>
<h3 id="maybe-es-un-monad">Maybe es un monad</h3>
<p>Hay varios tipos diferentes que son instancias de <code>Monad</code>. Una de las más
fáciles de describir es <code>Maybe</code>. Si se tiene una secuencia de valores <code>Maybe</code>,
se pueden usar monads para manipularlos. Es particularmente útil para remover
construcciones <code>if..then..else..</code> profundas</p>
<p>Imagina una operación bancaria compleja. Eres candidato a ganar 700$ solo si
puedes seguir una lista de operaciones sin que tu cuenta caiga hasta cero.</p>
<div class="sourceCode" id="cb184"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb184-1"><a href="#cb184-1" aria-hidden="true" tabindex="-1"></a>deposit  value account <span class="ot">=</span> account <span class="op">+</span> value</span>
<span id="cb184-2"><a href="#cb184-2" aria-hidden="true" tabindex="-1"></a>withdraw value account <span class="ot">=</span> account <span class="op">-</span> value</span>
<span id="cb184-3"><a href="#cb184-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb184-4"><a href="#cb184-4" aria-hidden="true" tabindex="-1"></a><span class="ot">eligible ::</span> (<span class="dt">Num</span> a,<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb184-5"><a href="#cb184-5" aria-hidden="true" tabindex="-1"></a>eligible account <span class="ot">=</span></span>
<span id="cb184-6"><a href="#cb184-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> account1 <span class="ot">=</span> deposit <span class="dv">100</span> account <span class="kw">in</span></span>
<span id="cb184-7"><a href="#cb184-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> (account1 <span class="op">&lt;</span> <span class="dv">0</span>)</span>
<span id="cb184-8"><a href="#cb184-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">then</span> <span class="dt">False</span></span>
<span id="cb184-9"><a href="#cb184-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb184-10"><a href="#cb184-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> account2 <span class="ot">=</span> withdraw <span class="dv">200</span> account1 <span class="kw">in</span></span>
<span id="cb184-11"><a href="#cb184-11" aria-hidden="true" tabindex="-1"></a>      <span class="kw">if</span> (account2 <span class="op">&lt;</span> <span class="dv">0</span>)</span>
<span id="cb184-12"><a href="#cb184-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">then</span> <span class="dt">False</span></span>
<span id="cb184-13"><a href="#cb184-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">else</span></span>
<span id="cb184-14"><a href="#cb184-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> account3 <span class="ot">=</span> deposit <span class="dv">100</span> account2 <span class="kw">in</span></span>
<span id="cb184-15"><a href="#cb184-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> (account3 <span class="op">&lt;</span> <span class="dv">0</span>)</span>
<span id="cb184-16"><a href="#cb184-16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">then</span> <span class="dt">False</span></span>
<span id="cb184-17"><a href="#cb184-17" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb184-18"><a href="#cb184-18" aria-hidden="true" tabindex="-1"></a>          <span class="kw">let</span> account4 <span class="ot">=</span> withdraw <span class="dv">300</span> account3 <span class="kw">in</span></span>
<span id="cb184-19"><a href="#cb184-19" aria-hidden="true" tabindex="-1"></a>          <span class="kw">if</span> (account4 <span class="op">&lt;</span> <span class="dv">0</span>)</span>
<span id="cb184-20"><a href="#cb184-20" aria-hidden="true" tabindex="-1"></a>          <span class="kw">then</span> <span class="dt">False</span></span>
<span id="cb184-21"><a href="#cb184-21" aria-hidden="true" tabindex="-1"></a>          <span class="kw">else</span></span>
<span id="cb184-22"><a href="#cb184-22" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> account5 <span class="ot">=</span> deposit <span class="dv">1000</span> account4 <span class="kw">in</span></span>
<span id="cb184-23"><a href="#cb184-23" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> (account5 <span class="op">&lt;</span> <span class="dv">0</span>)</span>
<span id="cb184-24"><a href="#cb184-24" aria-hidden="true" tabindex="-1"></a>            <span class="kw">then</span> <span class="dt">False</span></span>
<span id="cb184-25"><a href="#cb184-25" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="cb184-26"><a href="#cb184-26" aria-hidden="true" tabindex="-1"></a>              <span class="dt">True</span></span>
<span id="cb184-27"><a href="#cb184-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb184-28"><a href="#cb184-28" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb184-29"><a href="#cb184-29" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">300</span> <span class="co">-- True</span></span>
<span id="cb184-30"><a href="#cb184-30" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">299</span> <span class="co">-- False</span></span></code></pre></div>
<p>Ahora, mejoremos esto usando <code>Maybe</code> y el hecho de que es un Monad</p>
<div class="sourceCode" id="cb185"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb185-1"><a href="#cb185-1" aria-hidden="true" tabindex="-1"></a><span class="ot">deposit ::</span> (<span class="dt">Num</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb185-2"><a href="#cb185-2" aria-hidden="true" tabindex="-1"></a>deposit value account <span class="ot">=</span> <span class="dt">Just</span> (account <span class="op">+</span> value)</span>
<span id="cb185-3"><a href="#cb185-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb185-4"><a href="#cb185-4" aria-hidden="true" tabindex="-1"></a><span class="ot">withdraw ::</span> (<span class="dt">Num</span> a,<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb185-5"><a href="#cb185-5" aria-hidden="true" tabindex="-1"></a>withdraw value account <span class="ot">=</span> <span class="kw">if</span> (account <span class="op">&lt;</span> value)</span>
<span id="cb185-6"><a href="#cb185-6" aria-hidden="true" tabindex="-1"></a>                         <span class="kw">then</span> <span class="dt">Nothing</span></span>
<span id="cb185-7"><a href="#cb185-7" aria-hidden="true" tabindex="-1"></a>                         <span class="kw">else</span> <span class="dt">Just</span> (account <span class="op">-</span> value)</span>
<span id="cb185-8"><a href="#cb185-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb185-9"><a href="#cb185-9" aria-hidden="true" tabindex="-1"></a><span class="ot">eligible ::</span> (<span class="dt">Num</span> a, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Bool</span></span>
<span id="cb185-10"><a href="#cb185-10" aria-hidden="true" tabindex="-1"></a>eligible account <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb185-11"><a href="#cb185-11" aria-hidden="true" tabindex="-1"></a>  account1 <span class="ot">&lt;-</span> deposit <span class="dv">100</span> account</span>
<span id="cb185-12"><a href="#cb185-12" aria-hidden="true" tabindex="-1"></a>  account2 <span class="ot">&lt;-</span> withdraw <span class="dv">200</span> account1</span>
<span id="cb185-13"><a href="#cb185-13" aria-hidden="true" tabindex="-1"></a>  account3 <span class="ot">&lt;-</span> deposit <span class="dv">100</span> account2</span>
<span id="cb185-14"><a href="#cb185-14" aria-hidden="true" tabindex="-1"></a>  account4 <span class="ot">&lt;-</span> withdraw <span class="dv">300</span> account3</span>
<span id="cb185-15"><a href="#cb185-15" aria-hidden="true" tabindex="-1"></a>  account5 <span class="ot">&lt;-</span> deposit <span class="dv">1000</span> account4</span>
<span id="cb185-16"><a href="#cb185-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Just</span> <span class="dt">True</span></span>
<span id="cb185-17"><a href="#cb185-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb185-18"><a href="#cb185-18" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb185-19"><a href="#cb185-19" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">300</span> <span class="co">-- Just True</span></span>
<span id="cb185-20"><a href="#cb185-20" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">299</span> <span class="co">-- Nothing</span></span></code></pre></div>
<p>No esta nada mal, pero podemos mejorarlo más:</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb186-1"><a href="#cb186-1" aria-hidden="true" tabindex="-1"></a><span class="ot">deposit ::</span> (<span class="dt">Num</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb186-2"><a href="#cb186-2" aria-hidden="true" tabindex="-1"></a>deposit value account <span class="ot">=</span> <span class="dt">Just</span> (account <span class="op">+</span> value)</span>
<span id="cb186-3"><a href="#cb186-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb186-4"><a href="#cb186-4" aria-hidden="true" tabindex="-1"></a><span class="ot">withdraw ::</span> (<span class="dt">Num</span> a,<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb186-5"><a href="#cb186-5" aria-hidden="true" tabindex="-1"></a>withdraw value account <span class="ot">=</span> <span class="kw">if</span> (account <span class="op">&lt;</span> value)</span>
<span id="cb186-6"><a href="#cb186-6" aria-hidden="true" tabindex="-1"></a>                         <span class="kw">then</span> <span class="dt">Nothing</span></span>
<span id="cb186-7"><a href="#cb186-7" aria-hidden="true" tabindex="-1"></a>                         <span class="kw">else</span> <span class="dt">Just</span> (account <span class="op">-</span> value)</span>
<span id="cb186-8"><a href="#cb186-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb186-9"><a href="#cb186-9" aria-hidden="true" tabindex="-1"></a><span class="ot">eligible ::</span> (<span class="dt">Num</span> a, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Bool</span></span>
<span id="cb186-10"><a href="#cb186-10" aria-hidden="true" tabindex="-1"></a>eligible account <span class="ot">=</span></span>
<span id="cb186-11"><a href="#cb186-11" aria-hidden="true" tabindex="-1"></a>  deposit <span class="dv">100</span> account <span class="op">&gt;&gt;=</span></span>
<span id="cb186-12"><a href="#cb186-12" aria-hidden="true" tabindex="-1"></a>  withdraw <span class="dv">200</span> <span class="op">&gt;&gt;=</span></span>
<span id="cb186-13"><a href="#cb186-13" aria-hidden="true" tabindex="-1"></a>  deposit <span class="dv">100</span>  <span class="op">&gt;&gt;=</span></span>
<span id="cb186-14"><a href="#cb186-14" aria-hidden="true" tabindex="-1"></a>  withdraw <span class="dv">300</span> <span class="op">&gt;&gt;=</span></span>
<span id="cb186-15"><a href="#cb186-15" aria-hidden="true" tabindex="-1"></a>  deposit <span class="dv">1000</span> <span class="op">&gt;&gt;</span></span>
<span id="cb186-16"><a href="#cb186-16" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> <span class="dt">True</span></span>
<span id="cb186-17"><a href="#cb186-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb186-18"><a href="#cb186-18" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb186-19"><a href="#cb186-19" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">300</span> <span class="co">-- Just True</span></span>
<span id="cb186-20"><a href="#cb186-20" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> eligible <span class="dv">299</span> <span class="co">-- Nothing</span></span></code></pre></div>
<p>Hemos demostrado que los Monads son una buena forma de hacer el código más
elegante. Esta idea para organizar el código, en particular para <code>Maybe</code> se
puede usar en la mayoría de los lenguajes imperativos. De hecho, este es más
o menos el tipo de construcciones que hacemos naturalmente.</p>
<pre><code>Una aclaración importante:

El primer elemento en la secuencia evaluada a `Nothing` detendrá por
completo la evaluación. Esto significa que no se ejecutan todas las
lineas. Obtienes esto gratuitamente, gracias a la pereza (laziness).</code></pre>
<p>También se puede replicar este ejemplo con la definición de <code>(&gt;&gt;=)</code> para
<code>Maybe</code> en mente:</p>
<div class="sourceCode" id="cb188"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb188-1"><a href="#cb188-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
<span id="cb188-2"><a href="#cb188-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&gt;&gt;=) ::</span> <span class="dt">Maybe</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b) <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b</span>
<span id="cb188-3"><a href="#cb188-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nothing</span>  <span class="op">&gt;&gt;=</span> _  <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb188-4"><a href="#cb188-4" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> x) <span class="op">&gt;&gt;=</span> f  <span class="ot">=</span> f x</span>
<span id="cb188-5"><a href="#cb188-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb188-6"><a href="#cb188-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> x <span class="ot">=</span> <span class="dt">Just</span> x</span></code></pre></div>
<p>El monad <code>Maybe</code> probó ser útil en este ejemplo. Vimos la utilidad de el monad
<code>IO</code>. Pero vamos por un mejor ejemplo, las listas.</p>
<h3 id="el-monad-lista">El monad lista</h3>
<p><img src="/img/haskellhard/shot15.jpg" /></p>
<p>El monad lista ayuda a simular cómputos no determinístico:</p>
<div class="sourceCode" id="cb189"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb189-1"><a href="#cb189-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad</span> (guard)</span>
<span id="cb189-2"><a href="#cb189-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb189-3"><a href="#cb189-3" aria-hidden="true" tabindex="-1"></a>allCases <span class="ot">=</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb189-4"><a href="#cb189-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb189-5"><a href="#cb189-5" aria-hidden="true" tabindex="-1"></a><span class="ot">resolve ::</span> [(<span class="dt">Int</span>,<span class="dt">Int</span>,<span class="dt">Int</span>)]</span>
<span id="cb189-6"><a href="#cb189-6" aria-hidden="true" tabindex="-1"></a>resolve <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb189-7"><a href="#cb189-7" aria-hidden="true" tabindex="-1"></a>              x <span class="ot">&lt;-</span> allCases</span>
<span id="cb189-8"><a href="#cb189-8" aria-hidden="true" tabindex="-1"></a>              y <span class="ot">&lt;-</span> allCases</span>
<span id="cb189-9"><a href="#cb189-9" aria-hidden="true" tabindex="-1"></a>              z <span class="ot">&lt;-</span> allCases</span>
<span id="cb189-10"><a href="#cb189-10" aria-hidden="true" tabindex="-1"></a>              guard <span class="op">$</span> <span class="dv">4</span><span class="op">*</span>x <span class="op">+</span> <span class="dv">2</span><span class="op">*</span>y <span class="op">&lt;</span> z</span>
<span id="cb189-11"><a href="#cb189-11" aria-hidden="true" tabindex="-1"></a>              <span class="fu">return</span> (x,y,z)</span>
<span id="cb189-12"><a href="#cb189-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb189-13"><a href="#cb189-13" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb189-14"><a href="#cb189-14" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> resolve</span></code></pre></div>
<p>MAGIA:</p>
<pre><code>[(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,2,9),(1,2,10)]</code></pre>
<p>Para el monad lista, también hay azúcar sintáctica:</p>
<div class="sourceCode" id="cb191"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb191-1"><a href="#cb191-1" aria-hidden="true" tabindex="-1"></a><span class="fu">print</span> <span class="op">$</span> [ (x,y,z) <span class="op">|</span> x <span class="ot">&lt;-</span> allCases,</span>
<span id="cb191-2"><a href="#cb191-2" aria-hidden="true" tabindex="-1"></a>                      y <span class="ot">&lt;-</span> allCases,</span>
<span id="cb191-3"><a href="#cb191-3" aria-hidden="true" tabindex="-1"></a>                      z <span class="ot">&lt;-</span> allCases,</span>
<span id="cb191-4"><a href="#cb191-4" aria-hidden="true" tabindex="-1"></a>                      <span class="dv">4</span><span class="op">*</span>x <span class="op">+</span> <span class="dv">2</span><span class="op">*</span>y <span class="op">&lt;</span> z ]</span></code></pre></div>
<p>No listaré todos los monads, pero hay muchos de ellos. Usar monads simplifica
la manipulación de varias nociones en lenguajes puros. En particular,
los monads son muy útiles para:</p>
<ul>
<li>IO</li>
<li>Computo no determinístico</li>
<li>Generar números pseudo aleatorios</li>
<li>Mantener configuración de estado</li>
<li>Escribir estado</li>
<li>…</li>
</ul>
<p>Si me has seguido hasta aquí, entonces lo lograste! Sabes Monads[^7]!</p>
<h1 id="apéndice">Apéndice</h1>
<p>Esta sección no se trata de aprender Haskell. Solo está aquí para discutir a
más profundidad algunos detalles.</p>
<h2 id="más-sobre-los-arboles-infinitos">Más sobre los arboles infinitos</h2>
<p>En la sección <em>Estructuras infinitas</em> vimos algunas construcciones simples.
Desafortunadamente removimos dos propiedades de nuestro árbol:</p>
<ol type="1">
<li>No valores duplicados en los nodos</li>
<li>Árbol bien ordenado</li>
</ol>
<p>En esta sección intentaremos mantener la primera propiedad.
Respecto a la segunda, debemos relajarla pero discutiremos como mantenerla
todo lo posible.</p>
<p>El primer paso es crear una lista de números pseudo aleatorios:</p>
<div class="sourceCode" id="cb192"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb192-1"><a href="#cb192-1" aria-hidden="true" tabindex="-1"></a>shuffle <span class="ot">=</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (x<span class="op">*</span><span class="dv">3123</span>) <span class="ot">`mod`</span> <span class="dv">4331</span>) [<span class="dv">1</span><span class="op">..</span>]</span></code></pre></div>
<p>Solo como recordatorio, aquí esta la definición de <code>treeFromList</code></p>
<div class="sourceCode" id="cb193"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb193-1"><a href="#cb193-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFromList ::</span> (<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">BinTree</span> a</span>
<span id="cb193-2"><a href="#cb193-2" aria-hidden="true" tabindex="-1"></a>treeFromList []    <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb193-3"><a href="#cb193-3" aria-hidden="true" tabindex="-1"></a>treeFromList (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Node</span> x (treeFromList (<span class="fu">filter</span> (<span class="op">&lt;</span>x) xs))</span>
<span id="cb193-4"><a href="#cb193-4" aria-hidden="true" tabindex="-1"></a>                             (treeFromList (<span class="fu">filter</span> (<span class="op">&gt;</span>x) xs))</span></code></pre></div>
<p>y <code>treeTakeDepth</code>:</p>
<div class="sourceCode" id="cb194"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb194-1"><a href="#cb194-1" aria-hidden="true" tabindex="-1"></a>treeTakeDepth _ <span class="dt">Empty</span> <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb194-2"><a href="#cb194-2" aria-hidden="true" tabindex="-1"></a>treeTakeDepth <span class="dv">0</span> _     <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb194-3"><a href="#cb194-3" aria-hidden="true" tabindex="-1"></a>treeTakeDepth n (<span class="dt">Node</span> x left right) <span class="ot">=</span> <span class="kw">let</span></span>
<span id="cb194-4"><a href="#cb194-4" aria-hidden="true" tabindex="-1"></a>          nl <span class="ot">=</span> treeTakeDepth (n<span class="op">-</span><span class="dv">1</span>) left</span>
<span id="cb194-5"><a href="#cb194-5" aria-hidden="true" tabindex="-1"></a>          nr <span class="ot">=</span> treeTakeDepth (n<span class="op">-</span><span class="dv">1</span>) right</span>
<span id="cb194-6"><a href="#cb194-6" aria-hidden="true" tabindex="-1"></a>          <span class="kw">in</span></span>
<span id="cb194-7"><a href="#cb194-7" aria-hidden="true" tabindex="-1"></a>              <span class="dt">Node</span> x nl nr</span></code></pre></div>
<p>Observa el resultado de:</p>
<div class="sourceCode" id="cb195"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb195-1"><a href="#cb195-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb195-2"><a href="#cb195-2" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStrLn</span> <span class="st">&quot;take 10 shuffle&quot;</span></span>
<span id="cb195-3"><a href="#cb195-3" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> <span class="op">$</span> <span class="fu">take</span> <span class="dv">10</span> shuffle</span>
<span id="cb195-4"><a href="#cb195-4" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStrLn</span> <span class="st">&quot;\ntreeTakeDepth 4 (treeFromList shuffle)&quot;</span></span>
<span id="cb195-5"><a href="#cb195-5" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> <span class="op">$</span> treeTakeDepth <span class="dv">4</span> (treeFromList shuffle)</span></code></pre></div>
<pre><code>% runghc 02_Hard_Part/41_Infinites_Structures.lhs
take 10 shuffle
[3123,1915,707,3830,2622,1414,206,3329,2121,913]
treeTakeDepth 4 (treeFromList shuffle)

&lt; 3123
: |--1915
: |  |--707
: |  |  |--206
: |  |  `--1414
: |  `--2622
: |     |--2121
: |     `--2828
: `--3830
:    |--3329
:    |  |--3240
:    |  `--3535
:    `--4036
:       |--3947
:       `--4242</code></pre>
<p>Bien! Termina! Pero cuidado, solo funcionará si tiene algo que poner en la rama.</p>
<p>Por ejemplo</p>
<div class="sourceCode" id="cb197"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb197-1"><a href="#cb197-1" aria-hidden="true" tabindex="-1"></a>treeTakeDepth <span class="dv">4</span> (treeFromList [<span class="dv">1</span><span class="op">..</span>])</span></code></pre></div>
<p>No terminará nunca. Por que intentará acceder a la cabeza de <code>filter (&lt;1) [2..]</code>. Pero <code>filger</code> no es lo bastante inteligente para entender que el
resultado es una lista vacía.</p>
<p>Aun así, es un ejemplo muy bueno de lo que los programas no estrictos
pueden ofrecer.</p>
<p>Como ejercicio para el lector:</p>
<ul>
<li>Probar la existencia de un numero <code>n</code> tal que <code>treeTakeDepth n   (treeFromList shuffle)</code> entrará en un loop infinito.</li>
<li>Encontrar un limite superior para <code>n</code>.</li>
<li>Probar que no hay una lista <code>suffle</code> tal que para cualquier
profundidad, el programa termina.</li>
</ul>
<p>Para resolver este problema modificaremos un poco las funciones
<code>treeFromList</code> y <code>shuffle</code>.</p>
<p>Un primer problema es la falta de infinitos números diferentes en nuestra
implementación de <code>shuffle</code>. Solo hemos generado <code>4331</code> números distintos.
Para solucionarlo haremos una función <code>shuffle</code> mejorada.</p>
<div class="sourceCode" id="cb198"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb198-1"><a href="#cb198-1" aria-hidden="true" tabindex="-1"></a>shuffle <span class="ot">=</span> <span class="fu">map</span> rand [<span class="dv">1</span><span class="op">..</span>]</span>
<span id="cb198-2"><a href="#cb198-2" aria-hidden="true" tabindex="-1"></a>          <span class="kw">where</span></span>
<span id="cb198-3"><a href="#cb198-3" aria-hidden="true" tabindex="-1"></a>              rand x <span class="ot">=</span> ((p x) <span class="ot">`mod`</span> (x<span class="op">+</span>c)) <span class="op">-</span> ((x<span class="op">+</span>c) <span class="ot">`div`</span> <span class="dv">2</span>)</span>
<span id="cb198-4"><a href="#cb198-4" aria-hidden="true" tabindex="-1"></a>              p x <span class="ot">=</span> m<span class="op">*</span>x<span class="op">^</span><span class="dv">2</span> <span class="op">+</span> n<span class="op">*</span>x <span class="op">+</span> o <span class="co">-- some polynome</span></span>
<span id="cb198-5"><a href="#cb198-5" aria-hidden="true" tabindex="-1"></a>              m <span class="ot">=</span> <span class="dv">3123</span></span>
<span id="cb198-6"><a href="#cb198-6" aria-hidden="true" tabindex="-1"></a>              n <span class="ot">=</span> <span class="dv">31</span></span>
<span id="cb198-7"><a href="#cb198-7" aria-hidden="true" tabindex="-1"></a>              o <span class="ot">=</span> <span class="dv">7641</span></span>
<span id="cb198-8"><a href="#cb198-8" aria-hidden="true" tabindex="-1"></a>              c <span class="ot">=</span> <span class="dv">1237</span></span></code></pre></div>
<p>Esta función tiene la propiedad de no tener un limite superior o inferior.
Pero tener una lista mejor mezclada no es suficiente para no entrar en un
bucle infinito.</p>
<p>Generalmente, no podemos decidir si <code>filter (&lt;x) xs</code> está vacía. Entonces
para resolver este problema, autorizaré algo de error en la creación del árbol
binario. Esta nueva versión puede crear un árbol binario que no tienen la
siguiente propiedad para algunos de sus nodos:</p>
<pre><code>Cualquier elemento en la rama izquierda debe ser estrictamente
inferior a la etiqueta de la raíz.</code></pre>
<p>Permanecerá en su <em>mayor parte</em> un árbol binario ordenado. Más aún, por
construcción, el valor de cada nodo es único en el árbol.</p>
<p>Aquí nuestra nueva versión de <code>treeFromList</code>. Simplemente sea ha remplazado
<code>filter</code> por <code>safefilter</code>.</p>
<div class="sourceCode" id="cb200"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb200-1"><a href="#cb200-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFromList ::</span> (<span class="dt">Ord</span> a, <span class="dt">Show</span> a) <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">BinTree</span> a</span>
<span id="cb200-2"><a href="#cb200-2" aria-hidden="true" tabindex="-1"></a>treeFromList []    <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb200-3"><a href="#cb200-3" aria-hidden="true" tabindex="-1"></a>treeFromList (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Node</span> x left right</span>
<span id="cb200-4"><a href="#cb200-4" aria-hidden="true" tabindex="-1"></a>          <span class="kw">where</span></span>
<span id="cb200-5"><a href="#cb200-5" aria-hidden="true" tabindex="-1"></a>              left <span class="ot">=</span> treeFromList <span class="op">$</span> safefilter (<span class="op">&lt;</span>x) xs</span>
<span id="cb200-6"><a href="#cb200-6" aria-hidden="true" tabindex="-1"></a>              right <span class="ot">=</span> treeFromList <span class="op">$</span> safefilter (<span class="op">&gt;</span>x) xs</span></code></pre></div>
<p>Esta nueva función <code>safefilter</code> es casi equivalente a <code>filter</code> pero no entra en
un bucle infinito si el resultado es una lista infinita. Si no puede encontrar
un elemento para el cual la prueba resulte cierta luego de 10000 pasos
consecutivos, entonces considera que es el final de la búsqueda.</p>
<div class="sourceCode" id="cb201"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb201-1"><a href="#cb201-1" aria-hidden="true" tabindex="-1"></a><span class="ot">safefilter ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb201-2"><a href="#cb201-2" aria-hidden="true" tabindex="-1"></a>safefilter f l <span class="ot">=</span> safefilter&#39; f l nbTry</span>
<span id="cb201-3"><a href="#cb201-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb201-4"><a href="#cb201-4" aria-hidden="true" tabindex="-1"></a>      nbTry <span class="ot">=</span> <span class="dv">10000</span></span>
<span id="cb201-5"><a href="#cb201-5" aria-hidden="true" tabindex="-1"></a>      safefilter&#39; _ _ <span class="dv">0</span> <span class="ot">=</span> []</span>
<span id="cb201-6"><a href="#cb201-6" aria-hidden="true" tabindex="-1"></a>      safefilter&#39; _ [] _ <span class="ot">=</span> []</span>
<span id="cb201-7"><a href="#cb201-7" aria-hidden="true" tabindex="-1"></a>      safefilter&#39; f (x<span class="op">:</span>xs) n <span class="ot">=</span></span>
<span id="cb201-8"><a href="#cb201-8" aria-hidden="true" tabindex="-1"></a>                  <span class="kw">if</span> f x</span>
<span id="cb201-9"><a href="#cb201-9" aria-hidden="true" tabindex="-1"></a>                     <span class="kw">then</span> x <span class="op">:</span> safefilter&#39; f xs nbTry</span>
<span id="cb201-10"><a href="#cb201-10" aria-hidden="true" tabindex="-1"></a>                     <span class="kw">else</span> safefilter&#39; f xs (n<span class="op">-</span><span class="dv">1</span>)</span></code></pre></div>
<p>Ahora el programa se ejecuta bien:</p>
<div class="sourceCode" id="cb202"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb202-1"><a href="#cb202-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb202-2"><a href="#cb202-2" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStrLn</span> <span class="st">&quot;take 10 shuffle&quot;</span></span>
<span id="cb202-3"><a href="#cb202-3" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> <span class="op">$</span> <span class="fu">take</span> <span class="dv">10</span> shuffle</span>
<span id="cb202-4"><a href="#cb202-4" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStrLn</span> <span class="st">&quot;\ntreeTakeDepth 8 (treeFromList shuffle)&quot;</span></span>
<span id="cb202-5"><a href="#cb202-5" aria-hidden="true" tabindex="-1"></a>      <span class="fu">print</span> <span class="op">$</span> treeTakeDepth <span class="dv">8</span> (treeFromList <span class="op">$</span> shuffle)</span></code></pre></div>
<p>Se debería ver que el tiempo para imprimir cada valor es diferente. Esto es por
que Haskell calcula cada valor cuando lo necesita. Y en este caso, esto ocurre
cuando se solicita imprimirlo en pantalla.</p>
<p>Intenta remplazar la profundidad de <code>8</code> a <code>100</code>. Funcionará sin comerse tu
RAM! El flujo en el manejo de memoria es hecho de forma natural por Haskell.</p>
<p>Como ejercicio para el lector:</p>
<ul>
<li><p>Incluso con un valor grande constante para <code>deep</code> y <code>nbTry</code>, parece funcionar
bien. Pero en el peor caso, puede ser exponencial. Crear una lista para el
peor caso y darlo como parámetro a <code>treeFromList</code>. Pista: piensa en
<code>[0,-1,-1,...,-1,1,-1,...,-1,1,...]</code>.</p></li>
<li><p>Primero intenté implementar <code>safefilter</code> como:</p></li>
</ul>
<div class="sourceCode" id="cb203"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb203-1"><a href="#cb203-1" aria-hidden="true" tabindex="-1"></a>safefilter&#39; f l <span class="ot">=</span> <span class="kw">if</span> <span class="fu">filter</span> f (<span class="fu">take</span> <span class="dv">10000</span> l) <span class="op">==</span> []</span>
<span id="cb203-2"><a href="#cb203-2" aria-hidden="true" tabindex="-1"></a>            <span class="kw">then</span> []</span>
<span id="cb203-3"><a href="#cb203-3" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span> <span class="fu">filter</span> f l</span></code></pre></div>
<p>Explica por que no funciona y puede entrar en un loop infinito.</p>
<ul>
<li>Supón que <code>shuffle</code> es una lista aleatoria real con limites crecientes.
Si estudias un poco esta estructura, descubrirás que con una
probabilidad de 1, esta es una estructura infinita. Usando el siguiente
código encuentra una definición de <code>f</code> tal que con probabilidad de <code>1</code>,
<code>treeFromList' shuffle</code> es infinita. Y pruebalo. (esto solo es una
conjetura).</li>
</ul>
<div class="sourceCode" id="cb204"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb204-1"><a href="#cb204-1" aria-hidden="true" tabindex="-1"></a>treeFromList&#39; []  n <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb204-2"><a href="#cb204-2" aria-hidden="true" tabindex="-1"></a>treeFromList&#39; (x<span class="op">:</span>xs) n <span class="ot">=</span> <span class="dt">Node</span> x left right</span>
<span id="cb204-3"><a href="#cb204-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb204-4"><a href="#cb204-4" aria-hidden="true" tabindex="-1"></a>        left <span class="ot">=</span> treeFromList&#39; (safefilter&#39; (<span class="op">&lt;</span>x) xs (f n)</span>
<span id="cb204-5"><a href="#cb204-5" aria-hidden="true" tabindex="-1"></a>        right <span class="ot">=</span> treeFromList&#39; (safefilter&#39; (<span class="op">&gt;</span>x) xs (f n)</span>
<span id="cb204-6"><a href="#cb204-6" aria-hidden="true" tabindex="-1"></a>        f <span class="ot">=</span> <span class="op">???</span></span></code></pre></div>
<p>[^1]. Incluso si los lenguajes mas recientes intentan ocultarlos, están
presentes.</p>
<p>[^2]. Se que estoy haciendo trampa. Pero hablaré “no estricto” luego.</p>
<p>[^3]. Para los valientes, una explicación más completa del patrón de matching se
puede encontrar
<a href="http://www.cs.auckland.ac.nz/references/haskell/haskell-intro-html/patterns.html">aquí</a>.</p>
<p>[^4]. Es muy similar al <code>eval</code> de javascript en una cadena que contiene
JSON.</p>
<p>[^5]. Hay algunas excepciones <em>no seguras</em> ha esta regla. Pero no deberías
ver su uso en una aplicación real excepto tal vez para propósitos de depuración.</p>
<p>[^6]. Para los curiosos el tipo real es <code>data IO a = IO {unIO :: State# RealWorld -&gt; (#State# RealWorld, a #)}</code>. Los ‘#’ tienen que ver con la
optimización.</p>
<p>[^7]. Ciertamente necesitas practicar un poco para acostumbrarte a ellos y
entender cuando los puedes usar y crearlos tu mismo. Pero ya haz hecho un
gran avance.</p>]]></summary>
</entry>
<entry>
    <title>Seamless Vim-Tmux-WindowManager-Monitor navigation</title>
    <link href="http://www.sillybytes.net/2016/06/seamlessly-vim-tmux-windowmanager_24.html" />
    <id>http://www.sillybytes.net/2016/06/seamlessly-vim-tmux-windowmanager_24.html</id>
    <published>2016-06-24</published>
    <updated>2016-06-24T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><a href="https://robots.thoughtbot.com/seamlessly-navigate-vim-and-tmux-splits">This Thoughtbot
post</a>
describes how to make Vim and Tmux work together in Harmony based on <a href="https://github.com/christoomey/vim-tmux-navigator">this
crhistoomey’s plugin</a>,
allowing you to traverse both your Vim and Tmux windows and panes respectively.</p>
<p>Having the ability to traverse Vim and Tmux splits without having to think about
it using <code>ctrl-h</code>, <code>ctrl-j</code>, <code>ctrl-k</code>, <code>ctrl-l</code> is brilliant! But I still had an
annoyance source from the window manager (Ratpoison) and the multi monitor
setup.</p>
<p>So I took the same concept and extend it to those uses cases. Now I use
<code>ctrl-h</code>, <code>ctrl-j</code>, <code>ctrl-k</code>, <code>ctrl-l</code> to move through my <strong>Window Manager
splits</strong>, my <strong>Tmux panes</strong>, my <strong>Vim windows</strong> and my <strong>Monitors</strong> with minimum
mental overhead. Here is how.</p>
<!--more-->
<p>Some scripts are a bit of complex, so instead of explaining them in detail, the
general algorithm is described.</p>
<h1 id="frame-monitor-navigation">Frame-Monitor Navigation</h1>
<p><img src="/img/navigator/thumbnail.jpg" /></p>
<p>When traversing frames (Ratpoison splits) it stops at the end of the current
monitor, so first I needed to change to the left or right monitor when a
movement command is triggered at the edge of the current one.</p>
<p>The script
<a href="https://github.com/alx741/dotfiles/blob/master/scripts/.scripts/ratpoison/frame-mon_navigator.sh">frame-mon_navigator.sh</a>
calculates if the current frame is the rightmost or the leftmost in the current
monitor, if it is, it goes to the next of previous monitor depending on the
movement command.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/sh</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;fdump&#39;</span><span class="kw">|</span> <span class="fu">sed</span> <span class="st">&#39;s/,/\n/g&#39;</span> <span class="kw">|</span> <span class="fu">awk</span> <span class="st">&#39;{print $5&quot; &quot;$19}&#39;</span> <span class="op">&gt;</span> /tmp/ratpoison_frame_monitor_navigator</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co"># Calculate X coordinate for rightmost frame</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="va">greater_x_coordinate</span><span class="op">=</span>0</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="bu">read</span> <span class="va">frame</span><span class="kw">;</span> <span class="cf">do</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="va">coordinate</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$frame</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f1</span><span class="va">)</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$coordinate</span> <span class="ot">-gt</span> <span class="va">$greater_x_coordinate</span> <span class="kw">]];</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        <span class="va">greater_x_coordinate</span><span class="op">=</span><span class="va">$coordinate</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="cf">done</span> <span class="op">&lt;</span> /tmp/ratpoison_frame_monitor_navigator</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co"># Calculate current frame X coordinate</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="va">x_coordinate</span><span class="op">=</span><span class="va">$(</span><span class="fu">head</span> <span class="at">-n1</span> /tmp/ratpoison_frame_monitor_navigator <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f1</span><span class="va">)</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="va">last_access</span><span class="op">=</span><span class="va">$(</span><span class="fu">head</span> <span class="at">-n1</span> /tmp/ratpoison_frame_monitor_navigator <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f2</span><span class="va">)</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="bu">read</span> <span class="va">frame</span><span class="kw">;</span> <span class="cf">do</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>    <span class="va">access</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$frame</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f2</span><span class="va">)</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$access</span> <span class="ot">-gt</span> <span class="va">$last_access</span> <span class="kw">]];</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>        <span class="va">last_access</span><span class="op">=</span><span class="va">$access</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>        <span class="va">x_coordinate</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$frame</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f1</span><span class="va">)</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="cf">done</span> <span class="op">&lt;</span> /tmp/ratpoison_frame_monitor_navigator</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> is_leftmost</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$x_coordinate</span> <span class="ot">-eq</span> 0 <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> is_rightmost</span></span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$x_coordinate</span> <span class="ot">-eq</span> <span class="va">$greater_x_coordinate</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a><span class="co"># Go to previous screen if currently in leftmost frame</span></span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a><span class="co"># Go to next screen if currently in rightmost frame</span></span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a><span class="co"># Execute frame focus otherwise</span></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;left&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="ex">is_leftmost</span><span class="kw">;</span> <span class="cf">then</span></span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;prevscreen&#39;</span></span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusleft&#39;</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a><span class="cf">elif</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;right&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="ex">is_rightmost</span><span class="kw">;</span> <span class="cf">then</span></span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;nextscreen&#39;</span></span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusright&#39;</span></span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span></code></pre></div>
<h1 id="ratpoison-tmux-navigator">Ratpoison-Tmux Navigator</h1>
<p><img src="/img/navigator/shot2.jpg" class="img-left" /></p>
<p>We need a way to pass movement commands to Tmux so Vim-Tmux navigation works as
always, but we also need to pass movement commands from Tmux to Ratpoison when a
movement command is triggered from Tmux edge pane.</p>
<p>The script
<a href="https://github.com/alx741/dotfiles/blob/master/scripts/.scripts/ratpoison/rat_tmux-navigator.sh">rat_tmux-navigator.sh</a>
is able to tell if the terminal emulator (Urxvt) is currently focused and, if
so, send the movement commands to Tmux, so it can handle panes traversing as
usual. It also defines functions that Tmux can use to know if an edge pane is
reached and send the movement commands to Ratpoison through the
<strong>frame-mon_navigator.sh</strong> script so Frame-Monitor navigation is included in the
process.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;rat&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="va">current_window</span><span class="op">=</span><span class="va">$(</span><span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;info&#39;</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">&#39;s/(.*).*(\(.*\))/\1/&#39;</span><span class="dt">\</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>                <span class="kw">|</span> <span class="fu">tr</span> <span class="st">&#39;[:upper:]&#39;</span> <span class="st">&#39;[:lower:]&#39;</span><span class="va">)</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="cf">elif</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;tmux&quot;</span> <span class="kw">]];</span><span class="cf">then</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="va">window_bottom</span><span class="op">=</span><span class="va">$(</span><span class="ex">tmux</span> list-panes <span class="at">-F</span> <span class="st">&quot;#{window_height}&quot;</span> <span class="kw">|</span> <span class="fu">head</span> <span class="at">-n1</span><span class="va">)</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="va">window_right</span><span class="op">=</span><span class="va">$(</span><span class="ex">tmux</span> list-panes <span class="at">-F</span> <span class="st">&quot;#{window_width}&quot;</span> <span class="kw">|</span> <span class="fu">head</span> <span class="at">-n1</span><span class="va">)</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="va">window_bottom</span><span class="op">=</span><span class="va">$(($window_bottom</span> <span class="op">-</span> <span class="dv">1</span><span class="va">))</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="va">window_right</span><span class="op">=</span><span class="va">$(($window_right</span> <span class="op">-</span> <span class="dv">1</span><span class="va">))</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="va">pane</span><span class="op">=</span><span class="va">$(</span><span class="ex">tmux</span> list-panes <span class="at">-F</span> <span class="st">&quot;#{pane_left} #{pane_right} #{pane_top} #{pane_bottom} #{pane_active}&quot;</span> <span class="kw">|</span> <span class="fu">grep</span> <span class="st">&#39;.* 1$&#39;</span><span class="va">)</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    <span class="va">pane_left</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$pane</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f</span> 1<span class="va">)</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="va">pane_right</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$pane</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f</span> 2<span class="va">)</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="va">pane_top</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$pane</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f</span> 3<span class="va">)</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    <span class="va">pane_bottom</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$pane</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span><span class="st">&#39; &#39;</span> <span class="at">-f</span> 4<span class="va">)</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> rat_up</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$current_window</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;urxvt&quot;</span> <span class="kw">]];</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;meta C-k&#39;</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusup&#39;</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> rat_down</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$current_window</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;urxvt&quot;</span> <span class="kw">]];</span></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;meta C-j&#39;</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusdown&#39;</span></span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> rat_right</span></span>
<span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$current_window</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;urxvt&quot;</span> <span class="kw">]];</span></span>
<span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;meta C-l&#39;</span></span>
<span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/frame-mon_navigator.sh</span> right</span>
<span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> rat_left</span></span>
<span id="cb2-50"><a href="#cb2-50" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-51"><a href="#cb2-51" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$current_window</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;urxvt&quot;</span> <span class="kw">]];</span></span>
<span id="cb2-52"><a href="#cb2-52" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-53"><a href="#cb2-53" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;meta C-h&#39;</span></span>
<span id="cb2-54"><a href="#cb2-54" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-55"><a href="#cb2-55" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/frame-mon_navigator.sh</span> left</span>
<span id="cb2-56"><a href="#cb2-56" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-57"><a href="#cb2-57" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-58"><a href="#cb2-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-59"><a href="#cb2-59" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> tmux_up</span></span>
<span id="cb2-60"><a href="#cb2-60" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-61"><a href="#cb2-61" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$pane_top</span>  <span class="ot">-eq</span> 0 <span class="kw">]];</span></span>
<span id="cb2-62"><a href="#cb2-62" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-63"><a href="#cb2-63" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusup&#39;</span></span>
<span id="cb2-64"><a href="#cb2-64" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-65"><a href="#cb2-65" aria-hidden="true" tabindex="-1"></a>        <span class="ex">tmux</span> select-pane <span class="at">-U</span></span>
<span id="cb2-66"><a href="#cb2-66" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-67"><a href="#cb2-67" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-68"><a href="#cb2-68" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-69"><a href="#cb2-69" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> tmux_down</span></span>
<span id="cb2-70"><a href="#cb2-70" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-71"><a href="#cb2-71" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$pane_bottom</span>  <span class="ot">-eq</span> <span class="va">$window_bottom</span> <span class="kw">]];</span></span>
<span id="cb2-72"><a href="#cb2-72" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-73"><a href="#cb2-73" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&#39;focusdown&#39;</span></span>
<span id="cb2-74"><a href="#cb2-74" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-75"><a href="#cb2-75" aria-hidden="true" tabindex="-1"></a>        <span class="ex">tmux</span> select-pane <span class="at">-D</span></span>
<span id="cb2-76"><a href="#cb2-76" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-77"><a href="#cb2-77" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-78"><a href="#cb2-78" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-79"><a href="#cb2-79" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> tmux_right</span></span>
<span id="cb2-80"><a href="#cb2-80" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-81"><a href="#cb2-81" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$pane_right</span>  <span class="ot">-eq</span> <span class="va">$window_right</span> <span class="kw">]];</span></span>
<span id="cb2-82"><a href="#cb2-82" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-83"><a href="#cb2-83" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/frame-mon_navigator.sh</span> right</span>
<span id="cb2-84"><a href="#cb2-84" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-85"><a href="#cb2-85" aria-hidden="true" tabindex="-1"></a>        <span class="ex">tmux</span> select-pane <span class="at">-R</span></span>
<span id="cb2-86"><a href="#cb2-86" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-87"><a href="#cb2-87" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-88"><a href="#cb2-88" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-89"><a href="#cb2-89" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> tmux_left</span></span>
<span id="cb2-90"><a href="#cb2-90" aria-hidden="true" tabindex="-1"></a><span class="kw">{</span></span>
<span id="cb2-91"><a href="#cb2-91" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$pane_left</span>  <span class="ot">-eq</span> 0 <span class="kw">]];</span></span>
<span id="cb2-92"><a href="#cb2-92" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb2-93"><a href="#cb2-93" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/frame-mon_navigator.sh</span> left</span>
<span id="cb2-94"><a href="#cb2-94" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb2-95"><a href="#cb2-95" aria-hidden="true" tabindex="-1"></a>        <span class="ex">tmux</span> select-pane <span class="at">-L</span></span>
<span id="cb2-96"><a href="#cb2-96" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb2-97"><a href="#cb2-97" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb2-98"><a href="#cb2-98" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-99"><a href="#cb2-99" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-100"><a href="#cb2-100" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;rat&quot;</span> <span class="kw">]];</span><span class="cf">then</span></span>
<span id="cb2-101"><a href="#cb2-101" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="st">&quot;</span><span class="va">$2</span><span class="st">&quot;</span> <span class="kw">in</span></span>
<span id="cb2-102"><a href="#cb2-102" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;up&#39;</span><span class="kw">)</span></span>
<span id="cb2-103"><a href="#cb2-103" aria-hidden="true" tabindex="-1"></a>            <span class="ex">rat_up</span></span>
<span id="cb2-104"><a href="#cb2-104" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-105"><a href="#cb2-105" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;down&#39;</span><span class="kw">)</span></span>
<span id="cb2-106"><a href="#cb2-106" aria-hidden="true" tabindex="-1"></a>            <span class="ex">rat_down</span></span>
<span id="cb2-107"><a href="#cb2-107" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-108"><a href="#cb2-108" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;right&#39;</span><span class="kw">)</span></span>
<span id="cb2-109"><a href="#cb2-109" aria-hidden="true" tabindex="-1"></a>            <span class="ex">rat_right</span></span>
<span id="cb2-110"><a href="#cb2-110" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-111"><a href="#cb2-111" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;left&#39;</span><span class="kw">)</span></span>
<span id="cb2-112"><a href="#cb2-112" aria-hidden="true" tabindex="-1"></a>            <span class="ex">rat_left</span></span>
<span id="cb2-113"><a href="#cb2-113" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-114"><a href="#cb2-114" aria-hidden="true" tabindex="-1"></a>    <span class="cf">esac</span></span>
<span id="cb2-115"><a href="#cb2-115" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-116"><a href="#cb2-116" aria-hidden="true" tabindex="-1"></a><span class="cf">elif</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;tmux&quot;</span> <span class="kw">]];</span><span class="cf">then</span></span>
<span id="cb2-117"><a href="#cb2-117" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="st">&quot;</span><span class="va">$2</span><span class="st">&quot;</span> <span class="kw">in</span></span>
<span id="cb2-118"><a href="#cb2-118" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;up&#39;</span><span class="kw">)</span></span>
<span id="cb2-119"><a href="#cb2-119" aria-hidden="true" tabindex="-1"></a>            <span class="ex">tmux_up</span></span>
<span id="cb2-120"><a href="#cb2-120" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-121"><a href="#cb2-121" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;down&#39;</span><span class="kw">)</span></span>
<span id="cb2-122"><a href="#cb2-122" aria-hidden="true" tabindex="-1"></a>            <span class="ex">tmux_down</span></span>
<span id="cb2-123"><a href="#cb2-123" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-124"><a href="#cb2-124" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;right&#39;</span><span class="kw">)</span></span>
<span id="cb2-125"><a href="#cb2-125" aria-hidden="true" tabindex="-1"></a>            <span class="ex">tmux_right</span></span>
<span id="cb2-126"><a href="#cb2-126" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-127"><a href="#cb2-127" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;left&#39;</span><span class="kw">)</span></span>
<span id="cb2-128"><a href="#cb2-128" aria-hidden="true" tabindex="-1"></a>            <span class="ex">tmux_left</span></span>
<span id="cb2-129"><a href="#cb2-129" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb2-130"><a href="#cb2-130" aria-hidden="true" tabindex="-1"></a>    <span class="cf">esac</span></span>
<span id="cb2-131"><a href="#cb2-131" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span></code></pre></div>
<h1 id="vim-tmux-navigator">Vim-Tmux Navigator</h1>
<p>Modifying Tmux mappings to use above scripts will make it work for
Tmux-Ratpoison traversing but when a Vim instance is on a Tmux edge pane it will
not jump to the appropriate Ratpoison split. To solve it I forked the
<code>vim-tmux-navigator</code> project and made the right changes to it in the
<a href="https://github.com/alx741/vim-tmux-navigator/tree/vim-tmux-wm-monitor">vim-tmux-wm-monitor
branch</a></p>
<p>Then using <a href="https://github.com/junegunn/vim-plug">vim-plug</a> I install it in my
<code>.vimrc</code> with:</p>
<pre><code>Plug &#39;alx741/vim-tmux-navigator&#39;, { &#39;branch&#39;: &#39;vim-tmux-wm-monitor&#39; }</code></pre>
<h1 id="mappings">Mappings</h1>
<p>Putting all together requires the appropriate mappings for Ratpoison and Tmux.
Vim is already configured with the forked plugin.</p>
<h2 id="ratpoison">Ratpoison</h2>
<p>These lines on <code>.ratpoisonrc</code> will do the top level handling. Take into account
the path to the <code>rat_tmux-navigator.sh</code> script.</p>
<pre><code>definekey top C-k exec ~/.scripts/ratpoison/rat_tmux-navigator.sh rat up
definekey top C-j exec ~/.scripts/ratpoison/rat_tmux-navigator.sh rat down
definekey top C-l exec ~/.scripts/ratpoison/rat_tmux-navigator.sh rat right
definekey top C-h exec ~/.scripts/ratpoison/rat_tmux-navigator.sh rat left</code></pre>
<h2 id="tmux">Tmux</h2>
<p>Finally, these lines on <code>.tmux.conf</code> are basically modified versions of the
<code>vim-tmux-navigator</code> plugin ones.</p>
<pre><code>is_vim=&quot;ps -o state= -o comm= -t &#39;#{pane_tty}&#39; \
    | grep -iqE &#39;^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$&#39;&quot;
bind-key C-h if-shell &quot;$is_vim&quot; &quot;send-keys C-h&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux left&#39;&quot;
bind-key C-j if-shell &quot;$is_vim&quot; &quot;send-keys C-j&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux down&#39;&quot;
bind-key C-k if-shell &quot;$is_vim&quot; &quot;send-keys C-k&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux up&#39;&quot;
bind-key C-l if-shell &quot;$is_vim&quot; &quot;send-keys C-l&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux right&#39;&quot;
bind-key -n C-h if-shell &quot;$is_vim&quot; &quot;send-keys C-h&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux left&#39;&quot;
bind-key -n C-j if-shell &quot;$is_vim&quot; &quot;send-keys C-j&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux down&#39;&quot;
bind-key -n C-k if-shell &quot;$is_vim&quot; &quot;send-keys C-k&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux up&#39;&quot;
bind-key -n C-l if-shell &quot;$is_vim&quot; &quot;send-keys C-l&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux right&#39;&quot;
bind-key h if-shell &quot;$is_vim&quot; &quot;send-keys C-h&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux left&#39;&quot;
bind-key j if-shell &quot;$is_vim&quot; &quot;send-keys C-j&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux down&#39;&quot;
bind-key k if-shell &quot;$is_vim&quot; &quot;send-keys C-k&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux up&#39;&quot;
bind-key l if-shell &quot;$is_vim&quot; &quot;send-keys C-l&quot;  &quot;run &#39;~/.scripts/ratpoison/rat_tmux-navigator.sh tmux right&#39;&quot;</code></pre>]]></summary>
</entry>
<entry>
    <title>How to write C in 2016</title>
    <link href="http://www.sillybytes.net/2016/06/how-to-write-c-in-2016.html" />
    <id>http://www.sillybytes.net/2016/06/how-to-write-c-in-2016.html</id>
    <published>2016-06-19</published>
    <updated>2016-06-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Matt wrote a very interesting and totally recommended post about <a href="https://matt.sh/howto-c">how to C (as
of 2016)</a>. Keith Thompson wrote later a very detailed
and rather useful
<a href="https://github.com/Keith-S-Thompson/how-to-c-response/blob/master/README.md">critique</a>
with some extra notes about Matt’s post. I urge you to go ahead and read both
articles.</p>
<p>Here I’d like to point out some things I deem important about tooling.</p>
<!--more-->
<p><img src="/img/clang/shot1.jpg" /></p>
<h1 id="use-build-tools">Use build tools</h1>
<p>This might be obvious to most C programmers, but I’ve seen quite a lot of
people, novices specially, copying and pasting compilation commands on every
iteration.</p>
<p>Using a build tool will help you automate the building process, but also
testing, distribution package generation, etc.</p>
<p>In order to sanely write C code the bear minimum you need is to know and feel
comfortable <a href="http://mrbook.org/blog/tutorials/make/">writing</a> and
<a href="http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/">using</a>
<em>makefiles</em>, so the compilation process can be described as a recipe and
triggered by issuing the <code>$ make</code> command.</p>
<p>Using <a href="https://www.gnu.org/software/make/">make</a> alone by writing <em>makefiles</em>
will take you pretty far, but for larger software systems you might want to
automate things even further: examine the target system for both static and
dynamic libraries, binaries available and configure things to adapt to the
system and be as portable as possible.
<a href="https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html">Autotools</a>
to the rescue.</p>
<p><a href="https://autotools.io/index.html">Learning</a> and
<a href="https://www.sourceware.org/autobook/autobook/autobook.html#Top">using</a>
<em>Autotools</em> is not much of a trivial task, but when the complexity in your code
starts to get out of hand, <em>Autotools</em> do outweigh the effort of getting a grasp
on it.</p>
<p>If your code needs not only be portable on Posix systems, but also get compiled
on Windows machines, <a href="https://cmake.org/">CMake</a> is what you need.</p>
<h1 id="the-standard-c-library-is-your-friend">The standard C library is your friend</h1>
<p>You can’t get any better at writing C code if you’re not familiar enough with
the <a href="https://www.gnu.org/software/libc/manual/html_node/index.html">Standard C library
(libc)</a>. I’ve
seen developers trying to re-invent error reporting for instance, so make sure
to be familiar with <a href="https://www.gnu.org/software/libc/manual/html_node/index.html#toc-Error-Reporting-1">libc’s error reporting
mechanisms</a>,
as well as <a href="https://www.gnu.org/software/libc/manual/html_mono/libc.html">everything else it has to
offer</a>, you’ll be
pleasantly surprised.</p>
<h1 id="use-a-linter">Use a linter</h1>
<p>A <em>linter</em>, is a program that will statically check the <strong>source code</strong> (not the
binaries) to find any known non-portable constructs, vulnerabilities from common
programming mistakes, bad practices and any other general coding mistakes that
can cause your program leak memory, step on segmentation faults and the like.</p>
<p><a href="http://www.splint.org/">Splint</a> is one such linter. It will tell you a <em>lot</em>
about what your code might be doing wrong.</p>
<p>You can use it very easily by specifying the source files like:</p>
<pre><code>$ splint foo.c bar.c</code></pre>
<p>Most of splint’s output will be suggestions rather than critical warnings, but
following its recommendations with poise will make your code more robust.</p>
<p>You can tune the level of paranoia with these arguments: <code>-weak</code>, <code>-standard</code>,
<code>-cheks</code> and <code>-strict</code>.</p>
<h1 id="valgrind">Valgrind</h1>
<p><img src="/img/clang/shot6.png" /></p>
<p><a href="http://valgrind.org/">Valgrind</a> is a <em>profiling</em> program with more than a few
neat tricks up its sleeve. In contrast to <em>splint</em>, it will use your
<strong>executable program</strong> to help you find memory leaks, make it faster and
correct.</p>
<p>When compiling your program use the <code>-g</code> compiler flag to include extra
debugging information in the executable.</p>
<p>Then you can run you program with Valgrind like this:</p>
<pre><code>$ valgrind foobar arg1 arg2</code></pre>
<p>That will use the <code>Memcheck</code> tool, one of multiple <a href="http://valgrind.org/docs/manual/manual.html">Valgrind’s
tools</a>.</p>
<h1 id="use-a-debugger">Use a debugger</h1>
<p>Yeah sure, you can fill up you code with <code>printf</code> calls for debugging and pretty
much get away with it, but you’re missing out on the power a proper debugger
brings to the table. Some debugging sessions will be far easier with
<a href="https://www.gnu.org/software/gdb/">GDB</a> than a bunch of <code>printf</code> lines all
around.</p>
<h1 id="use-a-control-version-system">Use a control version system</h1>
<p>You might think you can get away with keeping multiple directories for each
version of your program if it’s small enough, but that mindset will eventually
bite you. A control version system will give you some superpowers for
collaboration, version restoring, multi-branching, proper history tracking, back
up and so much more.</p>
<p>You could use <a href="http://www.nongnu.org/cvs/">CVS</a> or <a href="https://subversion.apache.org/">SVN
(Subversion)</a>, but should prefer more modern
systems like <a href="https://www.mercurial-scm.org/wiki/">Mercurial</a>,
<a href="https://darcs.net">Darcs</a> or <a href="https://git-scm.com/">Git</a>.</p>
<p>Furthermore, even if you’re working alone in a project and won’t collaborate
with more developers, using a repository hosting service like
<a href="https://bitbucket.org/">Bitbucket</a>, <a href="https://github.com/">GitHub</a>, or
<a href="https://gitlab.com/">GitLab</a> is a great way to always have a backup of your
code. And in the future, if more people join to your project, collaboration will
be frictionless.</p>
<h1 id="automated-documentation">Automated documentation</h1>
<blockquote>
<p>Documentation is like sex: when it is good, it is very good; and when it is
bad, it is better than nothing
–Dick Brandon</p>
</blockquote>
<p>Nobody likes to write and maintain documentation, so keep it as automated as
possible.</p>
<p>Using tools like <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a> will provide
documentation generation from source code and multi-target format documentation
(HTML, LATEX, PDF, TROFF Man pages, PostScript, etc).</p>
<p>Remember to use your abilities writing <em>Make</em> recipes to automate the
documentation process as well!</p>
<p>Always write documentation in ways that every possible aspect of it can be
automated. Don’t write documentation using MS Word!. Use
<a href="https://daringfireball.net/projects/markdown/syntax">Markdown</a>,
<a href="http://www.methods.co.nz/asciidoc/">AsciiDoc</a>,
<a href="http://www.docbook.org/">DocBook</a>.</p>
<p>If you really want a WYSIWYG tool, <a href="https://www.libreoffice.org/">LibreOffice</a>
has a CLI interface that allows you to generate PDF files, so you can add in
your <em>Make</em> recipe something like:</p>
<pre><code>document.pdf: document.odt
    libreoffice --convert-to pdf $&lt;</code></pre>
<p>You can even automatize some graphics generation using
<a href="http://www.graphviz.org/doc/info/lang.html">DOT</a>.</p>
<h1 id="unit-testing">Unit testing</h1>
<p><img src="/img/clang/shot12.jpg" /></p>
<p>In a nutshell, <a href="https://en.wikipedia.org/wiki/Unit_testing">unit testing</a> is
about writing pieces of code that will exercise the functions of your software
and compare the results to what it is expected to produce. Think of it as
writing a program tu use your program and automatically check if it does what
it’s supposed to do.</p>
<p>You can take this approach further by practicing <a href="https://en.wikipedia.org/wiki/Test-driven_development">Test Driven Development
(TDD)</a>.</p>
<p>Although you could write test functions by hand, there are some great testing
frameworks that will make things smoother. I like
<a href="https://libcheck.github.io/check/">Check</a> in particular, running <code>$ make check</code>
will test your software.</p>
<p>Writing tests with <em>Check</em> is pretty simple, take a look:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;check.h&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;../src/foo.h&quot;</span><span class="pp">  </span><span class="co">// Contains the &#39;add&#39; function</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>START_TEST <span class="op">(</span>my_test<span class="op">)</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> result <span class="op">=</span> add<span class="op">(</span><span class="dv">2</span><span class="op">,</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    ck_assert_int_eq<span class="op">(</span>result<span class="op">,</span> <span class="dv">4</span><span class="op">);</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>END_TEST</span></code></pre></div>
<p>This test will use your <code>add</code> function, declared in <code>src/foo.h</code>, and <em>assert</em>
that the result of adding <code>2</code> and <code>2</code> equals <code>4</code>, so next time changes are made
in the <code>add</code> function that make it misbehave, you’ll catch the bug when running
the tests. Granted this example is over simplistic, but you get the idea. Check
every possible edge case. The more robust the tests are, the more robust your
program will be.</p>
<h1 id="learn-functional-programming">Learn functional programming</h1>
<p><img src="/img/clang/shot13.jpg" /></p>
<p>Learning how to think functionally will improve your C code despite C being an
imperative language, you’ll stop using mutable global state and all the kind of
stuff that prevents your software from being multi thread safe, and correct in
general.</p>
<p>If you work on embedded software, you’re probably writing in C. Considering that
even relatively cheap embedded hardware today has more than one core,
parallelism is pretty important and a functional programming mind set will help
you to get it right.</p>
<p>There are many multi-paradigm languages out there, like Python and Ruby for
instance, but my personal recommendation is: Learn a purely functional
programming language, in particular, <a href="https://www.haskell.org/">blow your mind with
Haskell</a>.</p>
<h1 id="write-in-c">Write in C</h1>
<p>Eric Raymond <a href="http://www.catb.org/esr/faqs/hacker-howto.html">said</a>:</p>
<blockquote>
<p>The more you can avoid programming in C the more productive you will be.</p>
</blockquote>
<p>And he’s got a point. However, I don’t believe C is a language you should need
to <em>avoid</em>, instead, do write in C when you can take advantage of its power and
can afford the additional effort it takes to handle that power.</p>
<p>Depending on what you’re working on, other languages would probably fit better
and give you higher level abstraction with just a small perforce hit. In most
cases, when you think you need C you can probably write it in
<a href="https://www.rust-lang.org/">Rust</a> or <a href="https://golang.org/">Go</a> (I recommend the
former) and get the work done with great performance and low level management
only when needed.</p>
<p>C is not a monster you have to hide from, it’s just a (wonderful) tool. You have
to pick the right tool for the job. C is the right tool for many jobs.</p>]]></summary>
</entry>
<entry>
    <title>From PIC to AVR</title>
    <link href="http://www.sillybytes.net/2016/06/from-pic-to-avr.html" />
    <id>http://www.sillybytes.net/2016/06/from-pic-to-avr.html</id>
    <published>2016-06-17</published>
    <updated>2016-06-17T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>This is my humble contribution to the <em>PIC vs AVR holy war</em>.</p>
<p>TL;DR: I was previously a PIC user but decided I hate it, switched to AVR and
love it!</p>
<p><a href="https://en.wikipedia.org/wiki/PIC_microcontroller">PIC</a> from Microchip and
<a href="https://en.wikipedia.org/wiki/Atmel_AVR">AVR</a> from Atmel are both wonderful
families of microcontrollers for the hobbyist and professional as well. I’m
going to argue, however, that AVR is overall better for every purpose and
because of multiple reasons.</p>
<!--more-->
<h1 id="hardware">Hardware</h1>
<p>I’m referring to programming/flashing hardware here. The only feasible way I
currently have to program PIC uCs is by using my <a href="https://sillybytes.net/2013/08/programando-pics-en-gnulinux-hardware-y.html">parallel port PIC
programmer</a>
and the almost forgotten at this point, though amazing <em>Odyssey</em> software.</p>
<p>The only feasible way you say? Yes!, at the time of writing, getting a PICkit (2
or 3) requires at least a $100+ (USD) budget. Any other solution like PICkit
clones are not much cheaper either. Not at all a reasonable budget for the 3rd
world hobbyist.</p>
<p>Using a Microchip’s PICkit (or a clone) requires using the <em>pk2cmd</em>
<strong>privative</strong> software, which means that doing anything outside MPLAB is a major
PITA.</p>
<p>AVR on the other hand, lets you flash chips so easily and for so cheap!, A DAPA
(or DASA) programmer is simple, inexpensive and fast. Both the USBTiny and the
USBASP programmers are readily available at reasonable prices online and can be
used with the <em>avrdude</em> CLI tool, a much welcomed improvement over MPLAB
behemoth.</p>
<h1 id="software">Software</h1>
<h2 id="programming">Programming</h2>
<p>Yes, Microchip provides a complete, fully compatible IDE (MPLAB) that can run in
Unix* systems and can talk to PICkit. <a href="https://sillybytes.net/2016/03/why-do-i-hate-ides.htm">But using an IDE pains
me</a>, and using
<strong>privative</strong> software that only works with <strong>privative</strong> hardware pains me even
more.</p>
<p>I want a Free Software (as in Freedom) command line tool to drive a reasonably
priced programmer hardware. The <em>Odyssey</em> utility that I’ve mentioned is a
blessing!, but getting (Free) software for a Serial programmer, a PICkit or a
PICkit clone is impossible, nobody cares about PIC Free tooling, just go and use
all the privative, restrictive stuff that Microchip forces onto you.</p>
<p><em>Avrdude</em> solves everything. A unified (GPL) tool that can drive any programmer
with any hardware interface. I absolutely love it!</p>
<h2 id="compiler">Compiler</h2>
<p>The same problem here, Microchip provides a freeware (privative) compiler –that
goes as far as to restrict some optimizations for the freeware user– and the
only sane way to use it is through the bloated IDE.</p>
<p>The <a href="http://sdcc.sourceforge.net/">SDCC</a> compiler solves this. Kind of… Look I
really like SDCC, it’s an excellent Free Software compiler, but the PIC port is
not that good (yet?), it still requires you to use non-free Microchip’s header
files and linker mappings.</p>
<p>With AVR, you get to use the <em>GCC</em> port. Yes that’s right, the GNU freaking C
compiler! And you also get a fully featured GPL
<a href="http://www.nongnu.org/avr-libc/">avr-libc</a> on top of that.</p>
<h1 id="community">Community</h1>
<p>I’ve always struggled to find help with PIC. Sure there is a lot out there,
Microchip’s official documentation is very good and professional, but even in
Microchip’s own forums you’re not able to get the level of community help you
can get from AVR’s community.</p>
<p>AVR has a hacker/hobbyist/professional Free Software and Open Hardware
centered community that makes it so much better overall.</p>
<h1 id="conclusion">Conclusion</h1>
<p>For me PIC is horrible mostly because I dislike IDE’s and prefer to use CLI
tools that I can easily script with, adapt to powerful text editors, run on
remote machines over network and so on. I acknowledge, however, that many
developers feel the opposite way and dislike the command line interface and/or
couldn’t live without an IDE, so the reasons I don’t like PIC and love AVR might
be the same reasons why you love PIC instead.</p>
<p>It’s all about <strong>tooling</strong>. When I say “I don’t like PIC”, what I really mean
is: “I don’t like PIC’s <strong>tooling</strong>”. Both PIC and AVR have extremely powerful
and comparable hardware. I do like the <strong>devices</strong> from both of them.</p>]]></summary>
</entry>
<entry>
    <title>Firefox control on steroids (Firefox + Ratpoison + Mozrepl)</title>
    <link href="http://www.sillybytes.net/2016/05/firefox-control-on-steroids-firefox.html" />
    <id>http://www.sillybytes.net/2016/05/firefox-control-on-steroids-firefox.html</id>
    <published>2016-05-27</published>
    <updated>2016-05-27T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Here is what We expect to achieve. Every command starts with Ratpoison’s prefix + ‘f’ like in <code>C-t f</code>:</p>
<pre><code>**Command**     **Action**

    f           Facebook
    y           Youtube
    r           Reddit
    g           Github
    o           Open a new tab
    w           Open a new window
    s           Search for the current content in the clipboard
    /           Jump to the tab with url mathing a user input
    l           Open a new tab with the lyrics of the currenlty playing song (mpd)</code></pre>
<!--more-->
<p>This does a bit more than what you’re probably thinking. Take for instance the
<code>f</code> command with the <em>“Facebook”</em> action, it will afford you this:</p>
<p>No matter where you are, which window has the focus, or even if Firefox is
currently running or not. Firefox will be started (if needed) and acquire the
focus, then all your tabs will be parsed (starting from the last one), and if a
Facebook tab is found then jump to it, if there is no Facebook tab then start a
new one.</p>
<p>The same is extended to any of the other sites available (The list can be
extended to suit you needs).</p>
<p>The <code>o</code> commands is self-explanatory, the only advantage of this one is the
ability to quickly get a new tab no matter where you are, which window has the
focus, or if Firefox is running or not.</p>
<p>The <code>s</code> command is quite nice, imagine this:</p>
<p>You’re trying to compile some code, but the compiler complains with a cryptic
message, so you use <a href="https://github.com/alx741/dotfiles/blob/master/tmux/.tmux.conf#L55-L59">tmux to copy the error
message</a>,
then issue the key sequence <code>C-t f /</code> and BANG!, you get a new Firefox tab in
front of you with the search engine results for the error message. And this is
applicable to any content in your clipboard as well!</p>
<p>The <code>/</code> command prompts the user for a query and jumps to the tab with a URL
that contains the query as a substring.</p>
<p>The <code>l</code> command will take the name of the currently playing song in MPD, search
for it, and open the first result for the song lyrics in a new tab.</p>
<h1 id="how-to">How to</h1>
<p>So you’re sold, let’s make it happen. The main dependencies are:</p>
<ul>
<li>Firefox</li>
<li><a href="https://github.com/bard/mozrepl">Mozrepl</a></li>
<li>Ratpoison</li>
<li>Expect</li>
</ul>
<p>You can install them all with the system package manager, except for Mozrepl
which you can get from Firefox addons.</p>
<p>This also depends on a Ratpoison
<a href="https://github.com/alx741/dotfiles/blob/master/scripts/.scripts/ratpoison/app_select.sh">script</a>
introduced in a previous post, so make sure to get that first.</p>
<p>Some extra <code>~/.ratpoisonrc</code> is needed for the new mappings:</p>
<pre><code>newkmap firefox
definekey firefox f exec ~/.scripts/ratpoison/firefox.sh select_tab facebook
definekey firefox y exec ~/.scripts/ratpoison/firefox.sh select_tab youtube
definekey firefox e exec ~/.scripts/ratpoison/firefox.sh select_tab evirtual
definekey firefox r exec ~/.scripts/ratpoison/firefox.sh select_tab reddit
definekey firefox g exec ~/.scripts/ratpoison/firefox.sh select_tab github
definekey firefox o exec ~/.scripts/ratpoison/firefox.sh new_tab
definekey firefox w exec ~/.scripts/ratpoison/firefox.sh new_window
definekey firefox s exec ~/.scripts/ratpoison/firefox.sh clipboard_search
definekey firefox l exec ~/.scripts/ratpoison/firefox.sh search_lyrics
definekey firefox slash exec ~/.scripts/ratpoison/firefox.sh search_tab
bind f readkey firefox</code></pre>
<p>Most of the magic is performed by <em>Mozrepl</em>. Unfortunately, I couldn’t get it to
load an external script, though <em>Expect</em> is needed for the communication with it
anyways, so let’s use it to hand the script line by line.</p>
<p>The <code>select_tab.js</code>
<a href="https://github.com/alx741/dotfiles/blob/master/mozrepl/.mozrepl/select_tab.js">script</a>
is on charge of parsing the tabs to find one that matches the query and jump to
it.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">selectTab</span>(page) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> numTabs<span class="op">=</span>gBrowser<span class="op">.</span><span class="at">browsers</span><span class="op">.</span><span class="at">length</span><span class="op">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> url<span class="op">=</span><span class="st">&quot;&quot;</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span>(i<span class="op">=</span>numTabs<span class="op">-</span><span class="dv">1</span><span class="op">;</span> i<span class="op">&gt;</span><span class="dv">0</span><span class="op">;</span> i<span class="op">--</span>) {</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        url<span class="op">=</span>gBrowser<span class="op">.</span><span class="at">browsers</span>[i]<span class="op">.</span><span class="at">contentDocument</span><span class="op">.</span><span class="at">location</span><span class="op">.</span><span class="at">href</span><span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span>(url<span class="op">.</span><span class="fu">search</span>(page) <span class="op">!=</span> <span class="op">-</span><span class="dv">1</span>) {</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>            gBrowser<span class="op">.</span><span class="at">tabContainer</span><span class="op">.</span><span class="at">selectedIndex</span><span class="op">=</span>i<span class="op">;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="kw">true</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Use <em>Expect</em> and the <code>select_tab.expect</code>
<a href="https://github.com/alx741/dotfiles/blob/master/mozrepl/.mozrepl/select_tab.expect">script</a>
to perform the telnet communication with <em>Mozrepl</em> and send the script and
commands as well.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/usr/bin/expect</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="bu">set</span> page [lindex <span class="va">$argv</span> 0]</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="bu">set</span> port 4242</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="bu">set</span> file [open <span class="st">&quot;select_tab.js&quot;</span>]</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="bu">set</span> content [split [read <span class="va">$file</span>] <span class="st">&quot;\n&quot;</span>]</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="ex">close</span> <span class="va">$file</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="ex">spawn</span> telnet localhost <span class="va">$port</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="ex">foreach</span> line <span class="va">$content</span> {</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    <span class="ex">send</span> <span class="st">&quot;</span><span class="va">$line</span><span class="st">\r&quot;</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="er">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="ex">send</span> <span class="st">&quot;selectTab(</span><span class="dt">\&quot;</span><span class="va">$page</span><span class="dt">\&quot;</span><span class="st">);\r&quot;</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="ex">expect</span> <span class="st">&quot;repl2&gt; &quot;</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="ex">expect</span> {</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;true&quot;</span> {</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>        <span class="bu">exit</span> 0</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="er">}</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;false&quot;</span> {</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>        <span class="bu">exit</span> 1</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>    <span class="er">}</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a><span class="er">}</span></span></code></pre></div>
<p>Now the <code>firefox.sh</code>
<a href="https://github.com/alx741/dotfiles/blob/master/scripts/.scripts/ratpoison/firefox.sh">script</a>,
invoked from Ratpoison, will glue it all together.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="va">URL</span><span class="op">=</span><span class="st">&quot;&quot;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> set_url</span> <span class="kw">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="kw">in</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;facebook&#39;</span><span class="kw">)</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>            <span class="va">URL</span><span class="op">=</span><span class="st">&quot;www.facebook.com&quot;</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;youtube&#39;</span><span class="kw">)</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>            <span class="va">URL</span><span class="op">=</span><span class="st">&quot;www.youtube.com&quot;</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;reddit&#39;</span><span class="kw">)</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>            <span class="va">URL</span><span class="op">=</span><span class="st">&quot;www.reddit.com&quot;</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;github&#39;</span><span class="kw">)</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>            <span class="va">URL</span><span class="op">=</span><span class="st">&quot;www.github.com&quot;</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;evirtual&#39;</span><span class="kw">)</span></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a>            <span class="va">URL</span><span class="op">=</span><span class="st">&quot;evirtual.ucuenca.edu.ec&quot;</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a>            <span class="cf">;;</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">esac</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> select_tab</span> <span class="kw">{</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>    <span class="bu">cd</span> ~/.mozrepl/</span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a>    <span class="ex">expect</span> select_tab.expect <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span> <span class="op">&gt;</span> /dev/null</span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="va">$?</span> <span class="ot">!=</span> 0 <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true" tabindex="-1"></a>        <span class="ex">set_url</span> <span class="st">&quot;</span><span class="va">$1</span><span class="st">&quot;</span></span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$URL</span><span class="st">&quot;</span> <span class="ot">!=</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a>            <span class="ex">firefox</span> <span class="at">--new-tab</span> <span class="st">&quot;</span><span class="va">$URL</span><span class="st">&quot;</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a>        <span class="cf">fi</span></span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb5-33"><a href="#cb5-33" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb5-34"><a href="#cb5-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-35"><a href="#cb5-35" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> search_tab</span> <span class="kw">{</span></span>
<span id="cb5-36"><a href="#cb5-36" aria-hidden="true" tabindex="-1"></a>    <span class="va">query</span><span class="op">=</span><span class="kw">`</span><span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;prompt [Tab] &gt;  &quot;</span><span class="kw">`</span></span>
<span id="cb5-37"><a href="#cb5-37" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$query</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span> <span class="cf">then</span> <span class="bu">exit</span> 0<span class="kw">;</span> <span class="cf">fi</span></span>
<span id="cb5-38"><a href="#cb5-38" aria-hidden="true" tabindex="-1"></a>    <span class="ex">select_tab</span> <span class="st">&quot;</span><span class="va">$query</span><span class="st">&quot;</span></span>
<span id="cb5-39"><a href="#cb5-39" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb5-40"><a href="#cb5-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-41"><a href="#cb5-41" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> clipboard_search</span> <span class="kw">{</span></span>
<span id="cb5-42"><a href="#cb5-42" aria-hidden="true" tabindex="-1"></a>    <span class="va">search</span><span class="op">=</span><span class="va">$(</span><span class="ex">xclip</span> <span class="at">-selection</span> clipboard <span class="at">-o</span><span class="va">)</span></span>
<span id="cb5-43"><a href="#cb5-43" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$search</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb5-44"><a href="#cb5-44" aria-hidden="true" tabindex="-1"></a>        <span class="bu">exit</span> 0</span>
<span id="cb5-45"><a href="#cb5-45" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb5-46"><a href="#cb5-46" aria-hidden="true" tabindex="-1"></a>    <span class="va">search</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$search</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">&#39;s/ /+/g&#39;</span><span class="va">)</span></span>
<span id="cb5-47"><a href="#cb5-47" aria-hidden="true" tabindex="-1"></a>    <span class="va">google_url</span><span class="op">=</span><span class="st">&quot;https://www.google.com/search?q=</span><span class="va">$search</span><span class="st">&quot;</span></span>
<span id="cb5-48"><a href="#cb5-48" aria-hidden="true" tabindex="-1"></a>    <span class="ex">firefox</span> <span class="at">--new-tab</span> <span class="st">&quot;</span><span class="va">$google_url</span><span class="st">&quot;</span></span>
<span id="cb5-49"><a href="#cb5-49" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb5-50"><a href="#cb5-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-51"><a href="#cb5-51" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> search_lyrics</span> <span class="kw">{</span></span>
<span id="cb5-52"><a href="#cb5-52" aria-hidden="true" tabindex="-1"></a>    <span class="va">search</span><span class="op">=</span><span class="va">$(</span><span class="ex">mpc</span> <span class="kw">|</span> <span class="fu">head</span> <span class="at">-n</span> 1<span class="va">)</span></span>
<span id="cb5-53"><a href="#cb5-53" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">[[</span> <span class="st">&quot;</span><span class="va">$search</span><span class="st">&quot;</span> <span class="ot">==</span> <span class="st">&quot;&quot;</span> <span class="kw">]];</span> <span class="cf">then</span></span>
<span id="cb5-54"><a href="#cb5-54" aria-hidden="true" tabindex="-1"></a>        <span class="bu">exit</span> 0</span>
<span id="cb5-55"><a href="#cb5-55" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb5-56"><a href="#cb5-56" aria-hidden="true" tabindex="-1"></a>    <span class="va">search</span><span class="op">+=</span><span class="st">&quot; lyrics&quot;</span></span>
<span id="cb5-57"><a href="#cb5-57" aria-hidden="true" tabindex="-1"></a>    <span class="va">search</span><span class="op">=</span><span class="va">$(</span><span class="bu">echo</span> <span class="st">&quot;</span><span class="va">$search</span><span class="st">&quot;</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">&#39;s/ /+/g&#39;</span><span class="va">)</span></span>
<span id="cb5-58"><a href="#cb5-58" aria-hidden="true" tabindex="-1"></a>    <span class="ex">curl</span> <span class="at">-A</span> <span class="st">&#39;Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/31.0&#39;</span><span class="dt">\</span></span>
<span id="cb5-59"><a href="#cb5-59" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;https://www.google.com/search?q=</span><span class="va">$search</span><span class="st">&quot;</span><span class="dt">\</span></span>
<span id="cb5-60"><a href="#cb5-60" aria-hidden="true" tabindex="-1"></a>            <span class="op">&gt;</span> /tmp/google_search_result.html</span>
<span id="cb5-61"><a href="#cb5-61" aria-hidden="true" tabindex="-1"></a>    <span class="va">url</span><span class="op">=</span><span class="va">$(</span><span class="fu">sed</span> <span class="st">&#39;s/&gt;/&gt;\r\n/g&#39;</span> /tmp/google_search_result.html<span class="dt">\</span></span>
<span id="cb5-62"><a href="#cb5-62" aria-hidden="true" tabindex="-1"></a>        <span class="kw">|</span> <span class="fu">grep</span> <span class="at">-m</span> 1 <span class="st">&#39;&lt;a href=&quot;http:.*&quot;.*&gt;&#39;</span><span class="dt">\</span></span>
<span id="cb5-63"><a href="#cb5-63" aria-hidden="true" tabindex="-1"></a>        <span class="kw">|</span> <span class="fu">sed</span> <span class="at">-e</span> <span class="st">&#39;s/.*href=&quot;\([^&quot;]*\)&quot;.*/\1/&#39;</span><span class="va">)</span></span>
<span id="cb5-64"><a href="#cb5-64" aria-hidden="true" tabindex="-1"></a>    <span class="ex">firefox</span> <span class="at">--new-tab</span> <span class="st">&quot;</span><span class="va">$url</span><span class="st">&quot;</span></span>
<span id="cb5-65"><a href="#cb5-65" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb5-66"><a href="#cb5-66" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-67"><a href="#cb5-67" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="va">$1</span> <span class="kw">in</span></span>
<span id="cb5-68"><a href="#cb5-68" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;select_tab&#39;</span><span class="kw">)</span></span>
<span id="cb5-69"><a href="#cb5-69" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/app_select.sh</span> firefox</span>
<span id="cb5-70"><a href="#cb5-70" aria-hidden="true" tabindex="-1"></a>        <span class="ex">select_tab</span> <span class="va">$2</span></span>
<span id="cb5-71"><a href="#cb5-71" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-72"><a href="#cb5-72" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;search_tab&#39;</span><span class="kw">)</span></span>
<span id="cb5-73"><a href="#cb5-73" aria-hidden="true" tabindex="-1"></a>        <span class="ex">search_tab</span></span>
<span id="cb5-74"><a href="#cb5-74" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-75"><a href="#cb5-75" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;new_tab&#39;</span><span class="kw">)</span></span>
<span id="cb5-76"><a href="#cb5-76" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/app_select.sh</span> firefox</span>
<span id="cb5-77"><a href="#cb5-77" aria-hidden="true" tabindex="-1"></a>        <span class="ex">firefox</span> <span class="at">--new-tab</span> <span class="st">&quot;http://www.google.com&quot;</span></span>
<span id="cb5-78"><a href="#cb5-78" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-79"><a href="#cb5-79" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;new_window&#39;</span><span class="kw">)</span></span>
<span id="cb5-80"><a href="#cb5-80" aria-hidden="true" tabindex="-1"></a>        <span class="ex">ratpoison</span> <span class="at">-c</span> <span class="st">&quot;nextscreen&quot;</span></span>
<span id="cb5-81"><a href="#cb5-81" aria-hidden="true" tabindex="-1"></a>        <span class="ex">firefox</span> <span class="at">--new-window</span> <span class="st">&quot;http://www.google.com&quot;</span></span>
<span id="cb5-82"><a href="#cb5-82" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-83"><a href="#cb5-83" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;clipboard_search&#39;</span><span class="kw">)</span></span>
<span id="cb5-84"><a href="#cb5-84" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/app_select.sh</span> firefox</span>
<span id="cb5-85"><a href="#cb5-85" aria-hidden="true" tabindex="-1"></a>        <span class="ex">clipboard_search</span></span>
<span id="cb5-86"><a href="#cb5-86" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-87"><a href="#cb5-87" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;search_lyrics&#39;</span><span class="kw">)</span></span>
<span id="cb5-88"><a href="#cb5-88" aria-hidden="true" tabindex="-1"></a>        <span class="ex">~/.scripts/ratpoison/app_select.sh</span> firefox</span>
<span id="cb5-89"><a href="#cb5-89" aria-hidden="true" tabindex="-1"></a>        <span class="ex">search_lyrics</span></span>
<span id="cb5-90"><a href="#cb5-90" aria-hidden="true" tabindex="-1"></a>        <span class="cf">;;</span></span>
<span id="cb5-91"><a href="#cb5-91" aria-hidden="true" tabindex="-1"></a><span class="cf">esac</span></span></code></pre></div>
<p>You can find all those scripts and configuration bits in my
<a href="https://github.com/alx741/dotfiles">Dotfiles</a>.</p>]]></summary>
</entry>

</feed>
