<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Elias Hernandis</title>
    <description>The latest articles on DEV Community by Elias Hernandis (@knifecake).</description>
    <link>https://dev.to/knifecake</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F16644%2F13c7b762-a973-4231-84e8-417321c6913c.jpeg</url>
      <title>DEV Community: Elias Hernandis</title>
      <link>https://dev.to/knifecake</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/knifecake"/>
    <language>en</language>
    <item>
      <title>Steady Queue: a Redis-less task backend for Django</title>
      <dc:creator>Elias Hernandis</dc:creator>
      <pubDate>Mon, 29 Dec 2025 08:41:00 +0000</pubDate>
      <link>https://dev.to/knifecake/steady-queue-a-redis-less-task-backend-for-django-4l6g</link>
      <guid>https://dev.to/knifecake/steady-queue-a-redis-less-task-backend-for-django-4l6g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a cross-post the &lt;a href="https://hernandis.me/2025/12/27/introducing-steady-queue.html" rel="noopener noreferrer"&gt;original article on my website&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A little more than a year ago I resumed using Ruby on Rails professionally after having been out of the ecosystem for several years. The last Rails version I used was Rails 4, and coming back to Rails 8 it was impressive to see how far things had come, especially in terms of the increasing number of tools included by default in the framework. While I was away from Rails, I mostly worked with Django in Python. Although Django is architecturally similar to Rails and also a joy to work with, it provides fewer tools out of the box.&lt;/p&gt;

&lt;p&gt;One of the tools that most web apps need is asynchronous task processing. Rails has had a standard interface for defining asynchronous tasks for a few versions already with ActiveJob, but it hadn't shipped with a default backend. Last year, &lt;a href="https://rosa.codes/" rel="noopener noreferrer"&gt;Rosa Gutierrez&lt;/a&gt; introduced &lt;a href="https://github.com/rails/solid_queue/" rel="noopener noreferrer"&gt;Solid Queue&lt;/a&gt;, which became the default job processing backend in Rails 8. Following the &lt;em&gt;omakase&lt;/em&gt;&lt;sup id="fnref1"&gt;1&lt;/sup&gt; Rails philosophy, it leverages &lt;code&gt;SELECT FOR UPDATE SKIP LOCKED&lt;/code&gt; to be able to use a relational database as the concurrency coordination mechanism, eliminating the need to deploy a separate Redis instance.&lt;/p&gt;

&lt;p&gt;Django also has excellent options&lt;sup id="fnref2"&gt;2&lt;/sup&gt; for async task processing, but, up until very recently, the framework didn't provide a standard interface for how tasks should be defined and the capabilities backends should have. This changed with the adoption of &lt;a href="https://github.com/django/deps/blob/main/accepted/0014-background-workers.rst#specification" rel="noopener noreferrer"&gt;DEP0014&lt;/a&gt; and its corresponding integration into Django 6.0 a few days ago. &lt;a href="https://theorangeone.net/posts/django-dot-tasks-exists/" rel="noopener noreferrer"&gt;Jake Howard&lt;/a&gt; was the main contributor to both the DEP and &lt;a href="https://github.com/realOrangeOne/django-tasks" rel="noopener noreferrer"&gt;django-tasks&lt;/a&gt;, the reference implementation. The database backend available in django-tasks uses the same core idea from Solid Queue: leveraging &lt;code&gt;SELECT FOR UPDATE SKIP LOCKED&lt;/code&gt; to use a database as the coordinator for concurrency.&lt;/p&gt;

&lt;p&gt;I had been wanting to dive deeper into the internals of Solid Queue for a while and having a task interface for Django on track to become part of the framework was the motivation I needed to attempt a port of Solid Queue to Django. Then, Steady Queue was born in mid-August 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick tour of Steady Queue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/knifecake/steady-queue" rel="noopener noreferrer"&gt;Steady Queue&lt;/a&gt; is a database-backed task backend for Django (&amp;gt;= 6.0). Beyond the features already offered by the django-tasks database backend, it also supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recurring tasks&lt;/strong&gt; (cron-like scheduling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency controls&lt;/strong&gt; (limiting how many instances of a task can run at a time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queue management&lt;/strong&gt; (pausing queues and ordering queues by priority)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database isolation&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;/strong&gt;,  &lt;strong&gt;enhanced task argument serialization&lt;/strong&gt; and a full &lt;strong&gt;Django admin interface&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing it (it has no dependencies), it can start processing tasks defined with the standard interface available in Django:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;

&lt;span class="nd"&gt;@task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queue_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;real_time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;welcome_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Welcome to Django!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Steady Queue extends the decorator-style interface to support limiting how many instances of a task can run at the same time and recurring tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;steady_queue.concurrency&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;limits_concurrency&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;steady_queue.recurring_task&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;recurring&lt;/span&gt;

&lt;span class="nd"&gt;@limits_concurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email rate limiting&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_daily_digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Your daily digest&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@recurring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;schedule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0 12 * * *&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;send daily digest at noon&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;daily_digest_at_noon&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
       &lt;span class="n"&gt;send_daily_digest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Configuration is entirely optional, but it supports running multiple workers (and dispatchers and schedulers, depending on your load), prioritizing queues and designating workers to only run tasks from specific queues. Since no Redis is required, all that's needed to start processing tasks is running in your development or production machines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py steady_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've been using Steady Queue in some production services with light load for a while now, and being able to ditch the Redis deployment was a joy. I'm very happy to take feedback and/or contributions from the community.&lt;/p&gt;

&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@meizhilang?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Meizhi Lang&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/a-group-of-people-standing-outside-a-building-R72P3yZyYJ8?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Also known as "batteries-included" in the Django world. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Big &lt;a href="https://huey.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Huey&lt;/a&gt; fan here! ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Using a separate database eliminates the possibility of accidentally relying on transactional integrity in tasks. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>django</category>
      <category>redis</category>
      <category>python</category>
    </item>
    <item>
      <title>Defining infinite structures in Haskell</title>
      <dc:creator>Elias Hernandis</dc:creator>
      <pubDate>Sun, 20 Oct 2019 21:29:30 +0000</pubDate>
      <link>https://dev.to/knifecake/defining-infinite-structures-in-haskell-3dml</link>
      <guid>https://dev.to/knifecake/defining-infinite-structures-in-haskell-3dml</guid>
      <description>&lt;p&gt;This article is part of a series on Haskell about how easy it is to define infinite structures in really concise ways. Building on the previous article about lazy evaluation, we explore how to define infinite structures using recursion without using a base case. While in other languages this would result in an infinite loop, this does not happen in Haskell due to its powerful lazy evaluation strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  First steps: an infinite list of ones
&lt;/h2&gt;

&lt;p&gt;Recall from the &lt;a href="https://dev.to/knifecake/lazy-evaluation-in-haskell-15of"&gt;previous post&lt;/a&gt; that in Haskell, parameters are evaluated only when they are needed. Let us revisit a simple example. Consider the following function definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling &lt;code&gt;f&lt;/code&gt; with parameters &lt;code&gt;a = 2 + 3&lt;/code&gt; and &lt;code&gt;b = 3 * 3&lt;/code&gt; would result in the following execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  f a b
= f (2 + 3) (3 * 3)
= (2 + 3) * 2
= 5 * 2
= 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the value of the parameter &lt;code&gt;b&lt;/code&gt; is never computed. More importantly, if the parameter &lt;code&gt;b&lt;/code&gt; did not contain a simple arithmetic expression, but rather some thing more complex, Haskell would not waste time computing its value.  Moreover, if the parameter &lt;code&gt;b&lt;/code&gt; was &lt;code&gt;undefined&lt;/code&gt;, i.e. if it could not be computed, the function call &lt;code&gt;f a b&lt;/code&gt; would not fail.&lt;/p&gt;

&lt;p&gt;Now consider the following definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;ones&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ones&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think would happen if we called &lt;code&gt;ones&lt;/code&gt;? Well, &lt;code&gt;ones&lt;/code&gt; is defined recursively, but it does not have a base case, so normally we would say that execution does not terminate, or that a maximum depth of recursion is reached and the program stops, or something along those lines. In Haskell, this is still true, calling &lt;code&gt;ones&lt;/code&gt; directly will result in the program never stopping.&lt;/p&gt;

&lt;p&gt;But, what if we called &lt;code&gt;take 3 ones&lt;/code&gt;. Remember that the function &lt;code&gt;take n xs&lt;/code&gt; returns the first &lt;code&gt;n&lt;/code&gt; elements of the list &lt;code&gt;xs&lt;/code&gt;. And indeed,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;ghci&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This not only doesn't fail, but returns the expected result. Let's look at the definition of take.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="kr"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;-- base case&lt;/span&gt;
&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="c1"&gt;-- recursive case&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let's look at how Haskell handles the call &lt;code&gt;take 3 ones&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;  &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- n = 3 dictates we go into the recursive case&lt;/span&gt;
  &lt;span class="c1"&gt;-- parameters are passed without being evaluated&lt;/span&gt;
&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- in the body of the recursive case,&lt;/span&gt;
  &lt;span class="c1"&gt;-- pattern matching assigns x = 1, xs = ones &lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- n = 2 dictates we go into the recursive case&lt;/span&gt;
  &lt;span class="c1"&gt;-- the same pattern matching assignments are made&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- n = 1 dictates we go into the recursive case&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- n = 0 dictates we go into the base case&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;ones&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- this time, the body of the base case does not depend on xs&lt;/span&gt;
  &lt;span class="c1"&gt;-- so it is not evaluated and the function returns&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;-- syntactic sugar&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Magic! As the expression &lt;code&gt;take 3 ones&lt;/code&gt; did not depend on the full, infinite, list of &lt;code&gt;ones&lt;/code&gt;, only the relevant part was evaluated and Haskell was able to correctly compute the expected result!&lt;/p&gt;

&lt;h2&gt;
  
  
  More interesting infinite definitions
&lt;/h2&gt;

&lt;p&gt;Base-case-less recursions need not be that simple. Assume we want to represent &lt;strong&gt;all of the natural numbers&lt;/strong&gt; in Haskell. We could easily do so with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;nats&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;nats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;nats&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And indeed,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ghci&amp;gt; take 10 nats
[0,1,2,3,4,5,6,7,8,9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Exercise: try to expand the call stack for &lt;code&gt;take 2 nats&lt;/code&gt; as we did before)&lt;/p&gt;

&lt;p&gt;This is a common enough case that Haskell has special syntax&lt;sup id="fnref1"&gt;1&lt;/sup&gt; for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;nats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;-- and we can even start later&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The sieve of Erathostenes
&lt;/h2&gt;

&lt;p&gt;Erathosthenes was a Greek mathematician who gave an algorithm to find all prime numbers up to a limit. The algorithm is similar to trial division, only it is constructive (i.e. instead of testing wether a number is prime, it finds all prime numbers up to a limit). Lets look at the pseudocode&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;List all numbers starting with &lt;code&gt;2&lt;/code&gt; until &lt;code&gt;n&lt;/code&gt;, where &lt;code&gt;n&lt;/code&gt; is the upper bound in our search for primes. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take the first element &lt;code&gt;p&lt;/code&gt; in the list and remove all multiples of $p$ from the list, i.e. remove &lt;code&gt;2p, 3p, 4p, ...&lt;/code&gt; from the list. Another way to think of this is, remove a number &lt;code&gt;x&lt;/code&gt; if &lt;code&gt;mod x p == 0&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go back to the previous step starting with the first remaining number.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This algorithm may be used without an upper bound if one wishes to find &lt;strong&gt;all&lt;/strong&gt; of the prime numbers. In most languages this would not be possible but it is in Haskell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- List all numbers starting with 2, until infinity&lt;/span&gt;
&lt;span class="n"&gt;primes&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;primes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;-- take the first number p in the list&lt;/span&gt;
&lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="c1"&gt;-- remove all multiples of p from the list&lt;/span&gt;
&lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;-- Done! (the definition above is recursive)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And indeed,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ghci&amp;gt; take 4 primes
[2,3,5,7]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lazy evaluation is a powerful evaluation strategy that allows us to concisely and expressively write definitions of infinite structures. In future posts, we will explore other consequences of this design decision of the Haskell language and some situations in which it does not prove so useful.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;You might have seen the syntax &lt;code&gt;[a..b]&lt;/code&gt; before. It is a shorthand for the function &lt;code&gt;enumFromTo&lt;/code&gt; defined in &lt;a href="https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1310006.3.4" rel="noopener noreferrer"&gt;the enum class&lt;/a&gt;. In fact, &lt;code&gt;[a..]&lt;/code&gt; is also a shorthand for the method &lt;code&gt;enumFrom&lt;/code&gt;. Integers in Haskell are an instance of the &lt;code&gt;Enum&lt;/code&gt; class that defines these methods. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>haskell</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Lazy evaluation in Haskell</title>
      <dc:creator>Elias Hernandis</dc:creator>
      <pubDate>Thu, 17 Oct 2019 21:21:19 +0000</pubDate>
      <link>https://dev.to/knifecake/lazy-evaluation-in-haskell-15of</link>
      <guid>https://dev.to/knifecake/lazy-evaluation-in-haskell-15of</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover image by &lt;a href="https://www.flickr.com/photos/andreaskay/" rel="noopener noreferrer"&gt;Andreas Kay&lt;/a&gt; licensed under CC BY-NC-SA 2.0.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A version of this article previously appeared &lt;a href="https://hernandis.me/2019/10/17/haskell-lazy-evaluation.html" rel="noopener noreferrer"&gt;in my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This article is part of a series on Haskell about how easy it is to define infinite structures in really concise ways. Lazy evaluation is an evaluation strategy that is the foundation of many features of haskell, from performance to expressiveness. In this first article, we explore different evaluation strategies found in other languages, how they compare to Haskell's and their benefits and drawbacks. No Haskell knowledge is required for this first post :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Call me by your value
&lt;/h2&gt;

&lt;p&gt;When discussing different families of programming languages, we sometimes use the phrases &lt;em&gt;call-by-value&lt;/em&gt; to refer to how parameters are passed to a function when it is called. Consider the following code in a generic language&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def f(a, b):
  return a * 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we say the language is &lt;em&gt;call-by-value&lt;/em&gt; we mean that the variables &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are evaluated before copies of them are passed to the function &lt;code&gt;f&lt;/code&gt;. For instance, if we called &lt;code&gt;f&lt;/code&gt; with arguments &lt;code&gt;a = 2 + 3&lt;/code&gt; and &lt;code&gt;b = 3 * 3&lt;/code&gt; the following would happen in a &lt;em&gt;call-by-value&lt;/em&gt; language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  f(a, b)
= f((2 + 3), (3 * 3))
= f(5, (3 * 3))
= f(5, 9)
= 5 * 2
= 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes roughly 5 steps to compute the value &lt;code&gt;f(a, b)&lt;/code&gt;. Observe that even though the value of &lt;code&gt;f&lt;/code&gt; is only dependent on the value of &lt;code&gt;a&lt;/code&gt;, the parameter &lt;code&gt;b&lt;/code&gt; is still evaluated. We call this evaluation strategy &lt;em&gt;strict&lt;/em&gt;, because it does not care about the usefulness of the values, it just computes everything as a very stubborn robot would do. This is the case with some low-level languages&lt;br&gt;
like &lt;code&gt;C&lt;/code&gt;.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Call me by your name
&lt;/h2&gt;

&lt;p&gt;What if we delayed evaluation until the parameters were actually needed? We call this &lt;em&gt;call-by-name&lt;/em&gt; and it is an example of a &lt;em&gt;non-strict&lt;/em&gt; evaluation strategy. Let's look at how the previous computation would look like with a call-by-name approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  f(a, b)
= f((2 + 3), (3 * 3))
= (2 + 3) * 2
= 5 * 2
= 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow! We saved one step! This is not too much but suppose that &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; weren't simple arithmetic expressions but complex computations instead. Then not computing &lt;code&gt;b&lt;/code&gt; would certainly be beneficial. Is this always the case? Unfortunately, it turns out, it isn't. Look at the following definition and compare the two evaluations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def square(a):
  return a * a

-- Call-by-value (strict) evaluation
  square(a)
= square((2 + 3))
= square(5)
= 5 * 5
= 25

-- Call-by-name (non-strict) evaluation
  square(a)
= square((2 + 3))
= (2 + 3) * (2 + 3)
= 5 * (2 + 3)
= 5 * 5
= 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yikes! That's one more step. Now a natural question is, which evaluation strategy makes more sense? Call-by-name seems better since unused values are not computed... Also, why did we calculate &lt;code&gt;(2 + 3)&lt;/code&gt; twice? Couldn't we have stored the value for the second calculation?&lt;/p&gt;

&lt;h2&gt;
  
  
  Call me lazy
&lt;/h2&gt;

&lt;p&gt;Turns out if we add &lt;em&gt;sharing&lt;/em&gt; to call-by-name, this strategy will never take more steps to evaluate an expression than call-by-value. We call this &lt;em&gt;call-by-need&lt;/em&gt; or &lt;em&gt;lazy evaluation&lt;/em&gt; in the context of Haskell. Call-by-need is also a form of non-strict evaluation but has this added benefit of never introducing a performance penalty (well, at least in the number of steps&lt;sup id="fnref2"&gt;2&lt;/sup&gt;).&lt;/p&gt;

&lt;p&gt;Let's look at how the previous examples would look like if we used call-by-need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  f(a)
= f((2 + 3))
= (2 + 3) * 2
= 5 * 2
= 10

  square(a)
= square((2 + 3))
= (2 + 3) * (2 + 3)
= 5 * 5
= 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that in both cases the evaluation takes fewer steps than call-by-name or call-by-value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing words
&lt;/h2&gt;

&lt;p&gt;Call-by-need or lazy evaluation is central to both the performance and expressiveness of the Haskell language. In addition, the Haskell compiler has pureness and a strong type system at its disposal, enabling it to make much more aggressive optimisations than would be possible in other languages. More simply, expressiveness in Haskell does not come with a performance price to pay.&lt;/p&gt;

&lt;p&gt;In the following articles we will apply lazy evaluation to create infinite structures.&lt;/p&gt;

&lt;p&gt;If you want to read more about evaluation strategies, you can check out &lt;a href="https://en.wikipedia.org/wiki/Evaluation_strategy" rel="noopener noreferrer"&gt;this wikipedia article&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Although in some languages we may substitute &lt;em&gt;call-by-name&lt;/em&gt; with &lt;em&gt;call-by-reference&lt;/em&gt;, the idea of strict evaluation still applies — &lt;strong&gt;all parameters are evaluated before the function call&lt;/strong&gt; — only in call-by-reference the address of the value is passed instead of a copy of the value itself, allowing the function to modify it. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;It may, however, introduce a memory usage penalty, but these cases are more rare and easier to detect and fix just by rewriting the order of arguments. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>haskell</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
