<?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>Forem: Tim McNamara</title>
    <description>The latest articles on Forem by Tim McNamara (@timclicks).</description>
    <link>https://forem.com/timclicks</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%2F48759%2F8df1f2f4-94b1-44c1-a370-183744a60f7e.png</url>
      <title>Forem: Tim McNamara</title>
      <link>https://forem.com/timclicks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/timclicks"/>
    <language>en</language>
    <item>
      <title>Two trie implementations in Rust (one's super fast)</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Fri, 31 Mar 2023 01:58:14 +0000</pubDate>
      <link>https://forem.com/timclicks/two-trie-implementations-in-rust-ones-super-fast-2f3m</link>
      <guid>https://forem.com/timclicks/two-trie-implementations-in-rust-ones-super-fast-2f3m</guid>
      <description>&lt;p&gt;A trie is a data structure that enables very fast lookups, while taking up quite a small amount of space. Here's an implementation in Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Default,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TrieNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;is_end_of_word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&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="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrieNode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Default,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Trie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TrieNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Trie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Trie&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;TrieNode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&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="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.root&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;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.chars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.children&lt;/span&gt;&lt;span class="nf"&gt;.entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.or_default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.is_end_of_word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.root&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;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.chars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.children&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;current_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;current_node&lt;/span&gt;&lt;span class="py"&gt;.is_end_of_word&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;trie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Trie&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;trie&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;trie&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;trie&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hey"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;trie&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{trie:#?}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hiiii? {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trie&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hiiii"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can gain some extra speed by replacing the standard library's hash map implementation with &lt;code&gt;fxhash&lt;/code&gt;. To do so, replace the first few lines with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;fxhash&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FxBuildHasher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FxHashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FxBuildHasher&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Default)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;TrieNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;is_end_of_word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&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="n"&gt;FxHashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrieNode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's happening?&lt;/p&gt;

&lt;p&gt;The standard library's &lt;code&gt;std::collections::HashMap&lt;/code&gt; uses a hash function -- a function which takes an input and morphs it into an output of a fixed size -- that's designed to be cryptographically secure and general purpose at the expense of speed. Because we know that our keys will be the &lt;code&gt;char&lt;/code&gt; type, which takes up 4 bytes, we can use a hash function that's more suited for short keys. (By the way, in case you were wondering, it probably still makes sense to use a hash function for &lt;code&gt;char&lt;/code&gt; values, even though we could just use the bits' values directly as they're all a fixed sized. Because human language tends to use a very narrow spectrum of bit patterns within a &lt;code&gt;char&lt;/code&gt;, and hash tables like keys to be well spread out, the hash function can spread the bits out for what is hopefully a net performance win.)&lt;/p&gt;

</description>
      <category>rust</category>
      <category>datastructures</category>
      <category>trie</category>
    </item>
    <item>
      <title>Create something beautiful this weekend! Write your first shader and put it on the web with WebGL</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Sun, 19 Mar 2023 02:13:00 +0000</pubDate>
      <link>https://forem.com/timclicks/create-something-beautiful-this-weekend-write-your-first-shader-and-put-it-on-the-web-with-webgl-3gc</link>
      <guid>https://forem.com/timclicks/create-something-beautiful-this-weekend-write-your-first-shader-and-put-it-on-the-web-with-webgl-3gc</guid>
      <description>&lt;p&gt;I've always wanted to create a "shader" -- a graphics program that works really fast (it runs on your GPU) -- but I've always been put off because they seemed really difficult.&lt;/p&gt;

&lt;p&gt;Shaders come in two forms: fragment shaders and vertex shaders. Fragment shaders are what we care about here, because they're more useful for drawing. A fragment shader is a type of shader that processes individual fragments (pixels) on the screen. It is responsible for determining the color of each pixel in the final rendered image. GLSL is a C-like language used for writing shaders in OpenGL.&lt;/p&gt;

&lt;p&gt;All of this complexity has kept me away for a long time. Today I managed to put that fear aside and create this - a fun dynamic gradient background:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/sMkgXh7ThT4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Running the shader yourself..
&lt;/h1&gt;

&lt;h2&gt;
  
  
  .. in ShaderToy
&lt;/h2&gt;

&lt;p&gt;ShaderToy is an interactive web playground for running shaders.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;mainImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;fragColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Normalized pixel coordinates (from 0 to 1)&lt;/span&gt;
    &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;iResolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Time-based variables for smooth animation&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iTime&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Color components&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&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;t1&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&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;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="n"&gt;uv&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;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Output the final color&lt;/span&gt;
    &lt;span class="n"&gt;fragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;To use this shader, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://www.shadertoy.com/new" rel="noopener noreferrer"&gt;https://www.shadertoy.com/new&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Replace the existing code in the "&lt;code&gt;mainImage&lt;/code&gt;" function with the code provided above.&lt;/li&gt;
&lt;li&gt;Click the "Play" button.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  .. locally
&lt;/h2&gt;

&lt;p&gt;If you want to learn how to use a shader in your own projects, you'll need to do a little more work to set things up.&lt;/p&gt;

&lt;p&gt;The project has two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;glsl.html&lt;/code&gt; - the main webpage&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shader.frag&lt;/code&gt; - a &lt;em&gt;fragment shader&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;glsl.html&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;GLSL/WebGL Shader Example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"author"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Tim McNamara"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;”og:url&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;”https://github.com/timClicks/glsl-shader-intro”&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nt"&gt;canvas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"glslCanvas"&lt;/span&gt; &lt;span class="na"&gt;data-fragment-url=&lt;/span&gt;&lt;span class="s"&gt;"shader.frag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.glslCanvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlslCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;shader.frag&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#ifdef GL_ES
&lt;/span&gt;&lt;span class="k"&gt;precision&lt;/span&gt; &lt;span class="kt"&gt;mediump&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;u_time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;u_resolution&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;mainImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;fragColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Normalized pixel coordinates (from 0 to 1)&lt;/span&gt;
    &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;u_resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Time-based variables for smooth animation&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u_time&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Color components&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&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;t1&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&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;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="n"&gt;uv&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;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Output the final color&lt;/span&gt;
    &lt;span class="n"&gt;fragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mainImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;gl_FragColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;gl_FragCoord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Note: the variables in WebGL are different than those available in ShaderToy. ShaderToy's &lt;code&gt;iResolution&lt;/code&gt; becomes &lt;code&gt;u_resolution&lt;/code&gt; and its &lt;code&gt;iTime&lt;/code&gt; becomes &lt;code&gt;u_time&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Explaining the code
&lt;/h1&gt;

&lt;p&gt;The GLSL code in &lt;code&gt;shader.frag&lt;/code&gt; is relatively short, but still fairly off-putting. Let's break it down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preprocessor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To start, we have a "Preprocessor directive". The compiler has stages, and one of the initial stages is called the "Preprocessor". &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

  &lt;span class="cp"&gt;#ifdef GL_ES
&lt;/span&gt;  &lt;span class="k"&gt;precision&lt;/span&gt; &lt;span class="kt"&gt;mediump&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="cp"&gt;#endif
&lt;/span&gt;

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

&lt;/div&gt;
&lt;p&gt;This part checks if the shader is running on OpenGL ES (Embedded Systems), a subset of OpenGL for mobile and embedded devices. If so, it sets the default floating-point precision to "medium." Precision indicates the accuracy and range of floating-point variables. "Medium" precision offers a balance between performance and accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating two "uniform" (global) variables&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;u_time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;u_resolution&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Uniform variables are global variables that can be set from outside the shader, usually from the application code. In this case, &lt;code&gt;u_time&lt;/code&gt; represents the elapsed time, and &lt;code&gt;u_resolution&lt;/code&gt; represents the screen resolution as a 2D vector (width, height).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mainImage function&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;mainImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;fragColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;mainImage&lt;/code&gt; function processes the fragment color (&lt;code&gt;fragColor&lt;/code&gt;) based on the fragment coordinates (&lt;code&gt;fragCoord&lt;/code&gt;). It takes an "output variable" &lt;code&gt;fragColor&lt;/code&gt; of type &lt;code&gt;vec4&lt;/code&gt; rather than use a return value to set the color of the fragment (pixel) and an input variable &lt;code&gt;fragCoord&lt;/code&gt; of type &lt;code&gt;vec2&lt;/code&gt; that describes the fragment's coordinates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalize pixel coordinates&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragCoord&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;u_resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;This line translates the fragment's coordinates between absolute position and a relative position between 0 and 100%. I use the term normalized because the coordinates &lt;code&gt;uv&lt;/code&gt; are independent from the device that is rendering the shader, whereas &lt;code&gt;fragCoord&lt;/code&gt; is device-specific. The code calculates &lt;code&gt;uv&lt;/code&gt; by dividing the fragment coordinates by the resolution. The uv coordinates will range from (0, 0) to (1, 1), representing the bottom-left and top-right corners of the screen, respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changing what's displayed over time&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u_time&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;These lines create time-based variables for smooth animation. The &lt;code&gt;t&lt;/code&gt; variable scales the elapsed time (&lt;code&gt;u_time&lt;/code&gt;), while &lt;code&gt;t1&lt;/code&gt; and &lt;code&gt;t2&lt;/code&gt; use sine and cosine functions to create smoothly changing values that oscillate between 0 and 1. &lt;/p&gt;

&lt;p&gt;Changing the constant being multiplied with &lt;code&gt;u_time&lt;/code&gt; changes how quickly the image changes. Adjusting how &lt;code&gt;t1&lt;/code&gt; and &lt;code&gt;t2&lt;/code&gt; behave will affect the cycle that produces the colors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculate color components (red, green, blue)&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&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;t1&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;float&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;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="n"&gt;uv&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;uv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;5&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;These lines calculate the red, green, and blue color components for each fragment using the time-based variables and the normalized pixel coordinates. The sine and cosine functions generate smoothly varying values, creating color gradients on the screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set the pixel's color&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="n"&gt;fragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;This line sets the output &lt;code&gt;fragColor&lt;/code&gt; with the calculated color components (&lt;code&gt;r&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;) and an alpha (transparency) value of 1.0 (fully opaque).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Main function&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mainImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;gl_FragColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;gl_FragCoord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function is the entry point of the shader. Its only job is to call the &lt;code&gt;mainImage&lt;/code&gt; function that we've just chatted about. I've included &lt;code&gt;mainImage&lt;/code&gt; to simplify refactoring and translating between your own HTML and ShaderToy's hosted environment.&lt;/p&gt;
&lt;h1&gt;
  
  
  Expanding the shader
&lt;/h1&gt;

&lt;p&gt;You can further experiment with this shader by adjusting the parameters, such as the coefficients in the sine (&lt;code&gt;sin&lt;/code&gt;) and cosine (&lt;code&gt;cos&lt;/code&gt;) functions that produce color components, to create different effects.&lt;/p&gt;
&lt;h1&gt;
  
  
  Acknowledgments
&lt;/h1&gt;

&lt;p&gt;This example makes use of the &lt;code&gt;patriciogonzalezvivo/glslCanvas&lt;/code&gt; project, which makes it really easy to use a GLSL shader within the HTML  tag.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/patriciogonzalezvivo" rel="noopener noreferrer"&gt;
        patriciogonzalezvivo
      &lt;/a&gt; / &lt;a href="https://github.com/patriciogonzalezvivo/glslCanvas" rel="noopener noreferrer"&gt;
        glslCanvas
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple tool to load GLSL shaders on HTML Canvas using WebGL
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://github.com/patriciogonzalezvivo/glslCanvas" rel="noopener noreferrer"&gt;GlslCanvas&lt;/a&gt; is JavaScript Library that helps you easily load GLSL Fragment and Vertex Shaders into an HTML canvas. I have used this in my &lt;a href="http://thebookofshaders.com" rel="nofollow noopener noreferrer"&gt;Book of Shaders&lt;/a&gt; and &lt;a href="http://editor.thebookofshaders.com" rel="nofollow noopener noreferrer"&gt;glslEditor&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;amp;hosted_button_id=4BQMKQJDQ9XH6" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b1df558f0d7fd1f22390f4a0d86609da22dea7803ee60bcf28cde5cfe7099b0d/68747470733a2f2f7777772e70617970616c6f626a656374732e636f6d2f656e5f55532f692f62746e2f62746e5f646f6e6174655f534d2e676966" alt="Donate"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to use it?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;There are different ways to do this. But first, make sure you are loading the latest version of &lt;code&gt;GlslCanvas.js&lt;/code&gt; on your page by adding this line to your HTML:&lt;/p&gt;

&lt;div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt; &lt;span class="pl-c1"&gt;type&lt;/span&gt;="&lt;span class="pl-s"&gt;text/javascript&lt;/span&gt;" &lt;span class="pl-c1"&gt;src&lt;/span&gt;="&lt;span class="pl-s"&gt;https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;or if you are using npm package manager on your console do:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install glslCanvas&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;The easy way&lt;/h3&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Create a canvas element in your HTML.&lt;/li&gt;
&lt;li&gt;Add the class name &lt;code&gt;glslCanvas&lt;/code&gt; to the canvas.&lt;/li&gt;
&lt;li&gt;Assign it a shader
&lt;ul&gt;
&lt;li&gt;through a url using the attribute &lt;code&gt;data-fragment-url&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;or directly writing your code inside the &lt;code&gt;data-fragment&lt;/code&gt; attribute&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;canvas&lt;/span&gt; &lt;span class="pl-c1"&gt;class&lt;/span&gt;="&lt;span class="pl-s"&gt;glslCanvas&lt;/span&gt;" &lt;span class="pl-c1"&gt;data-fragment-url&lt;/span&gt;="&lt;span class="pl-s"&gt;shader.frag&lt;/span&gt;" &lt;span class="pl-c1"&gt;width&lt;/span&gt;="&lt;span class="pl-s"&gt;500&lt;/span&gt;" &lt;span class="pl-c1"&gt;height&lt;/span&gt;="&lt;span class="pl-s"&gt;500&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/patriciogonzalezvivo/glslCanvas" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>webgl</category>
      <category>glsl</category>
      <category>html</category>
    </item>
    <item>
      <title>Creating a priority queue with a custom sort order using a binary heap in Rust</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Fri, 28 Oct 2022 09:13:00 +0000</pubDate>
      <link>https://forem.com/timclicks/creating-a-priority-queue-with-a-custom-sort-order-using-a-binary-heap-in-rust-3oab</link>
      <guid>https://forem.com/timclicks/creating-a-priority-queue-with-a-custom-sort-order-using-a-binary-heap-in-rust-3oab</guid>
      <description>&lt;p&gt;I want to create a personal web crawler. As I download each page, I collect a new list of URLs. To increase the likelihood that I am downloading the most important pages first, I want to keep the list of URLs to visit sorted by length (shorter URLs are more likely to be closer to the front page). That presents a problem though, because I'm also adding URLs.&lt;/p&gt;

&lt;p&gt;A naïve list (&lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; in Rust), won't be very efficient. After every batch of inserts, I would need to re-sort the list. Wouldn't it be good if there were a data structure that could maintain the sort order itself? Yes! It's called a &lt;em&gt;binary heap&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1585905108029960193-847" src="https://platform.twitter.com/embed/Tweet.html?id=1585905108029960193"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1585905108029960193-847');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1585905108029960193&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Rust's standard library provides a binary heap implementation, as &lt;code&gt;std::collections::BinaryHeap&lt;/code&gt;. In my case, I want to sort a list of &lt;code&gt;url::Url&lt;/code&gt;. By default, they are sorted in alphabetic order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;url&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BinaryHeap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;raw_urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;"https://www.youtube.com/watch?v=ywskA8CoulM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"https://tim.mcnamara.nz/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"https://github.com/rust-lang/rust/issues?labels=E-easy&amp;amp;state=open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BinaryHeap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;url&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;raw_urls&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="nf"&gt;.as_str&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints our URLs, but in alphabetic order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"https://www.youtube.com/watch?v=ywskA8CoulM"
"https://tim.mcnamara.nz/"
"https://github.com/rust-lang/rust/issues?labels=E-easy&amp;amp;state=open"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, it's a little bit complicated to ask &lt;code&gt;BinaryHeap&lt;/code&gt; to use a custom sort order. To change the default, I create a new type that wraps one as &lt;code&gt;ShortestFirst(Url)&lt;/code&gt;. Then, I implement &lt;code&gt;Ord&lt;/code&gt; and &lt;code&gt;PartialOrd&lt;/code&gt; traits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;url&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BinaryHeap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(PartialEq,&lt;/span&gt; &lt;span class="nd"&gt;Eq,&lt;/span&gt; &lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;ShortestFirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;PartialOrd&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ShortestFirst&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;partial_cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Ordering&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&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="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;Ord&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ShortestFirst&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;cmp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Ordering&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="nf"&gt;.cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;right&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="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;raw_urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;"https://www.youtube.com/watch?v=ywskA8CoulM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"https://tim.mcnamara.nz/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"https://github.com/rust-lang/rust/issues?labels=E-easy&amp;amp;state=open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BinaryHeap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&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;url&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;raw_urls&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ShortestFirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ShortestFirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="nf"&gt;.as_str&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints the URLs, in the order we wanted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"https://tim.mcnamara.nz/"
"https://www.youtube.com/watch?v=ywskA8CoulM"
"https://github.com/rust-lang/rust/issues?labels=E-easy&amp;amp;state=open"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>rust</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Principles of the 1x programmer</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Tue, 09 Nov 2021 22:31:36 +0000</pubDate>
      <link>https://forem.com/timclicks/principles-of-the-1x-programmer-3hdk</link>
      <guid>https://forem.com/timclicks/principles-of-the-1x-programmer-3hdk</guid>
      <description>&lt;h2&gt;
  
  
  Software is a team sport
&lt;/h2&gt;

&lt;p&gt;Even if you’re coding for yourself, you’re still coding for a team. Your future self will not have the same cognitive context that you do currently. Therefore, you should always code in a way that respects the people who are following you.&lt;/p&gt;

&lt;p&gt;One of the best introductions to this type of socially minded programming is called &lt;a href="https://buildtogether.tech/"&gt;Building Software Together&lt;/a&gt; (freely licensed under CC-BY-NC 4.0) by Greg Wilson and contributors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our aim is to teach you how to be a compassionate programmer: one who cares as much about the well-being of their colleagues and users as they do about their own. This focus is not entirely altruistic—everything you do to help others also helps your future self—but now that we all know how much harm software can do, we hope you’ll be interested in some practical idealism.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Learn through mimicry
&lt;/h2&gt;

&lt;p&gt;Find the best software written in your programming language of choice. Usually, the language’s standard library is a good place to start. Look for patterns. Try to consider how you would implement things.&lt;/p&gt;

&lt;p&gt;Small children learn by copying others. Why shouldn’t adults?&lt;/p&gt;

&lt;h2&gt;
  
  
  Being a computer scientist is less useful than you might think**
&lt;/h2&gt;

&lt;p&gt;​​Synthesis is essence of software engineering, whereas abstraction is the essence of computer science. Your job as a software developer will be to synthesise something new from composable pieces. What you create should be simple to understand and extend.&lt;/p&gt;

&lt;p&gt;You are unlikely to implement sophisticated data structures and algorithms.&lt;/p&gt;

&lt;p&gt;I don’t agree with everything that pg writes, but &lt;a href="http://paulgraham.com/weird.html"&gt;this struck out&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;99.5% of programming consists of gluing together calls to library functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The time to fix things is now&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Your team isn’t going to have fewer priorities next week or next month. There will not be an opportunity to the wholesale rewrite that the code base deserves. The only way to improve a code base is incrementally.&lt;/p&gt;

&lt;p&gt;I learned this through John Ousterhout’s book, &lt;em&gt;A Philosophy of Software Design&lt;/em&gt;. The overall suggestion that I took away from the book is that if your team is struggling with a spaghetti code base, its members should be investing about 10-20% of their total development time cleaning it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  You’re paid to build
&lt;/h2&gt;

&lt;p&gt;If you think that you’re employed to write software, then you’ve not thought hard enough.&lt;/p&gt;

&lt;p&gt;You’re employed to make money – or save money – for someone. And the way to do that is probably through programming.&lt;/p&gt;

&lt;p&gt;The phrase is terrible, but it’s worth repeating anyway. Make sure that you “add value”.&lt;/p&gt;

&lt;p&gt;This matters because sometimes – perhaps often – working on the boring thing that no one wants to work on is really the thing that you should be doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity really helps
&lt;/h2&gt;

&lt;p&gt;We all want to write simple software, as hard as that is. Ideally, your code should be simple enough so that a junior programmer who doesn’t like you can understand it.&lt;/p&gt;

&lt;p&gt;Ironically, simple code probably has a shorter lifespan than complex code. Complex and difficult code remains fixed because people are afraid to change it. Complex code is very hard to test. And without regression tests, we don’t know if we’ve broken behaviour. So it becomes brittle.&lt;/p&gt;

&lt;h2&gt;
  
  
  API beats algorithm
&lt;/h2&gt;

&lt;p&gt;Syntax matters. One of the lessons from the success of Kenneth Reith’s &lt;code&gt;requests&lt;/code&gt; package — which completely took over from the standard library’s own implementation of making web requests — is that the (public) API is more important than every millisecond that you save from implementing the perfect algorithm. Users care about convenience. Convenient code is easy to write, easy to read and easy to maintain.However, it’s also understand what comprises your &lt;a href="https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain"&gt;“Porcelain API” and your “Plumbing API”&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other people make mistakes
&lt;/h2&gt;

&lt;p&gt;The majority of us are better drivers than average. I’m sure the same is true for programming.Brains are imperfect.&lt;/p&gt;

&lt;p&gt;It’s impossible for you to assess your own skill level.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want adoption, software is just the start
&lt;/h2&gt;

&lt;p&gt;If you care about adoption, there’s lots of work to do once the code has been written. That is, unless you’re Fabrice Bellard, I guess.&lt;/p&gt;

&lt;p&gt;This, to me, is the ultimate reason why being a 1x programmer (even in a professional setting) can be sufficient. You might be able to contribute to other areas that someone who is focused purely on the code is not able (or, more commonly, unwilling) to do. 10x programmers care about the code. Everything else is secondary.&lt;/p&gt;

&lt;p&gt;Users care about themselves. To them, they need to be the primary priority. This rift causes a problem when open source maintainers decide that their users are indeed secondary. But that might be the theme of a future post.&lt;/p&gt;




&lt;p&gt;Let me know what you agree with. Hopefully it isn't everything!&lt;/p&gt;

</description>
      <category>1x</category>
      <category>career</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How type conversions work in Rust</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Thu, 12 Aug 2021 10:23:33 +0000</pubDate>
      <link>https://forem.com/timclicks/how-type-conversions-work-in-rust-1b54</link>
      <guid>https://forem.com/timclicks/how-type-conversions-work-in-rust-1b54</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Rust is a strongly-typed programming language with static typing. It’s also quite pedantic. For example, it’s impossible to compare two integers with each other if they are of the different types. To avoid any extra work at runtime, such as &lt;a href="https://href.li/?https://en.wikipedia.org/wiki/Reflective_programming"&gt;reflection&lt;/a&gt;, Rust requires us to be precise with the types that our programs use.&lt;/p&gt;

&lt;p&gt;This small program won't compile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=4a0ad78e651e74bc52d986037eb21b0c&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&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="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead creating a program that prints 20  to the console, we receive an error message with two error codes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0308]: mismatched types
 --&amp;gt; src/main.rs:4:22
  |
4 |   println!("{}", a + b); 
  |                      ^ expected `i32`, found `u32`

error[E0277]: cannot add `u32` to `i32`
 --&amp;gt; src/main.rs:4:20
  |
4 |   println!("{}", a + b); 
  |                    ^ no implementation for `i32 + u32`
  |
  = help: the trait `Add&amp;lt;u32&amp;gt;` is not implemented for `i32`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the curious, here is some information about how to interpret those error codes. The first (&lt;a href="https://href.li/?https://doc.rust-lang.org/stable/error-index.html#E0308"&gt;E0308&lt;/a&gt;) is caused because the addition operator (+) expects the same type for both of its operands. The second error (&lt;a href="https://href.li/?https://doc.rust-lang.org/stable/error-index.html#E0277"&gt;E0277&lt;/a&gt;) is subtly different. It’s saying that the trait bounds (the interface) are not satisfied. Addition is provided by the std::ops::Add  trait and has been implicitly parameterized to i32 type by its left operand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicitly changing types with the as keyword
&lt;/h2&gt;

&lt;p&gt;The most common method you’ll encounter to convert one type to another is via the as  keyword. It’s particularly common when converting between usize (which may be 32 or 64 bits wide, depending on CPU architecture) and fixed-width integers, such as &lt;code&gt;u32&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One option that's available to us for fixing the earlier example is to promote both values to the type &lt;code&gt;i64&lt;/code&gt;, which can represent all possible values within the &lt;code&gt;u32&lt;/code&gt; and &lt;code&gt;i32&lt;/code&gt; types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=b55bd9b4447b9b01d4f98649ed54edf6&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&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="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the value cannot fit within the bounds of the type being converted to — a negative number cannot be represented by an unsigned integer type, for example — then the program will exhibit very strange behaviour (see the "Rustnomicon" reference at the bottom of the article for details). We'll work through other options for handling cases where type conversions might fail later in the series.   &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;as&lt;/code&gt; keyword asks Rust to do the minimal amount of work possible to treat a value of one type as a value of another. Very often, such as converting between integer types of equal width, the internal representation does not change. This efficiency comes at a cost.&lt;/p&gt;

&lt;p&gt;As is only available for primitive types. When you require conversions of types that you’ve designed yourself, you need to use the &lt;code&gt;std::convert::{From,Into}&lt;/code&gt; traits.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Rust reference provides a good overview of the details in the &lt;a href="https://href.li/?https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#type-cast-expressions"&gt;type cast expression&lt;/a&gt; page. The Rustnomicon also has a detailed section about &lt;a href="https://doc.rust-lang.org/nomicon/casts.html"&gt;casting between data types&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Posts to come in this series. Please follow me to get notified when they are posted!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Using the &lt;code&gt;From&lt;/code&gt; and &lt;code&gt;Into&lt;/code&gt; traits&lt;/li&gt;
&lt;li&gt;  Using the &lt;code&gt;From&lt;/code&gt; and &lt;code&gt;Into&lt;/code&gt; traits&lt;/li&gt;
&lt;li&gt;  Hidden type conversion via the &lt;code&gt;Deref&lt;/code&gt; trait&lt;/li&gt;
&lt;li&gt;  Trait objects&lt;/li&gt;
&lt;li&gt;  Downcasting&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks to &lt;a class="mentioned-user" href="https://dev.to/vorfeedcanal"&gt;@vorfeedcanal&lt;/a&gt; for comments on a previous version of this post.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>My book on Rust is available on Amazon!</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Wed, 11 Aug 2021 03:57:38 +0000</pubDate>
      <link>https://forem.com/timclicks/my-book-on-rust-is-available-on-amazon-53nl</link>
      <guid>https://forem.com/timclicks/my-book-on-rust-is-available-on-amazon-53nl</guid>
      <description>&lt;p&gt;It may seem like a small milestone, but I'm really happy to share that my book, Rust in Action, is being sent around the world from Amazon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://smile.amazon.com/Rust-Action-Tim-McNamara/dp/1617294551/"&gt;https://smile.amazon.com/Rust-Action-Tim-McNamara/dp/1617294551/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also spent some time creating a website for the book last night:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.rustinaction.com/"&gt;https://www.rustinaction.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The source code for the book's examples is available here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/rust-in-action"&gt;
        rust-in-action
      &lt;/a&gt; / &lt;a href="https://github.com/rust-in-action/code"&gt;
        code
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Source code for the book Rust in Action
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/95faae670a0008c952fc6e7a40eec6d0760b3155acf078e2f3e7a3af3bb82081/68747470733a2f2f696d616765732e6d616e6e696e672e636f6d2f3236342f3335322f726573697a652f626f6f6b2f342f643333653133392d613733652d343230362d623435372d3666613032343434396533332f4d634e616d6172612d527573742d48492e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/95faae670a0008c952fc6e7a40eec6d0760b3155acf078e2f3e7a3af3bb82081/68747470733a2f2f696d616765732e6d616e6e696e672e636f6d2f3236342f3335322f726573697a652f626f6f6b2f342f643333653133392d613733652d343230362d623435372d3666613032343434396533332f4d634e616d6172612d527573742d48492e706e67" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
Welcome to &lt;em&gt;Rust in Action&lt;/em&gt; source code&lt;/h1&gt;

&lt;p&gt;This source code repository is a companion to the &lt;a href="https://www.manning.com/books/rust-in-action?a_aid=rust&amp;amp;a_bid=0367c58f&amp;amp;chan=source_code" rel="nofollow"&gt;Rust in Action&lt;/a&gt; book by Tim McNamara, published by Manning Publications.&lt;/p&gt;

&lt;h1&gt;
Supporting the book&lt;/h1&gt;

&lt;p&gt;Most book sales are generated on the basis of trusted referrals and recommendations
Please add your rating or review on &lt;a href="https://www.goodreads.com/book/show/48496405-rust-in-action" rel="nofollow"&gt;Goodreads&lt;/a&gt;, &lt;a href="https://www.amazon.com/Rust-Action-Tim-McNamara/dp/1617294551/" rel="nofollow"&gt;Amazon&lt;/a&gt; or perhaps even your own blog.&lt;/p&gt;

&lt;p&gt;If you haven't got it yet, here are some links so that you can buy &lt;em&gt;Rust in Action&lt;/em&gt; for yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.manning.com/books/rust-in-action?a_aid=rust&amp;amp;a_bid=0367c58f&amp;amp;chan=source_code" rel="nofollow"&gt;direct from the publisher&lt;/a&gt; (recommended)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.amazon.com/Rust-Action-Tim-McNamara/dp/1617294551/" rel="nofollow"&gt;Amazon&lt;/a&gt;, or one of its subsidiaries like &lt;a href="https://www.bookdepository.com/Rust-Action-Ts-McNamara/9781617294556" rel="nofollow"&gt;Book Depository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.booksamillion.com/p/9781617294556" rel="nofollow"&gt;Books-a-Million&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.barnesandnoble.com/w/rust-in-action-tim-mcnamara/1134424547" rel="nofollow"&gt;Barnes &amp;amp; Noble&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;perhaps even your local bookshop via &lt;a href="http://www.indiebound.org/book/9781617294556" rel="nofollow"&gt;indiebound&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
Providing feedback&lt;/h1&gt;

&lt;p&gt;The issue tracker is open, and is useful for minor bug reports.&lt;/p&gt;

&lt;p&gt;Please don't submit pull requests. They are not accepted due to copyright.&lt;/p&gt;

&lt;p&gt;Please use &lt;a href="https://livebook.manning.com/books/rust-in-action" rel="nofollow"&gt;https://livebook.manning.com/books/rust-in-action&lt;/a&gt; to submit issues for anything larger, especially if you want to discuss the book's text…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/rust-in-action/code"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
 

</description>
      <category>rust</category>
    </item>
    <item>
      <title>9 advantages of programming in Rust</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Tue, 27 Jul 2021 03:56:20 +0000</pubDate>
      <link>https://forem.com/timclicks/9-advantages-of-programming-in-rust-22m0</link>
      <guid>https://forem.com/timclicks/9-advantages-of-programming-in-rust-22m0</guid>
      <description>&lt;p&gt;So, &lt;a href="https://edwardsnowden.substack.com/p/ns-oh-god-how-is-this-legal"&gt;Edward Snowden has endorsed the Rust programming language&lt;/a&gt;. &lt;a href="https://foundation.rust-lang.org/members/"&gt;Google, Microsoft, AWS, Mozilla, Facebook and many other companies are funding its development&lt;/a&gt;. Why? I can’t say for sure, but here are a few of the reasons that I like the language so much that I wrote a &lt;a href="https://www.manning.com/books/rust-in-action"&gt;book about it&lt;/a&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety for your users
&lt;/h2&gt;

&lt;p&gt;Programming in Rust provides safety guarantees that are not available to programing languages that have safety features bolted on. And unlike languages that provide an equivalent level of safety, Rust is unique in that it does not impose runtime costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheaper running costs
&lt;/h2&gt;

&lt;p&gt;Other things being equal, the application that uses less memory is cheaper to run. You can run more applications on fewer compute nodes, or you can run your application within a smaller compute instance. An application that can easily scale to serve the next 1,000 users means you’ll spend less money on development also.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faster debugging
&lt;/h2&gt;

&lt;p&gt;The Rust compiler is a coach, not simply a pedantic critic. Your experience with the helpfulness of Rust’s compiler output will make you frustrated with what you encounter from other error messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed that’s available to ordinary programmers
&lt;/h2&gt;

&lt;p&gt;Most programmers are not 10x programmers. Because of its safety safeguards, Rust programmers who do not consider themselves expert are free more willing to experiment — free from the fear that they have introduced security holes or stability issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-disciplinary community
&lt;/h2&gt;

&lt;p&gt;Rust is almost no one’s first programming language. Nor are there many Rust programmers who code exclusively in Rust. Instead, its community is drawn from programmers from many fields. This means that the Rust ecosystem benefits from many ideas that have been incubated and refined, where-ever they first popped up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wide applicability
&lt;/h2&gt;

&lt;p&gt;Rust is labelled as a “systems programming language”, but don’t allow that to cloud your thinking. Many domains are well suited for Rust development. To draw an analogy, Rust has high dynamic range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughtful abstractions
&lt;/h2&gt;

&lt;p&gt;Rust’s design process is highly collaborative. It takes years for an idea to become a stable Rust feature, partially because there are often multiple iterations of thoughtful design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easy packaging and code-reuse
&lt;/h2&gt;

&lt;p&gt;Incorporating third-party libraries into your project involves adding a single line to a metadata file. No fighting with multiple interpreter versions, incompatible dependencies, strange linker problems, or an arcane module system.&lt;/p&gt;

&lt;h2&gt;
  
  
  An empowerment mindset
&lt;/h2&gt;

&lt;p&gt;The Rust community’s overarching goal is to empower. As you take the time to learn Rust and become productive with it, you’ll find yourself believing in yourself.&lt;/p&gt;




&lt;p&gt;Tim McNamara is the author of &lt;em&gt;Rust in Action&lt;/em&gt;. He is &lt;a href="https://twitter.com/timClicks"&gt;active on Twitter&lt;/a&gt; and hosts &lt;a href="https://youtube.com/c/timClicks"&gt;tutorials on YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Things I learned about creating a C API for my Rust crate by making every mistake about creating a C API</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Tue, 06 Jul 2021 10:22:54 +0000</pubDate>
      <link>https://forem.com/timclicks/things-i-learned-about-creating-a-c-api-for-my-rust-crate-by-making-every-mistake-about-creating-a-c-api-3l6i</link>
      <guid>https://forem.com/timclicks/things-i-learned-about-creating-a-c-api-for-my-rust-crate-by-making-every-mistake-about-creating-a-c-api-3l6i</guid>
      <description>&lt;h2&gt;
  
  
  tl;dr
&lt;/h2&gt;

&lt;p&gt;Here are my tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C programmers want to allocate and free their own memory. They don't want a string provided for them. They want you to write to an array that they control.&lt;/li&gt;
&lt;li&gt;You need to "box" local variables if you want them to out-live the function. &lt;/li&gt;
&lt;li&gt;Don't model your API after &lt;code&gt;libc&lt;/code&gt;. In particular, you should avoid global state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;A few weeks ago, I stumbled upon a way for creating unique identifiers that are still sortable: &lt;a href="https://github.com/ulid/spec"&gt;ULIDs&lt;/a&gt;. ULIDs are very similar to UUIDs are typically used: as random identifiers [footnote: you should ensure that you're using UUIDv4 if you're using them this way, otherwise your IDs are not random]. &lt;/p&gt;

&lt;p&gt;ULIDs have a neat trick trick though, newer IDs are higher than older IDs. IDs generated within the same millisecond are random, but if the interval between them is longer than that then you'll be able to compare them.&lt;/p&gt;

&lt;p&gt;Naturally, I thought that I should try and implement them. &lt;a href="https://github.com/timClicks/ulid-lite"&gt;And I did&lt;/a&gt;. In fact, some benchmarking indicates that I may have created the fastest Rust implementation: it takes my computer roughly 28 nanoseconds to generate an identifier. That's 35,000 ULIDs per millisecond.&lt;/p&gt;

&lt;p&gt;Then I thought about exposing my Rust code as a C library. &lt;code&gt;libulid&lt;/code&gt;. And then I discovered that I knew almost nothing about writing a C library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;p&gt;Here are a few things that I needed to fix before getting &lt;code&gt;libulid&lt;/code&gt; ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  Global state
&lt;/h3&gt;

&lt;p&gt;One of the first things that I did was to take inspiration from the &lt;code&gt;rand()&lt;/code&gt; function from &lt;code&gt;libc&lt;/code&gt;. &lt;code&gt;rand()&lt;/code&gt; requires a &lt;code&gt;seed()&lt;/code&gt; function to be called that initializes a global random seed.&lt;/p&gt;

&lt;p&gt;My initial API involved calling &lt;code&gt;ulid_seed()&lt;/code&gt; and then &lt;code&gt;ulid_new()&lt;/code&gt; later on. This created two issues. First it was horrible to work with. Secondly, it wasn't thread safe. &lt;/p&gt;

&lt;p&gt;It turns out that the thread safety problem is &lt;a href="https://man7.org/linux/man-pages/man3/rand.3.html"&gt;well documented&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The function &lt;code&gt;rand()&lt;/code&gt; is not reentrant, since it uses hidden state that is modified on each call.  This might just be the seed to be used by the next call, or it might be something more elaborate.  In order to get reproducible behavior in a threaded application, this state must be made explicit; this can be done using the reentrant function &lt;code&gt;rand_r()&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why did I use functionality that is not thread safe? Well, I was working with the rust crate and didn't check the upstream &lt;code&gt;libc&lt;/code&gt; documentation. &lt;/p&gt;

&lt;p&gt;I was somewhat embarrassed, although very relieved, that a contributor to my code that raised the thread safety issue. Thanks &lt;a href="https://github.com/jonasmalacofilho"&gt;Jonas!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To avoid the issue, I ask users of the library to initialize a &lt;code&gt;ulid_ctx&lt;/code&gt; object that stores the random seed and pass a pointer to it when creating a new ULID.&lt;/p&gt;

&lt;h3&gt;
  
  
  _t suffix is reserved
&lt;/h3&gt;

&lt;p&gt;At one stage, I added a &lt;code&gt;_t&lt;/code&gt; suffix to all of the types that I created. It turns out that this convention is reserved by POSIX for its types. &lt;/p&gt;

&lt;h3&gt;
  
  
  Let callers manage their own memory
&lt;/h3&gt;

&lt;p&gt;One of the things that caused quite a few problems was attempting to create raw pointers in Rust, then hand them across the FFI boundary.&lt;/p&gt;

&lt;p&gt;I did this to match the ULID spec, which specifies that the API to generate a ULID should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ulid()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Rust, this is a fine thing to do. But in C, you have a decision to make: where will the memory be allocated and freed? Will it be the responsibility of the caller or the library?&lt;/p&gt;

&lt;p&gt;I spent several days trying to figure out how to do something very simple: allocate an array in Rust on the heap, pass a pointer to that array to C, then free the memory later in Rust. I eventually gave up on getting all of the pieces work together, because it seemed like C programmers would like to do something else entirely. They want to manage their own memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;Many thanks to the &lt;a href="https://www.includecpp.org/discord/"&gt;#include  Discord server&lt;/a&gt; for offering lots of advice and encouragement during this process.&lt;/p&gt;

&lt;p&gt;Thanks also to &lt;a href="https://github.com/jonasmalacofilho"&gt;Jonas&lt;/a&gt; for providing lots of patches!  &lt;/p&gt;

</description>
      <category>rust</category>
      <category>c</category>
      <category>ffi</category>
    </item>
    <item>
      <title>Calling a private Rust function from outside of its module</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Sat, 06 Mar 2021 22:10:44 +0000</pubDate>
      <link>https://forem.com/timclicks/calling-a-private-rust-function-from-outside-of-its-module-5e0n</link>
      <guid>https://forem.com/timclicks/calling-a-private-rust-function-from-outside-of-its-module-5e0n</guid>
      <description>&lt;p&gt;Private functions should be, well, private. Let's learn how to break that! Understanding what's happening will provide you insight into how programming languages are implemented.&lt;/p&gt;

&lt;p&gt;This party trick is attributed to &lt;a href="https://twitter.com/LordMZTE"&gt;LordMZTE&lt;/a&gt;. When I was discussing raw pointer manipulation on a live stream a few days' ago, they sent me a Rust playground link to explore. What I discovered was code doing something that I didn’t think was possible: call a function that’s private from outside of a module.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=9f24b9073668d80cbfc00619560d4bb8"&gt;the code from the example below is executed&lt;/a&gt;, it prints an interesting message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Private function called!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take a look at the source and see if you can figure out what’s happening:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#![allow(dead_code)]

pub mod foo {
    pub fn public() {
        println!("Public function called");
        private();   
    }
    fn private() {
        println!("Private function called!");
    }
}

pub fn main() {
    // foo::public();

    unsafe {
        std::mem::transmute::&amp;lt;usize fn&amp;gt; ()&amp;gt;((foo::public as usize) + 64)();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, how does it work? And where does 64 come from?&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Recording
&lt;/h2&gt;

&lt;p&gt;If you prefer videos - you can watch a &lt;a href="https://www.youtube.com/watch?v="&gt;recording of the stream&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/uQsDxlSojpM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;The magic happens here: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;std::mem::transmute::&amp;lt;usize fn&amp;gt; ()&amp;gt;((foo::public as usize) + 64)();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This line asks Rust to treat the memory address of the &lt;code&gt;foo::public&lt;/code&gt; function as an unsigned integer, add 64 to that value, then treat that higher address as a function and call it.&lt;/p&gt;

&lt;p&gt;Let’s break it apart to figure out how it works.&lt;/p&gt;

&lt;p&gt;Functions are represented in memory as an array of bytes just like data. Unlike data, the CPU interprets them as code. To call the &lt;code&gt;foo::private&lt;/code&gt; function from outside of the &lt;code&gt;foo&lt;/code&gt; module, we need to find out where it is laid out in memory. The Rust compiler happens to lay functions right next to each other. So to find the start of &lt;code&gt;foo::private&lt;/code&gt;, we can start with the location of &lt;code&gt;foo::public&lt;/code&gt;  and add its length. &lt;/p&gt;

&lt;p&gt;Now to reveal a sleight of hand in the original example. I removed a call to the &lt;code&gt;dbg!()&lt;/code&gt; macro, which I had executed in a previous execution:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// finding the length of foo::public()

#![allow(dead_code)]

pub mod foo {
    pub fn public() {
        println!("Public function called");
        private();   
    }
    pub fn private() { // temporarily mark foo::private as public
        println!("Private function called!");
    }
}

pub fn main() {
    dbg!((foo::private as usize) - (foo::public as usize));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If we &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2018&amp;amp;gist=f67ce26852808a0c2be11c3475116ddd"&gt;run this new version in the playground&lt;/a&gt;, we’ll receive the length printed to the console:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[src/main.rs:16] (foo::private as usize) - (foo::public as usize) = 64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With the length handy, we now know what &lt;code&gt;fn foo::private&lt;/code&gt; refers to. As an implementation detail, the &lt;code&gt;fn&lt;/code&gt; keyword creates a function pointer. Function pointers are pointers that point to executable memory.&lt;/p&gt;

&lt;p&gt;To treat a function pointer as an integer, the code uses &lt;code&gt;&amp;lt;fn&amp;gt; as usize&lt;/code&gt;. To treat a &lt;code&gt;usize&lt;/code&gt; as a memory address though, we need more powerful tools. The &lt;code&gt;std::mem::transmute()&lt;/code&gt; function is that tool. It is probably the most unsafe constructs in the Rust language. It instructs Rust to re-interpret data types. In our case,  &lt;code&gt;std::mem::transmute::&amp;lt;usize fn&amp;gt; ()&amp;gt;&lt;/code&gt;  asks Rust to interpret a &lt;code&gt;usize&lt;/code&gt; as a function pointer that takes 0 arguments and returns the “unit type” (&lt;code&gt;()&lt;/code&gt;). &lt;/p&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is being able to call private functions a security hole?
&lt;/h3&gt;

&lt;p&gt;No, not really. The program needs to be able to call private functions. We only knew which memory address to “call” because we had access to the source code. This enabled us to mark &lt;code&gt;foo::private&lt;/code&gt; as public and deduce the length of &lt;code&gt;foo::public&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That said, it is possible to scan a program’s address space looking for executable chunks. That’s exactly what viruses do.  But that doesn’t mean that Rust programs can arbitrarily violate their own privacy guards.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does “private” mean in the context of a programming language?
&lt;/h3&gt;

&lt;p&gt;In some sense, privacy doesn’t exist. There is no guard watching modules to make sure that they’re not trespassing other modules. Privacy, at least within Rust as it’s currently implemented, is a compile-time construct. We can’t look inside the executable binary to find sections marked as private.&lt;/p&gt;

&lt;p&gt;That said, programming language designers have the ability to define whatever compile-time they want. For example, the operating system has the ability to mark specific memory pages as illegal (look up “guard pages” for extra info). Attempts to access these specially marked sections of memory indicate a runtime fault and the process will be terminated. It would be possible to add one of these pages between private and public members of a module, but that would incur a memory overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s in those 64 bytes?
&lt;/h3&gt;

&lt;p&gt;If you’re interested in what is happening in those 64 bytes, then you can ask the playground to print out the assembly generated by rustc. Look for the &lt;code&gt;playground::foo::public&lt;/code&gt; section:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;playground::foo::public:
        subq        $56, %rsp
        leaq        .L__unnamed_2(%rip), %rax
        leaq        .L__unnamed_3(%rip), %rcx
        xorl        %edx, %edx
        movl        %edx, %r8d
        leaq        8(%rsp), %rdi
        movq        %rax, %rsi
        movl        $1, %edx
        callq        core::fmt::Arguments::new_v1
        leaq        8(%rsp), %rdi
        callq        *std::io::stdio::_print@GOTPCREL(%rip)
        callq        playground::foo::private
        addq        $56, %rsp
        retq 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here is &lt;code&gt;foo::public&lt;/code&gt;  again. Can you align the source code its assembly? &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    pub fn public() {
        println!("Public function called");
        private();   
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here are some hints for the curious. Many of the the opcodes are suffixed with &lt;code&gt;q&lt;/code&gt; meaning quad, or &lt;code&gt;l&lt;/code&gt; for long. Strings are passed to functions as memory addresses and the &lt;code&gt;println!&lt;/code&gt; macro desugars to calls to functions within &lt;code&gt;core::fmt&lt;/code&gt;. &lt;br&gt;
 &lt;/p&gt;

</description>
      <category>rust</category>
      <category>compilers</category>
    </item>
    <item>
      <title>Docker for the late majority</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Fri, 26 Feb 2021 00:36:34 +0000</pubDate>
      <link>https://forem.com/timclicks/docker-for-the-late-majority-kng</link>
      <guid>https://forem.com/timclicks/docker-for-the-late-majority-kng</guid>
      <description>&lt;p&gt;This is a guide for people who would like a brief introduction to Docker and are too afraid to ask for one. I get it. Everyone around you already seems to know what they’re talking about. Looking ignorant is no fun.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a container?
&lt;/h2&gt;

&lt;p&gt;A container is a strengthened process. Processes each have their own memory address space, all processes share the file system and the network. Containers are processes that have also been delegated with their own isolated file system and network.&lt;/p&gt;

&lt;p&gt;If you think of isolation of concurrent applications as a spectrum. As you move from left-to-right in this table, isolation increases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Thread&lt;/th&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Container&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CPU time&lt;/td&gt;
&lt;td&gt;CPU time&lt;/td&gt;
&lt;td&gt;CPU time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;File system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each step rightwards includes steps to the left. Containers contain 1 or more processes. Each process contains 1 or more threads.&lt;/p&gt;

&lt;p&gt;One thing to note is that these abstractions are not created equally. Processes and containers are abstractions provided by the operating system. Threads are abstractions that are provided by the CPU. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a “cgroup”? And what is a “namespace”?
&lt;/h2&gt;

&lt;p&gt;In Linux, containers are implemented with a kernel feature called &lt;em&gt;namespaces&lt;/em&gt;. Namespaces can have their access to resources such as the system’s memory restricted via _control _groups (“cgroups”). The &lt;code&gt;docker run&lt;/code&gt; command provides &lt;code&gt;--cpus&lt;/code&gt;, &lt;code&gt;--memory&lt;/code&gt;, &lt;code&gt;--ulimit&lt;/code&gt; and other parameters to enable you to define the cgroup restrictions. &lt;/p&gt;

&lt;p&gt;In addition to cgroups, Linux also enables you to restrict which syscalls are permitted by any processes running inside a container through &lt;em&gt;secure computing mode&lt;/em&gt; (“seccomp” and its “secomp-bpf” extension) . This could be used, for example, to prevent a container exposed to the Internet from ever writing to file. In Docker, this feature is exposed as &lt;code&gt;--cap-drop&lt;/code&gt; and  &lt;code&gt;--security-opt&lt;/code&gt; parameters to &lt;code&gt;docker run&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an “image”?
&lt;/h2&gt;

&lt;p&gt;Applications running in containers managed by Docker have an added trick: they carry their data along with them. Docker images, or more precisely, container images, are .tar files that contain an application and anything the application needs to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a “Docker container"?
&lt;/h2&gt;

&lt;p&gt;A Docker container is a fusion of the two concepts we’ve discussed: kernel namespaces and container image. Once that container image is created, it can be run by any &lt;code&gt;docker&lt;/code&gt; command on any (relatively recent) Linux kernel. &lt;code&gt;docker&lt;/code&gt; takes the image, creates a kernel namespace, applies the cgroup and seccomp-bpf policies, creates any required file system and networking resources, then the ENTRYPOINT defined in the Dockerfile.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why did Docker take off?
&lt;/h2&gt;

&lt;p&gt;Containers were moderately successful before Docker. But Docker solved something else apart from isolation. They were lightweight. The predominant alternative at the time Docker emerged was to run virtual machines to isolate development environment. So, every project required its own entire operating system, along with requisite disk space and memory.&lt;/p&gt;

&lt;p&gt;Moreover, virtual machine images were too bulky to send from a laptop to a production server. While it’s possible to create container images weighing in at over 1GB, it’s uncommon. Virtual machines were the opposite. It was possible to create VM images that were less than 1GB, but it was uncommon.&lt;/p&gt;

&lt;p&gt;Docker provided some things that set it apart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an easy-to-use, developer-centric CLI that simplified namespaces, cgroups, seccomp and container images&lt;/li&gt;
&lt;li&gt;creating Dockerfile, an easy-to-use, developer-centric format for specifying how to build container images&lt;/li&gt;
&lt;li&gt;hosting Docker Hub, an easy-to-use, developer-centric image hosting service &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ease-of-use looked quite attractive when compared against virtual machines, which were slow to boot and resource intensive to run. &lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix: is Docker dead?
&lt;/h2&gt;

&lt;p&gt;If you’re in the late majority and are just coming to grips with the terminology, I have an admission to make: you’re probably going to need to learn some more language.&lt;/p&gt;

&lt;p&gt;Despite the frequency of the word “Docker container”, very few containers are run directly by &lt;code&gt;docker&lt;/code&gt; these days. Not even Docker manages containers anymore. Most containers will be managed by a different container runtime environment, such as &lt;code&gt;containerd&lt;/code&gt; or CRI-O.&lt;/p&gt;

&lt;p&gt;Depending on your audience, you may wish to change your language to use industry-neutral terminology: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;replace the term “Docker container” with “container”&lt;/li&gt;
&lt;li&gt;replace the term ”Docker image” with “container image”. Or even better, use the term “OCI image”&lt;/li&gt;
&lt;li&gt;replace “docker” with the name of the actual container runtime, such as &lt;code&gt;containerd&lt;/code&gt; or CRI-O&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
    </item>
    <item>
      <title>Spend your novelty budget on Rust</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Tue, 16 Jun 2020 01:30:55 +0000</pubDate>
      <link>https://forem.com/timclicks/spend-your-novelty-budget-on-rust-4ci4</link>
      <guid>https://forem.com/timclicks/spend-your-novelty-budget-on-rust-4ci4</guid>
      <description>&lt;p&gt;Starting a new project is exciting. You get to try the new database, the new framework, the new architecture, the new everything. But every new tool introduces a risk. And those risks compound. That’s why I believe that you should &lt;a href="https://boringtechnology.club/"&gt;choose boring technology&lt;/a&gt; for most of your stack and only allow a meagre &lt;a href="https://www.shimweasel.com/2018/08/25/novelty-budgets"&gt;novelty budget&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rust is a programming language that has now proven that it deserves your attention. Software heavyweights, including Microsoft, Google and AWS all use Rust. &lt;a href="https://www.rust-lang.org/production/users"&gt;Hundreds of smaller companies&lt;/a&gt; are also taking advantage of it.&lt;/p&gt;

&lt;p&gt;If you’re in the lucky position of being able to decide which tools to use, consider Rust.&lt;/p&gt;

&lt;p&gt;Side projects make good candidates, especially if you are hitting memory constraints. Don’t rewrite your core application in a programming language that you haven’t used before. Using Rust for projects off the critical path provides time for learning, stumbling and revision. Even if the Rust prototype is not put into production, I believe that you will become a stronger software engineer. The compiler will teach you about object lifetime management and modelling concurrent applications.&lt;/p&gt;

&lt;p&gt;There are many stories of applications that are now impossible to maintain because someone decided that the latest NoSQL database, framework, or language would be perfect for the new project. That person has now left and no one knows how to keep the application alive. Luckily, &lt;a href="https://www.youtube.com/watch?v=A3AdN7U24iU"&gt;Rust is a programming language for the next 40 years&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Deadbeef? Just say no. Let's learn to build a small Rust app to find out what words can you spell with the letters A-F</title>
      <dc:creator>Tim McNamara</dc:creator>
      <pubDate>Thu, 07 Nov 2019 18:39:08 +0000</pubDate>
      <link>https://forem.com/timclicks/deadbeef-just-say-no-let-s-learn-to-build-a-small-rust-app-to-find-out-what-words-can-you-spell-with-the-letters-a-f-47em</link>
      <guid>https://forem.com/timclicks/deadbeef-just-say-no-let-s-learn-to-build-a-small-rust-app-to-find-out-what-words-can-you-spell-with-the-letters-a-f-47em</guid>
      <description>&lt;p&gt;I'm always really irritated when I see "babe" and "deadbeef" (the worst) in code examples that use hexadecimal numbers. It's actually not that funny.&lt;/p&gt;

&lt;p&gt;You know you can do the dab in hex, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--96e2MNar--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vl968jyo7yoo2jnz7gpm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--96e2MNar--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/vl968jyo7yoo2jnz7gpm.jpg" alt="Doing the Dab" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo: &lt;a href="https://commons.wikimedia.org/wiki/User:Gokudabbing"&gt;User:Gokudabbing&lt;/a&gt; / &lt;a href="https://en.wikipedia.org/wiki/Dab_(dance)#/media/File:Do_the_Dab.jpg"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What else is there? Here's a selection (the full list is at the bottom of the post).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nouns&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ace (perhaps that should be an adjective, it's time for a 90s linguistic revival) &lt;/li&gt;
&lt;li&gt;bead&lt;/li&gt;
&lt;li&gt;bee&lt;/li&gt;
&lt;li&gt;cab&lt;/li&gt;
&lt;li&gt;dad&lt;/li&gt;
&lt;li&gt;fad&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adjectives&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;decaf&lt;/li&gt;
&lt;li&gt;deaf&lt;/li&gt;
&lt;li&gt;dead&lt;/li&gt;
&lt;li&gt;deed&lt;/li&gt;
&lt;li&gt;faded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verbs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add&lt;/li&gt;
&lt;li&gt;cede&lt;/li&gt;
&lt;li&gt;fade&lt;/li&gt;
&lt;li&gt;dab&lt;/li&gt;
&lt;li&gt;feed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do we find them?
&lt;/h2&gt;

&lt;p&gt;Here's the full source code. If you're new to Rust, keep reading&amp;amp;mdashlI explain what's going on below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BufRead&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/usr/share/dict/words"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;'lines&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;line&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="nf"&gt;.lines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;byte&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sc"&gt;b'A'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'B'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'C'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'D'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'E'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'F'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
                &lt;span class="sc"&gt;b'a'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'b'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'c'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'd'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'e'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'f'&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt; &lt;span class="nv"&gt;'lines&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Let's break the example down. We start with imports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BufRead&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 bringing some of the standard library into local scope. That gives us the ability to open files. &lt;code&gt;File&lt;/code&gt; can open them. A &lt;code&gt;BufReader&lt;/code&gt; can read them efficiently. We also need to import &lt;code&gt;BufReader&lt;/code&gt;'s "traits" along with it to avoid name clashes. Traits define methods, and we can sort of pick and mix the methods that we want for any given type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hint:&lt;/strong&gt; If you haven't encountered the term trait before, think of it as an Abstract Base Class or an interface. If you're new to programming and haven't heard of those two either, that's ok. It's not essential to know what a trait is for the rest of the post.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;std::io::Result&amp;lt;()&amp;gt;&lt;/code&gt; type is a bit crazy, sorry about that. It's an indicator that something might fail under the hood—like the hard drive might break or we could trigger a permissions error—and Rust should be prepared for that.&lt;/p&gt;

&lt;p&gt;Adding &lt;code&gt;Ok(())&lt;/code&gt; at the end is our &lt;code&gt;main()&lt;/code&gt; function saying "everything went fine". We are returning &lt;code&gt;Ok&lt;/code&gt; with a &lt;code&gt;()&lt;/code&gt; type, which has the fun name "unit". It is a placeholder value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/usr/share/dict/words"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I run Ubuntu, which includes a list of valid-ish words as a plain text file. We open that up. If we do end up triggering a permissions error, or the file is deleted, the &lt;code&gt;?&lt;/code&gt; at the end will propagate the error and immediately exit the &lt;code&gt;main()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a &lt;code&gt;BufReader&lt;/code&gt; that knows how to read from &lt;code&gt;File&lt;/code&gt; objects efficiently. It's called &lt;code&gt;BufReader&lt;/code&gt; because it has contains an internal in-memory buffer that can  and then ask it to inject anything it reads into the string we create next.&lt;/p&gt;

&lt;p&gt;Now comes the best bits, or why I love Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="nv"&gt;'lines&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;line&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="nf"&gt;.lines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&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;byte&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sc"&gt;b'A'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'B'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'C'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'D'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'E'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'F'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
                &lt;span class="sc"&gt;b'a'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'b'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'c'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'd'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'e'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="sc"&gt;b'f'&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt; &lt;span class="nv"&gt;'lines&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This chunk of code is a bit of a showoff. We define a named loop, &lt;code&gt;'lines&lt;/code&gt; that can be used later to immediately abort from a word that contains a character outside of our limited alphabet. And then it uses the &lt;code&gt;match&lt;/code&gt; syntax to elegantly match bytes that we care about. (The &lt;code&gt;b&lt;/code&gt; prefix on all of those literals indicates to Rust that they should be treated as 8-bit integers, not as characters or strings - for the details check a Rust book) &lt;/p&gt;

&lt;h2&gt;
  
  
  Compiling the code
&lt;/h2&gt;

&lt;p&gt;Let's see the result!&lt;/p&gt;

&lt;p&gt;First let's build a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cargo new hexwords
     Created binary (application) `hexwords` package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree hexwords
hexwords
├── Cargo.toml
└── src
    └── main.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now copy the source code into the &lt;code&gt;main.rs&lt;/code&gt; file. Once that's done, we can run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd hexwords

$ cargo run -q
Abe
Ada
BBB
Bede
Beebe
Dacca
Dada
Dec
Decca
Dee
Edda
Feb
abed
accede
acceded
ace
aced
add
added
baa
baaed
babe
bad
bade
bead
beaded
bed
bedded
bee
beef
beefed
cab
cabbed
cad
cede
ceded
dab
dabbed
dad
dead
deaf
deb
decade
decaf
deed
deeded
deface
defaced
ebb
ebbed
efface
effaced
facade
face
faced
fad
fade
faded
fed
fee
feed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voilà!&lt;/p&gt;

&lt;p&gt;Full source code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/timClicks/hexwords"&gt;https://github.com/timClicks/hexwords&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>tutorial</category>
      <category>commandline</category>
      <category>friendlycode</category>
    </item>
  </channel>
</rss>
