<?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: Rickard Andersson</title>
    <description>The latest articles on DEV Community by Rickard Andersson (@gonzooo).</description>
    <link>https://dev.to/gonzooo</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%2F120081%2F71973e63-8923-4b58-a2b5-b526ded598ed.jpeg</url>
      <title>DEV Community: Rickard Andersson</title>
      <link>https://dev.to/gonzooo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gonzooo"/>
    <language>en</language>
    <item>
      <title>You don't need the community</title>
      <dc:creator>Rickard Andersson</dc:creator>
      <pubDate>Mon, 29 May 2023 10:58:13 +0000</pubDate>
      <link>https://dev.to/gonzooo/you-dont-need-the-community-566a</link>
      <guid>https://dev.to/gonzooo/you-dont-need-the-community-566a</guid>
      <description>&lt;p&gt;If you're relatively new to software development and tend to keep up with developments in different areas of it you are probably convinced that community is important. I think you're probably overestimating the value of community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are we here?
&lt;/h2&gt;

&lt;p&gt;How did we end up with this view that a good language has a massive community and that it derives its value from this community?&lt;/p&gt;

&lt;p&gt;Simple: Visibility.&lt;/p&gt;

&lt;p&gt;A community that hosts conferences, has user groups, has thousands upon thousands of libraries readily available is &lt;strong&gt;visible&lt;/strong&gt;. We can observe the mighty power of this language and technology and since these are some of the easiest things to observe we tend to associate this with high quality that is trending upwards. The community is sure to produce more libraries for us that we can use to build more things faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can't we observe as easily?
&lt;/h2&gt;

&lt;p&gt;We can't actually observe how many of these libraries are thrown away after a month because they have massive bugs, take forever to compile or are otherwise not good enough to use in our code bases.&lt;/p&gt;

&lt;p&gt;We can't actually observe how many programmers hate coming in to work because the popular language they use has massive holes and is super easy to accidentally misuse. Likewise we can't observe how many &lt;strong&gt;other&lt;/strong&gt; offerings the users of a technology have been exposed to, so we don't know whether their frame of reference even holds any reasonable alternatives. We have extremely imprecise proxies for some of these things but they aren't good enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  What am I suggesting?
&lt;/h2&gt;

&lt;p&gt;Recently there has been a series of controversies around the Rust language and its governance. I'm here to tell you that even before this you should've been unconcerned with most other people. The community doesn't matter; only you and your usage of the technology matters.&lt;/p&gt;

&lt;p&gt;Learn your fundamentals, learn lower-level programming and how to express those things in Rust and engage minimally with everyone else. Perhaps engage with &lt;strong&gt;a&lt;/strong&gt; community but not with &lt;strong&gt;the&lt;/strong&gt; community. Staying on this path will help your objectivity as you will not add libraries to your projects "because everyone else uses this serialization library that adds 20 seconds to their compile time", you won't tolerate bad things just because it's the status quo of the community.&lt;/p&gt;

&lt;p&gt;In short, you'll learn to think for yourself and evaluate both language features and libraries based on their actual merit and usefulness &lt;strong&gt;to you&lt;/strong&gt;, not anyone else. When you need something, you'll be more prepared to build it unless you can easily find an alternative that &lt;strong&gt;actually&lt;/strong&gt; works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Knock-on effects
&lt;/h2&gt;

&lt;p&gt;One of the best things about detaching yourself and your engagement from a community is that you free yourself up to simply do other things. Time spent engaging with the community can be spent doing actually productive things, spent researching &lt;a href="https://odin-lang.org/"&gt;alternatives&lt;/a&gt; that have unique upsides you didn't see before because you were so entrenched in this one technology and its community.&lt;/p&gt;

&lt;p&gt;You can do all of these things without having to engage in spectacles like "Why I'm leaving X" posts, because you're not &lt;strong&gt;leaving&lt;/strong&gt; anything. You're just &lt;strong&gt;also&lt;/strong&gt; using other tools. You are a programmer, a software developer, you're not tied to any one language or technology.&lt;/p&gt;

&lt;p&gt;Hopefully when you've disconnected from any one language and community you'll also be ready to learn things that simply aren't about languages, but rather an application of ideas such as network programming, 3D rendering, game engine design, etc.&lt;/p&gt;

</description>
      <category>software</category>
      <category>development</category>
      <category>programming</category>
      <category>rust</category>
    </item>
    <item>
      <title>purerl - Integrating PureScript into Elixir projects</title>
      <dc:creator>Rickard Andersson</dc:creator>
      <pubDate>Wed, 11 Jan 2023 09:35:41 +0000</pubDate>
      <link>https://dev.to/quanterall/purerl-integrating-purescript-into-elixir-projects-3n8c</link>
      <guid>https://dev.to/quanterall/purerl-integrating-purescript-into-elixir-projects-3n8c</guid>
      <description>&lt;h2&gt;
  
  
  What is PureScript?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.purescript.org" rel="noopener noreferrer"&gt;PureScript&lt;/a&gt; is a Haskell-like language aimed at providing an alternative to TypeScript for statically typed programming in the JavaScript space. I highly recommend taking a look at PureScript for your compile-to-JavaScript needs outside of the use case we'll be talking about in this post.&lt;/p&gt;

&lt;p&gt;PureScript is most easily &lt;a href="https://www.youtube.com/watch?v=JTEfpNtEoSA" rel="noopener noreferrer"&gt;compared to TypeScript&lt;/a&gt; where it could be summed up as having many of the defaults you'd want in most TypeScript projects anyway, then layered with effects being noted in the types of functions on top.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://www.erlang.org/" rel="noopener noreferrer"&gt;Erlang&lt;/a&gt; is a language developed from the 80's onwards for the purposes of writing highly concurrent software. The primary purpose from the beginning was telephony systems where fault tolerance, concurrency and failure isolation were important concepts. These happen to be very important concepts in essentially all networked services nowadays.&lt;/p&gt;

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

&lt;p&gt;Elixir is a collection of libraries, a syntax and a slim set of language features that enable a somewhat nicer workflow over Erlang. The libraries come into play when we want to use already created functionality in our PureScript code, as it might not be available in Erlang.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;purerl&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/purerl/purerl" rel="noopener noreferrer"&gt;&lt;code&gt;purerl&lt;/code&gt; is a compiler&lt;/a&gt; for turning &lt;a href="https://www.purescript.org/" rel="noopener noreferrer"&gt;PureScript&lt;/a&gt; code into Erlang code, so that you're able to write BEAM (the Erlang virtual machine) applications using it.&lt;/p&gt;

&lt;p&gt;This enables us to use it together with both Elixir and Erlang, which in a beautiful symbiosis extends the power of all three languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our project setup
&lt;/h2&gt;

&lt;p&gt;We'll start with an Elixir application that we'll add automatic compilation of &lt;code&gt;*.purs&lt;/code&gt; files to, which will provide the perfect basis for getting things up and running quickly, easily and with a robust foundation to build on.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;mix&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In this particular example we'll use &lt;code&gt;mix new&lt;/code&gt;, but &lt;code&gt;mix phx.new&lt;/code&gt; will work exactly the same way and it's likely that any other &lt;code&gt;new&lt;/code&gt; template would work as well. We're using &lt;code&gt;mix&lt;/code&gt; because it's the standard tool for managing Elixir projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mix new purerl_up_and_running
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When our project has been created we want to make sure that the versions we have of everything are clearly described. For this purpose we'll use &lt;a href="https://asdf-vm.com/" rel="noopener noreferrer"&gt;&lt;code&gt;asdf&lt;/code&gt;&lt;/a&gt;, a general version management tool we can use for all the tools we'll need in this project.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;asdf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add erlang &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;erlang 25.1.2 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;erlang 25.1.2
...
&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add elixir &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;elixir 1.14.2-otp-25 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;elixir 1.14.2-otp-25
...
&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add purescript &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;purescript 0.15.3 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;purescript 0.15.3
...
&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add spago &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;spago 0.20.9 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;spago 0.20.9
...
&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add purerl &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;purerl 0.0.17 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;purerl 0.0.17
...
&lt;span class="nv"&gt;$ &lt;/span&gt;asdf plugin add rebar &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;install &lt;/span&gt;rebar 3.20.0 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; asdf &lt;span class="nb"&gt;local &lt;/span&gt;rebar 3.20.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The process for each tool here is to install the &lt;code&gt;asdf&lt;/code&gt; plugin, a version of the tool and then set that version as the locally used one for our project. This ensures that other contributors can use the correct versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  PureScript bits via &lt;code&gt;spago&lt;/code&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Initial setup
&lt;/h4&gt;

&lt;p&gt;First we run &lt;code&gt;spago init&lt;/code&gt; in our project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;spago init
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets up our project to have basic PureScript files. The source directory for PureScript is &lt;code&gt;src&lt;/code&gt;, so out of the box we are able to keep it separate from our Elixir code, which lives in &lt;code&gt;lib&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Minor changes to our project files
&lt;/h4&gt;

&lt;p&gt;We'll have to modify our &lt;code&gt;spago.dhall&lt;/code&gt; and &lt;code&gt;packages.dhall&lt;/code&gt; files just a bit in order for our project to point to the correct &lt;code&gt;purerl&lt;/code&gt; things:&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;packages.dhall&lt;/code&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/packages.dhall b/packages.dhall
index e13009d..28bcb0c 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/packages.dhall
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/packages.dhall
&lt;/span&gt;&lt;span class="p"&gt;@@ -99,7 +99,6 @@&lt;/span&gt; in  upstream
 -------------------------------
 -}
 let upstream =
&lt;span class="gd"&gt;-      https://github.com/purescript/package-sets/releases/download/psc-0.15.3-20220712/packages.dhall
-        sha256:ffc496e19c93f211b990f52e63e8c16f31273d4369dbae37c7cf6ea852d4442f
&lt;/span&gt;&lt;span class="gi"&gt;+      https://github.com/purerl/package-sets/releases/download/erl-0.15.3-20220629/packages.dhall
&lt;/span&gt; in  upstream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The change we're making here is that we are pointing the package set, the set of packages known to work together for this PureScript compiler version, to the &lt;code&gt;purerl&lt;/code&gt; package set, i.e. a package set that uses Erlang code as the implementation language.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;spago.dhall&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;The definition of our PureScript side of the project is done in &lt;code&gt;spago.dhall&lt;/code&gt; and we'll add just one minor bit here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/spago.dhall b/spago.dhall
index 41a8576..a9b223a 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/spago.dhall
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/spago.dhall
&lt;/span&gt;&lt;span class="p"&gt;@@ -14,4 +14,5 @@&lt;/span&gt; to generate this file without the comments in this block.
 , dependencies = [ "console", "effect", "prelude" ]
 , packages = ./packages.dhall
 , sources = [ "src/**/*.purs", "test/**/*.purs" ]
&lt;span class="gi"&gt;+, backend = "purerl"
&lt;/span&gt; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The change above tells PureScript that we want to use a special compiler backend, i.e. &lt;code&gt;purerl&lt;/code&gt;, in order to compile our PureScript code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Elixir code needs to understand our project
&lt;/h3&gt;

&lt;p&gt;In order to compile our PureScript code we'll rely on Elixir managing the compilation process as part of its normal compilation, via &lt;code&gt;mix&lt;/code&gt; compilers.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;mix.exs&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/mix.exs b/mix.exs
index 6ba9745..657162c 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/mix.exs
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/mix.exs
&lt;/span&gt;&lt;span class="p"&gt;@@ -7,7 +7,9 @@&lt;/span&gt; defmodule PurerlUpAndRunning.MixProject do
       version: "0.1.0",
       elixir: "~&amp;gt; 1.14",
       start_permanent: Mix.env() == :prod,
&lt;span class="gd"&gt;-      deps: deps()
&lt;/span&gt;&lt;span class="gi"&gt;+      deps: deps(),
+      compilers: [:purerl] ++ Mix.compilers(),
+      erlc_paths: ["output"]
&lt;/span&gt;     ]
   end
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -21,6 +23,7 @@&lt;/span&gt; defmodule PurerlUpAndRunning.MixProject do
   # Run "mix help deps" to learn about dependencies.
   defp deps do
     [
&lt;span class="gi"&gt;+      {:purerlex, "~&amp;gt; 0.4.2"}
&lt;/span&gt;       # {:dep_from_hexpm, "~&amp;gt; 0.3.0"},
       # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
     ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package we are using is called &lt;a href="https://hex.pm/packages/purerlex" rel="noopener noreferrer"&gt;&lt;code&gt;purerlex&lt;/code&gt;&lt;/a&gt; and works out of the box as long as we also add that Erlang source files can be found in the &lt;code&gt;output&lt;/code&gt; folder. We need to run &lt;code&gt;mix deps.get&lt;/code&gt; in our project folder to get this dependency as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding PureScript code
&lt;/h2&gt;

&lt;p&gt;We are now ready to add PureScript code that can be executed on the BEAM. We'll try this functionality out in &lt;code&gt;iex&lt;/code&gt;, the interactive Elixir session that we can use to evaluate expressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;OurModule.purs&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let's add a file in &lt;code&gt;src/OurModule.purs&lt;/code&gt; containing the following:&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="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;OurModule&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;iex&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Let's run &lt;code&gt;iex -S mix&lt;/code&gt; in the project folder and execute the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:ourModule&lt;/span&gt;&lt;span class="nv"&gt;@ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="s2"&gt;"Hello!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note here that our module name is being translated in a particular way. First of all it's converted into camel-case from the PascalCase standard that PureScript modules use. On top of that modules are also compiled with a &lt;code&gt;@ps&lt;/code&gt; suffix that is very close to the &lt;code&gt;Elixir.&lt;/code&gt; prefix that Elixir modules are compiled with, to distinguish the modules from modules generated with other languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;p&gt;We're now able to compile and run PureScript code so that we can use it in the rest of our Elixir code. This means we can write entire subsystems in PureScript instead and start them in our application supervisor, meaning they are started from the root of our application. If we have a subsystem that is best expressed in a statically typed language this is now something we can cover as a use case.&lt;/p&gt;

&lt;p&gt;In the next article we'll go over how to write one of these subsystems so that we can take advantage of this newfound ability to compile and run PureScript code in our project.&lt;/p&gt;

</description>
      <category>purescript</category>
      <category>beam</category>
      <category>elixir</category>
      <category>erlang</category>
    </item>
    <item>
      <title>ERTS &amp; OTP - The Erlang Runtime System and core library</title>
      <dc:creator>Rickard Andersson</dc:creator>
      <pubDate>Sun, 18 Dec 2022 17:06:48 +0000</pubDate>
      <link>https://dev.to/quanterall/erts-otp-the-erlang-runtime-system-and-core-library-4b3g</link>
      <guid>https://dev.to/quanterall/erts-otp-the-erlang-runtime-system-and-core-library-4b3g</guid>
      <description>&lt;p&gt;Since I will be writing posts about how to do things on the BEAM with different languages I thought it might be prudent to create a short intro to the systems that power the programs we write.&lt;/p&gt;

&lt;p&gt;If you prefer to look at things yourself, the code that will be referenced later is available &lt;a href="https://github.com/GoNZooo/beam_intro" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  BEAM
&lt;/h2&gt;

&lt;p&gt;The name "BEAM" comes originally from Bogdan's/Björn's Erlang Abstract Machine, named after the first and subsequent implementer &amp;amp; maintainer of the virtual machine. There were previous, distinct versions of this concept before, notably JAM (Joe's Abstract Machine), created by &lt;a href="https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)" rel="noopener noreferrer"&gt;Joe Armstrong&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;BEAM is a bytecode interpreter, meaning it takes a well-defined, high-level description of logic and executes that on whatever platform we are running on, as opposed to compiling to native code immediately. This is often implicit in the phrase "virtual machine". You can imagine this as a adapter machine running on top of the one actually executing things.&lt;/p&gt;

&lt;p&gt;We won't go over the internals of the BEAM in this article, but rather focus on the capabilities offered by the Erlang Runtime System. If you're interested in how the BEAM works, &lt;a href="https://blog.stenmans.org/theBeamBook/" rel="noopener noreferrer"&gt;this book by Erik Stenman is a great place to start&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Erlang Runtime System
&lt;/h2&gt;

&lt;p&gt;The Erlang Runtime System is the software that runs your code on top of the BEAM. Since the BEAM is just a bytecode interpreter, any logic that needs to manage the scheduling and de-scheduling of code on top of that needs to have a system taking care of it. That is exactly what ERTS is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lightweight processes
&lt;/h3&gt;

&lt;p&gt;Processes are threads managed by ERTS and all code that runs on it is executed in these processes.&lt;/p&gt;

&lt;p&gt;Processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take up very little heap space by default; about 1232 bytes&lt;/li&gt;
&lt;li&gt;Have message queues (the primary way to interact with them is messages)&lt;/li&gt;
&lt;li&gt;Don't really use any processing power unless they have waiting messages (see below)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Preemptive scheduling
&lt;/h3&gt;

&lt;p&gt;ERTS has a scheduler that decides which processes are allowed to do work at the moment. It does so via a list of &lt;strong&gt;ready&lt;/strong&gt; and &lt;strong&gt;waiting&lt;/strong&gt; processes. A process is put in a ready state if it has a message in its message queue, and put in the waiting state if it asks for incoming messages again, or consumes too many resources while processing a message.&lt;/p&gt;

&lt;p&gt;This last part is distinct from most models of concurrency and parallelism; we do not usually have a limit on how much we can do in a thread before it gets de-scheduled. ERTS has an internal concept of &lt;strong&gt;reductions&lt;/strong&gt;. A process has a set amount of reductions it can consume/do before the scheduler determines that it has to let other processes run. You can view this concept as having a set amount of fuel to consume before you have to make a pit stop.&lt;/p&gt;

&lt;p&gt;The above concept means that threads are scheduled &lt;strong&gt;fairly&lt;/strong&gt; and without any user intervention on the BEAM. We don't ever have to "yield" a thread, it's a concept managed entirely by the runtime itself. The absence of preemptive scheduling can be seen in languages where starting a thread can completely shut off a core from doing anything else while it's running, because we are locking that core up entirely until we are done, or until we yield.&lt;/p&gt;

&lt;p&gt;Because we don't use a lot of memory for each process and that a process doesn't use any processing power unless it has incoming messages it is very common to start very high numbers of them if we need to do so. We can be confident that they are managed as they should be by the runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  OTP
&lt;/h2&gt;

&lt;p&gt;We've learned that code running in the BEAM is intrinsically tied to the concept of processes and that the way we do things with processes is by way of messages; pieces of data that a process can react and reply to. So how do we deal with processes from a code perspective?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OTP&lt;/strong&gt;, the Open Telecom Platform, is a library for starting, managing, communicating with and stopping processes. We'll go over some of the most commonly used components of this library to give a sense of what it means to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;gen_server&lt;/code&gt; / &lt;code&gt;GenServer&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;As the name suggests, &lt;code&gt;gen_server&lt;/code&gt; is for generic servers. You can view a server here as something that accepts and potentially responds to messages and manages an internal state.&lt;/p&gt;

&lt;p&gt;As an example of a server, let's look at how a very simple server for storing a list of things and getting the current list might look:&lt;/p&gt;

&lt;p&gt;
  gen_server (Erlang)
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beam_intro_lister&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;export&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add&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="nb"&gt;get&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="n"&gt;handle_call&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle_info&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;behaviour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;% We specify how to start the process. In this case we don't use the
&lt;/span&gt;  &lt;span class="c"&gt;% arguments coming in at all, and pass down only the symbol `ok` to
&lt;/span&gt;  &lt;span class="c"&gt;% our `init` function, which is used for determining the initial
&lt;/span&gt;  &lt;span class="c"&gt;% state of the process.
&lt;/span&gt;  &lt;span class="nn"&gt;gen_server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nv"&gt;MODULE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;

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

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

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(_&lt;/span&gt;&lt;span class="nv"&gt;Args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;% The initial state of the process is a map where the key `contents`
&lt;/span&gt;  &lt;span class="c"&gt;% is associated with an empty list.
&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]}}.&lt;/span&gt;

&lt;span class="c"&gt;% We use pattern matching here to pull out the `contents` value so we
% can use it in our logic. When a thing is added, we prepend it to our
% internal list of things.
&lt;/span&gt;&lt;span class="nf"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Thing&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;OldContents&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;noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Thing&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;OldContents&lt;/span&gt;&lt;span class="p"&gt;]}}.&lt;/span&gt;

&lt;span class="c"&gt;% When someone requests the contents of our process, we reply to their
% call with the `contents` value in our state.
&lt;/span&gt;&lt;span class="nf"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt;&lt;span class="nv"&gt;From&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Contents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;

&lt;span class="nf"&gt;handle_info&lt;/span&gt;&lt;span class="p"&gt;(_&lt;/span&gt;&lt;span class="nv"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;State&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;

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

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  GenServer (Elixir)
  &lt;br&gt;

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

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# We specify how to start the process. In this case we don't use&lt;/span&gt;
    &lt;span class="c1"&gt;# the arguments coming in at all, and pass down only the symbol&lt;/span&gt;
    &lt;span class="c1"&gt;# `ok` to our `init` function, which is used for determining the&lt;/span&gt;
    &lt;span class="c1"&gt;# initial state of the process.&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# The initial state of the process is a map where the key&lt;/span&gt;
    &lt;span class="c1"&gt;# `contents` is associated with an empty list.&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;contents:&lt;/span&gt; &lt;span class="p"&gt;[]}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# We use pattern matching here to pull out the `contents` value&lt;/span&gt;
  &lt;span class="c1"&gt;# so we can use it in our logic. When a thing is added, we prepend&lt;/span&gt;
  &lt;span class="c1"&gt;# it to our internal list of things.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;contents:&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;contents:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;]}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# When someone requests the contents of our process, we reply to&lt;/span&gt;
  &lt;span class="c1"&gt;# their call with the `contents` value in our state.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;contents:&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gen_server&lt;/code&gt; follows a fairly simple request/response model and if we can answer some key questions we can construct one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;start_link&lt;/code&gt; &amp;amp; &lt;code&gt;init&lt;/code&gt;: How is the server started and what does that mean for the initial state?&lt;/li&gt;
&lt;li&gt;Interface functions: Which messages do we want to send when other processes interact with the server?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;handle_call&lt;/code&gt;, &lt;code&gt;handle_cast&lt;/code&gt; &amp;amp; &lt;code&gt;handle_info&lt;/code&gt;: When those messages come in, how does our internal state change and what do we reply with?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these key questions answered we can cover a surprisingly large area in the design space of a system.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;supervisor&lt;/code&gt; / &lt;code&gt;Supervisor&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Supervisors are processes that manage the starting, restarting and stopping of other processes.&lt;/p&gt;

&lt;p&gt;
  supervisor (Erlang)
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beam_intro_lister_supervisor&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;export&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;supervisor&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

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

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;Flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c"&gt;% We specify here that the supervisor restarts a single process when it
&lt;/span&gt;      &lt;span class="c"&gt;% dies, not all the processes attached to the supervisor.
&lt;/span&gt;      &lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c"&gt;% If 3 children die in 5 seconds, the supervisor will terminate. If this
&lt;/span&gt;      &lt;span class="c"&gt;% supervisor is a child of another supervisor, the parent supervisor will
&lt;/span&gt;      &lt;span class="c"&gt;% react to that termination as specified.
&lt;/span&gt;      &lt;span class="n"&gt;intensity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;period&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c"&gt;% This describes how our child process is started.
&lt;/span&gt;  &lt;span class="nv"&gt;ListerSpec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;beam_intro_lister&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;start&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;beam_intro_lister&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
      &lt;span class="n"&gt;restart&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;permanent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;shutdown&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ListerSpec&lt;/span&gt;&lt;span class="p"&gt;]}}.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;
  Supervisor (Elixir)
  &lt;br&gt;

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

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;BeamIntro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Lister&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;# We specify here that the supervisor restarts a single process&lt;/span&gt;
      &lt;span class="c1"&gt;# when it dies, not all the processes attached to the supervisor.&lt;/span&gt;
      &lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;# If 3 children die in 5 seconds, the supervisor will terminate.&lt;/span&gt;
      &lt;span class="c1"&gt;# If this supervisor is a child of another supervisor, the parent&lt;/span&gt;
      &lt;span class="c1"&gt;# supervisor will react to that termination as specified.&lt;/span&gt;
      &lt;span class="ss"&gt;max_restarts:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;max_seconds:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Supervisors allow us to talk about how a process is started, under which circumstances it should be restarted as well as how many failures we can tolerate before we need to restart the entire supervisor.&lt;/p&gt;

&lt;p&gt;Supervisors come with a simple but featureful set of configuration options that we can use to design our system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Restart strategies: Should we restart only the process that has failed, or should we restart all the supervisor's children, or perhaps all the ones that come after the failed one in our child list?&lt;/li&gt;
&lt;li&gt;How many process failures in how much time do we tolerate before we restart the entire supervisor and all its children?&lt;/li&gt;
&lt;li&gt;Which processes are important to always have up even though they may have shut down normally? Are some processes fine to not restart if they shut down normally, but should be restarted if they crashed?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Answering the above questions is key to understanding what role a supervisor and its children have in a system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supervision trees
&lt;/h3&gt;

&lt;p&gt;Supervision trees are an emergent property of the above questions. Because we can have supervisors as children of other supervisors, this means we can segment our systems up in sub-systems that might be important to keep together.&lt;/p&gt;

&lt;p&gt;If one sub-system depends on another, we might for example say that our restart strategy is &lt;code&gt;rest_for_one&lt;/code&gt; (restart all subsequent children when one fails) and have them be part of the same supervision tree. This allows us to guarantee that the dependent one is always started after the one it depends on.&lt;/p&gt;

&lt;p&gt;If you take the time to look, you'll find that most BEAM applications are actually started by a root supervisor process usually called some variant of &lt;code&gt;application&lt;/code&gt;/&lt;code&gt;Application&lt;/code&gt;. This means that even the most minimal system will tend towards some level of supervision tree structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seeing the forest and not just the trees
&lt;/h2&gt;

&lt;p&gt;What these things and more boil down to is that on the BEAM we are able to use high-level specifications and libraries to talk about the most interesting parts of a system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which parts go together?&lt;/li&gt;
&lt;li&gt;How do the parts communicate change and effect?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being allowed to take on this high-level view is very liberating and is why I personally feel that the BEAM &amp;amp; ERTS is a great place to be as a creator and maintainer of systems.&lt;/p&gt;

</description>
      <category>erts</category>
      <category>beam</category>
      <category>erlang</category>
      <category>elixir</category>
    </item>
    <item>
      <title>API constraints a'la carte in Haskell &amp; PureScript</title>
      <dc:creator>Rickard Andersson</dc:creator>
      <pubDate>Wed, 08 May 2019 21:41:31 +0000</pubDate>
      <link>https://dev.to/gonzooo/api-constraints-a-la-carte-in-haskell-purescript-3aba</link>
      <guid>https://dev.to/gonzooo/api-constraints-a-la-carte-in-haskell-purescript-3aba</guid>
      <description>&lt;p&gt;The example in this post is 100% compatible in PureScript as well, with the exception of the effect monad which is called &lt;code&gt;Effect&lt;/code&gt; in PureScript. Replacing &lt;code&gt;IO&lt;/code&gt; with &lt;code&gt;Effect&lt;/code&gt; is all you have to do, as well as use the libraries available there.&lt;/p&gt;

&lt;p&gt;I think everyone who's in and around Haskell &amp;amp; PureScript hear some variant of  "Every program you make always ends up having a bunch of &lt;code&gt;IO ()&lt;/code&gt; in it all the time anyway." and they're not necessarily wrong. The complaint is that you have this neat type system that should constrain your effects but all you get is &lt;code&gt;IO&lt;/code&gt; or &lt;code&gt;Effect&lt;/code&gt;, which just plain permits everything.&lt;/p&gt;

&lt;p&gt;It's not untrue, but it's not exactly the full story either. Consider the following function:&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;downloadFile'&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Link&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="kt"&gt;ByteString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;downloadFile'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Link&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="kt"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;HttpExceptionRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StatusCodeException&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="n"&gt;bytestring&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
     &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;^.&lt;/span&gt; &lt;span class="n"&gt;responseStatus&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
       &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"ERROR: File not found (404) for "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;
       &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
         &lt;span class="n"&gt;putStrLn&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"ERROR: Unknown error with code "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;" for "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
         &lt;span class="n"&gt;link&lt;/span&gt;
     &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;LBS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromStrict&lt;/span&gt; &lt;span class="n"&gt;bytestring&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can of course see that we're trying to download a file. But there's a lot going on that doesn't really have anything to do with downloading files in here. In total, the effects we are dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We're using HTTP functions: &lt;code&gt;Http.get&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We're dealing with exceptions: &lt;code&gt;Exception.catch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We're printing to the terminal: &lt;code&gt;putStrLn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can we be clearer in our types about what we're doing in a lightweight way?&lt;/p&gt;

&lt;p&gt;Well, let's make some &lt;em&gt;constraints&lt;/em&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="kr"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;MonadTerminalIO&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;putStrLnM&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;MonadTerminalIO&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;putStrLnM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;putStrLn&lt;/span&gt;

&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;MonadHttp&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;httpGetM&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="kt"&gt;LBS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ByteString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;MonadHttp&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;httpGetM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Exception.catch&lt;/code&gt; already has an associated type class/constraint, so we don't need to make that one.&lt;/p&gt;

&lt;p&gt;We can now transform our function to the following:&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;downloadFile&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;MonadHttp&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;MonadTerminalIO&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;MonadCatch&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Link&lt;/span&gt;
  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Response&lt;/span&gt; &lt;span class="kt"&gt;ByteString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;downloadFile&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Link&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;httpGetM&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="kt"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;HttpExceptionRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StatusCodeException&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="n"&gt;bytestring&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
     &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;^.&lt;/span&gt; &lt;span class="n"&gt;responseStatus&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
       &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;putStrLnM&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"ERROR: File not found (404) for "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;
       &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
         &lt;span class="n"&gt;putStrLnM&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="s"&gt;"ERROR: Unknown error with code "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;" for "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
         &lt;span class="n"&gt;link&lt;/span&gt;
     &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;fmap&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;LBS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromStrict&lt;/span&gt; &lt;span class="n"&gt;bytestring&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're now being a lot clearer with what we're doing in our type signature and all it took was a couple of type classes and a &lt;em&gt;generic&lt;/em&gt; return monad type.&lt;/p&gt;

&lt;p&gt;Because we now return &lt;code&gt;m (Response ByteString)&lt;/code&gt; and have a set of constraints on &lt;code&gt;m&lt;/code&gt; instead, we've guaranteed that there can't be any random &lt;code&gt;IO&lt;/code&gt; or other effects in our function, because those are in fact not valid for any &lt;code&gt;m&lt;/code&gt; the type system can imagine. When we try to add something that can talk to the network, for example, it would have to have an associated constraint called &lt;code&gt;MonadNetwork&lt;/code&gt;, for example, and we would have to add it to our constraints to make those functions available in that scope.&lt;/p&gt;

&lt;p&gt;If we find ourselves wanting better type signatures, they could be just a few small constraints / type classes away. It's a very effective way to limit the capabilities of a function and be very clear about what's happening inside of it.&lt;/p&gt;

&lt;p&gt;This is all possible because of type classes which serve as constraints on generic type variables, as well as higher-kinded types that allow us to talk generically about types wrapping types and together they form something I really like about Haskell &amp;amp; PureScript.&lt;/p&gt;

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