{"id":10929,"date":"2024-07-09T21:29:48","date_gmt":"2024-07-09T21:29:48","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=10929"},"modified":"2024-07-13T09:23:34","modified_gmt":"2024-07-13T09:23:34","slug":"starting-out-with-elixir","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/starting-out-with-elixir\/","title":{"rendered":"Starting out with Elixir"},"content":{"rendered":"<p>I&#8217;ve wanted to try out <a href=\"https:\/\/elixir-lang.org\/\" rel=\"noopener\" target=\"_blank\">Elixir<\/a> for a while. The Elixir language is a functional, dynamic language runs on the Erlang VM. <\/p>\n<p>Obviously this is a small post and hence we&#8217;re going to cover very little of the Elixir language here, instead we&#8217;ll cover the basics of getting things up and running.<\/p>\n<p>We&#8217;re going to run up a an Elixir environment using devcontainers.<\/p>\n<ul>\n<li>Create yourself a .devcontainer folder within your source folder<\/li>\n<li>Create a file named <em>devcontrainer.json<\/em> with the following contents\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{\r\n    &quot;image&quot;: &quot;elixir&quot;,\r\n    &quot;forwardPorts&quot;: &#x5B;3000]\r\n}\r\n<\/pre>\n<\/li>\n<li>Open Visual Code from the folder (or open the folder in VS Code)<\/li>\n<li>You should have the option to open as a devcontainer, so do that<\/li>\n<\/ul>\n<p>I&#8217;d suggest installing the <em>ElixirLS: Elixir support and debugger<\/em> or another plugin if you prefer.<\/p>\n<p><strong>Hello World<\/strong><\/p>\n<p>As is the usual starting point of any language, let&#8217;s create a <em>hello_world.exs<\/em> file and add the following<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nIO.puts(&quot;Hello World&quot;)\r\n<\/pre>\n<p>Now to run this open a terminal from VS Code and type.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nelixir hello_world.exs \r\n<\/pre>\n<p>As you can see the <em>IO.puts<\/em> function outputs to the console and strings are represented by double quotes.<\/p>\n<p><strong>The Mix build tool<\/strong><\/p>\n<p>Mix is a little like the dotnet command (if you come from .NET) in that it can be used to create a new project, as well as different types of project. It&#8217;s used to run unit tests and ofcourse compile our application.<\/p>\n<p>Let&#8217;s start by creating a new Elixir project<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmix new my_project\r\n<\/pre>\n<p>This will create a new project named <em>my_project<\/em> along with default files such as mix.exs (using for configuring our application, dependencies etc.). We also have a test folder with an example test<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndefmodule ExampleTest do\r\n  use ExUnit.Case\r\n  doctest Example\r\n\r\n  test &quot;greets the world&quot; do\r\n    assert Example.hello() == :world\r\n  end\r\nend\r\n<\/pre>\n<p>We can run the tests using<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmix test\r\n<\/pre>\n<p>We can compile our Elixir application using<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmix compile\r\n<\/pre>\n<p>this will produce a _build folder and within this we&#8217;ll see a ebin\/my_project.app <\/p>\n<p><strong>Supervisor<\/strong><\/p>\n<p>Now, I&#8217;m going to state upfront, at this time all I know about supervisors and supervision trees is that they&#8217;re like an OS in a lightweight process. They start, work, then terminate. This is the mechanism we&#8217;ll use to create a Hello World application using mix<\/p>\n<p>Run <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmix new hello_world --sup\r\n<\/pre>\n<p>This produces a mix.exs file with the key addition<\/p>\n<pre class=\"brush: plain; highlight: [4]; title: ; notranslate\" title=\"\">\r\ndef application do\r\n  &#x5B;\r\n    extra_applications: &#x5B;:logger],\r\n    mod: {HelloWorld.Application, &#x5B;]}\r\n  ]\r\nend\r\n<\/pre>\n<p>and the lib\/hello_world\/application.ex file looks like this. I&#8217;ve added the IO.puts line as well as removed the comments<\/p>\n<pre class=\"brush: plain; highlight: [11]; title: ; notranslate\" title=\"\">\r\ndefmodule HelloWorld.Application do\r\n  @moduledoc false\r\n\r\n  use Application\r\n\r\n  @impl true\r\n  def start(_type, _args) do\r\n    children = &#x5B;\r\n  ]\r\n\r\n   IO.puts &quot;Hello World&quot;\r\n\r\n   opts = &#x5B;strategy: :one_for_one, name: HelloWorld.Supervisor]\r\n   Supervisor.start_link(children, opts)\r\n  end\r\nend\r\n<\/pre>\n<p>This will then run a process (using mix run) and output our &#8220;Hello World&#8221; string then terminates cleanly.<\/p>\n<p><strong>exs and ex files<\/strong><\/p>\n<p>You&#8217;ll notice that both .ex and .exs are used for Elixir file extensions. The basis seems to be that .ex are meant to be compiled whereas .exs are script files. It can be a little confusing as <em>mix<\/em> generated projects include both. For example for config and tests it generates .exs files, for the endpoints, router etc. they&#8217;re .ex.<\/p>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"https:\/\/elixir-lang.org\/\" rel=\"noopener\" target=\"_blank\">Elixir<\/a><br \/>\n<a href=\"https:\/\/hexdocs.pm\/mix\/Mix.html\" rel=\"noopener\" target=\"_blank\">Mix<\/a><br \/>\n<a href=\"https:\/\/blog.appsignal.com\/2021\/08\/23\/using-supervisors-to-organize-your-elixir-application.html\" rel=\"noopener\" target=\"_blank\">Using Supervisors to Organize Your Elixir Application<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve wanted to try out Elixir for a while. The Elixir language is a functional, dynamic language runs on the Erlang VM. Obviously this is a small post and hence we&#8217;re going to cover very little of the Elixir language here, instead we&#8217;ll cover the basics of getting things up and running. We&#8217;re going to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[730],"tags":[],"class_list":["post-10929","post","type-post","status-publish","format-standard","hentry","category-elixir"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=10929"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10929\/revisions"}],"predecessor-version":[{"id":10954,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10929\/revisions\/10954"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=10929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=10929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=10929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}