<?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: Patrick Wendo</title>
    <description>The latest articles on Forem by Patrick Wendo (@w3ndo).</description>
    <link>https://forem.com/w3ndo</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%2F473910%2F2d6d4ad0-6f4d-4a79-959f-581b21e1b118.png</url>
      <title>Forem: Patrick Wendo</title>
      <link>https://forem.com/w3ndo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/w3ndo"/>
    <language>en</language>
    <item>
      <title>Simulating Boids with ECSx and liveview</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 09 Mar 2026 10:06:24 +0000</pubDate>
      <link>https://forem.com/w3ndo/simulating-boids-with-ecsx-and-liveview-124m</link>
      <guid>https://forem.com/w3ndo/simulating-boids-with-ecsx-and-liveview-124m</guid>
      <description>&lt;p&gt;You can view the live simulation &lt;a href="https://boids-with-ecsx.gigalixirapp.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the code &lt;a href="https://github.com/W3NDO/boids" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity Component Systems for Simulations
&lt;/h2&gt;

&lt;p&gt;Entity Component Systems are a new concept I have come to learn as I am learning more about Video Game development. I was then presently surprised to find that a developer &lt;a href="https://github.com/APB9785" rel="noopener noreferrer"&gt;Andrew Berrien&lt;/a&gt; had built a library, &lt;a href="https://github.com/ecsx-framework/ECSx" rel="noopener noreferrer"&gt;ecsx&lt;/a&gt; for developing entity component systems in Elixir. Naturally I had to play around with it. &lt;/p&gt;

&lt;p&gt;In this article, I will cover what entity component systems are, how we can use them to build a boid simulation(after all, what is a game but an interactive simulation) and how we can learn to optimize simulations. We also explore ECSx and ECSx Dashboard. All references used are at the end. &lt;/p&gt;

&lt;h3&gt;
  
  
  What are Entity component systems??
&lt;/h3&gt;

&lt;p&gt;They are an architectural pattern often used in video game development. They allow for re-usability by separating data from behavior. It is a pattern that obeys the "composition over inheritance principle"&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ECS is an architecture for building real-time games and simulations, wherein data about Entities is stored in small fragments called Components, which are then read and updated by Systems.&lt;br&gt;
~Mike Binns, ecsx README.md&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Entities
&lt;/h4&gt;

&lt;p&gt;These represent a thing in a video game. A distinct object representing an actor in a simulated space. For instance, if we are playing flappy bird, the bird would be an entity. &lt;/p&gt;

&lt;p&gt;Entities have no actual data or behaviors. &lt;/p&gt;

&lt;h4&gt;
  
  
  Components
&lt;/h4&gt;

&lt;p&gt;They are data types consisting of unique behavior assigned to an entity. They are re-usable modules that are attached to entities, providing behavior, functionality and appearance forming an entity. &lt;/p&gt;

&lt;p&gt;In our flappy bird example, some components would be a y_coordinate. When attached to a bird entity we know how high on the screen the bird is.&lt;/p&gt;

&lt;h4&gt;
  
  
  Systems
&lt;/h4&gt;

&lt;p&gt;Systems provide the logic that operates on the components. &lt;/p&gt;

&lt;p&gt;For instance, in our flappy bird example, a jump system would update the y_coordinate of the bird when a click occurs. &lt;/p&gt;

&lt;h3&gt;
  
  
  Putting it all together
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System&lt;/strong&gt; : This listens to outside events and publishes updates to the components. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Components&lt;/strong&gt; : They listen to the system events and update their state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entities&lt;/strong&gt;: They gain behavior through changes in their associated components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ECSx
&lt;/h2&gt;

&lt;p&gt;The best intro I could give you for ecsx would be for you to watch &lt;a href="https://youtu.be/E9pZP5jUYZg?si=IVVny2LOJTQAeECV" rel="noopener noreferrer"&gt;Andrew Berrien's talk&lt;/a&gt; at ElixirConfUS 2023. &lt;/p&gt;

&lt;p&gt;The highlights are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entities within ecsx are conceptual.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Components and Systems have generators you can use&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mix ecsx.gen.component component_name component_type
mix ecsx.gen.system system_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a manager that controls initialization components, and which components and systems are known to the program&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tags are a special type of component that do not have a type.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Boids and our simulation.
&lt;/h2&gt;

&lt;p&gt;Craig Reynolds introduced the Boid algorithm in 1986. It is a computational model that simulates flocking behavior based on 3 rules; separation, alignment and cohesion. It have since been used widely in computer graphics and robotics to model flocking and swarming behavior.&lt;/p&gt;

&lt;p&gt;To design a boids simulation with ecsx, we need to define our components and systems. We will have 4 systems, &lt;em&gt;separation&lt;/em&gt;, &lt;em&gt;cohesion&lt;/em&gt;, &lt;em&gt;alignment&lt;/em&gt; and &lt;em&gt;movement&lt;/em&gt;. With regards to components, we need to consider that we will require to do a lot of 2d vector manipulation. As such, most of our components will have an x component and a y component. For instance, Velocity will be split into 2 components XVelocity and YVelocity.&lt;/p&gt;

&lt;p&gt;The reason for this split is that ecsx only allows a small subset of types for the components. &lt;/p&gt;

&lt;p&gt;From the internal documentation of the library&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The type of value which will be stored in this component type.  Valid types are: &lt;code&gt;:atom, :binary, :datetime, :float, :integer&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But this is ok, because we can build helpers that make it easier to work with these separate components. &lt;/p&gt;

&lt;p&gt;Further, we also define a small utility to assist with some common calculations. We will call this utility Vector, because it helps us with Vector calculations. &lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the systems
&lt;/h2&gt;

&lt;p&gt;We have 4 systems defined, &lt;code&gt;movement&lt;/code&gt;, &lt;code&gt;cohesion&lt;/code&gt;, &lt;code&gt;separation&lt;/code&gt; and &lt;code&gt;alignment&lt;/code&gt;. The systems &lt;code&gt;cohesion&lt;/code&gt;, &lt;code&gt;separation&lt;/code&gt; and &lt;code&gt;alignment&lt;/code&gt; systems will update the &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; components associated with those systems. For instance &lt;code&gt;x_cohesion&lt;/code&gt; and &lt;code&gt;y_cohesion&lt;/code&gt; are updated by the cohesion systems and so forth. &lt;/p&gt;

&lt;p&gt;The movement of a boid is defined by the sum of the result of these systems. The purpose of the movement system is to that sum these results and update the x and y position components. &lt;/p&gt;

&lt;h3&gt;
  
  
  Alignment System
&lt;/h3&gt;

&lt;p&gt;Alignment force helps the boids coordinate their direction with nearby boids. It encourages the boids to match the average velocity of their closest neighbors ensuring the group moves in a unified manner.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First we check if there are any neighbors within the alignment radius, if not the force is zero&lt;/li&gt;
&lt;li&gt;Sum all the neighbors' velocity vectors and average them to determine the group's general movement direction&lt;/li&gt;
&lt;li&gt;Instead of directly setting the velocity to the average, we subtract the boid's current velocity from it, creating a smooth transition instead of an abrupt change. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cohesion System
&lt;/h3&gt;

&lt;p&gt;The cohesion force ensures that boids stay close to their group, preventing them from drifting apart. It calculates the center of mass of the nearby boids and applying a force that pulls the boids towards this center&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We check if there are any neighboring boids. If not the force is set to a zero vector&lt;/li&gt;
&lt;li&gt;Average the position of all nearby boids to find the center of mass of the local group&lt;/li&gt;
&lt;li&gt;The boid then moves toward this center helping it stay within the flock.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Separation System
&lt;/h3&gt;

&lt;p&gt;Prevents boids from colliding with each other by making them steer away from nearby neighbors. We calculate the this by tracking the closest boids within a certain radius and calculate a repulsion force based on their distances. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The closer a neighboring boid is, the stronger the repulsion force should be. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;separation_intensity&lt;/code&gt; is a parameter that follows a hyperbolic function of the form &lt;code&gt;f(x) = a/x&lt;/code&gt; which means that as the distance decreases, the force increases. &lt;/li&gt;
&lt;li&gt;The repulsion forces from all the neighbors are summed and averages ensuring smooth movement instead of abrupt changes in direction.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Movement System
&lt;/h3&gt;

&lt;p&gt;We define weights to the 3 other forces, cohesion, separation and alignment. These allow us to provide greater control over their combined effect. After weighting, each force is added to the boid's velocity vector. &lt;/p&gt;

&lt;p&gt;Once the velocity is updated, the boid's position is recalculated. It's heading is adjusted to align with the velocity vector. We compute the orientation angle using &lt;code&gt;atan2&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The ECSx Manager.
&lt;/h2&gt;

&lt;p&gt;Our manager is responsible for the startup state of the boids. According to the docs&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This module holds three critical pieces of data - component setup, a list of every valid component type, and a list of each game system in the order they are to be run.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our manager startup function will 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;def startup do
    for _boid &amp;lt;- 1..@number_of_boids do
      entity = Base.encode16(:crypto.strong_rand_bytes(16), case: :lower)

      Boids.Components.BoidEntity.add(entity)
      Boids.Components.XCoord.add(entity, Enum.random(100..1400) * 1.0)
      Boids.Components.YCoord.add(entity, Enum.random(100..900) * 1.0)
      Boids.Components.Width.add(entity, 7.5)
      Boids.Components.Height.add(entity, 15.0)
      Boids.Components.Heading.add(entity, 360.0)
      Boids.Components.XVelocity.add(entity, Enum.random([-1, 1]) * 1.0)
      Boids.Components.YVelocity.add(entity, Enum.random([-1, 1]) * 1.0)
      Boids.Components.XCohesion.add(entity, 0.0)
      Boids.Components.YCohesion.add(entity, 0.0)
      Boids.Components.XAlignment.add(entity, 0.0)
      Boids.Components.YAlignment.add(entity, 0.0)
      Boids.Components.XSeparation.add(entity, 0.0)
      Boids.Components.YSeparation.add(entity, 0.0)
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We randomize the starting position to be random within our screen viewport. We also randomize our velocities. &lt;/p&gt;

&lt;h3&gt;
  
  
  Showing the boids
&lt;/h3&gt;

&lt;p&gt;To render our boids, we will use phoenix liveview with SVG graphics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def render(assigns) do
    ~H"""
    &amp;lt;div class="w-full p-4 bg-gray-800 h-screen border rounded-md border-black"&amp;gt;
      &amp;lt;div class="w-full flex items-center"&amp;gt;
        &amp;lt;p class="w-full text-white text-center text-2xl"&amp;gt;BOIDS&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;

    &amp;lt;!-- Render the Boids ViewFrame --&amp;gt;
      &amp;lt;div class="flex items-center justify-around"&amp;gt;
        &amp;lt;svg version="1.1" width="1500" height="900" xmlns="http://www.w3.org/2000/svg"&amp;gt;
          &amp;lt;rect width="100%" height="100%" fill="black" /&amp;gt;

          &amp;lt;%= for {height, l_position, r_position} &amp;lt;- @boids do %&amp;gt;
            &amp;lt;% [{h_1, h_2}, {l_1, l_2}, {r_1, r_2}] = [height, l_position, r_position] %&amp;gt;
            &amp;lt;polygon
              points={"#{h_1},#{h_2} #{l_1},#{l_2} #{r_1},#{r_2}"}
              fill={random_fill()}
            /&amp;gt;
          &amp;lt;% end %&amp;gt;
        &amp;lt;/svg&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    """
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component &lt;code&gt;height, l_position&lt;/code&gt; and &lt;code&gt;r_position&lt;/code&gt; all have an &lt;code&gt;x,y&lt;/code&gt; component. These will be used to render the 3 vertices of a triangle. The boids will also have random colors for now. &lt;/p&gt;

&lt;h2&gt;
  
  
  Performance optimizations
&lt;/h2&gt;

&lt;p&gt;As it stands, there are 2 optimizations I am considering. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hash Partitioning&lt;/li&gt;
&lt;li&gt;Using Nx to perform vector math. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Hash Partitioning
&lt;/h3&gt;

&lt;p&gt;Instead of calculating the forces separation, cohesion and separation for the show system, we can divide the viewport into quadrants and calculates forces for the boids in those quadrants.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Nx
&lt;/h3&gt;

&lt;p&gt;Numerical Elixir is optimized for faster mathematical computation in elixir. Right now I am doing Vector math with my own small &lt;a href="https://github.com/W3NDO/boids/blob/main/lib/boids/utils/vector.ex" rel="noopener noreferrer"&gt;vector module&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nx would do the math faster, however, in testing, I found that it actually increases system latency. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking
&lt;/h2&gt;

&lt;p&gt;For benchmarking, we will render 50 boids on a view-port of 1500x1000 px. We use &lt;a href="https://github.com/ecsx-framework/ecsx_live_dashboard" rel="noopener noreferrer"&gt;ECSx-live-dashboard&lt;/a&gt; to check performance of the systems.&lt;/p&gt;

&lt;p&gt;First we look at performance without hash partitioning and without using Nx.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vkfadhk368ixkumuhmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vkfadhk368ixkumuhmw.png" alt="systems performance of 50 boids without hash partitioning and without nx" width="696" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we check how the boids perform with hash partitioning. We use 81 partitions&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy10cmrdhpjgfqbeljjoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy10cmrdhpjgfqbeljjoi.png" alt="systems performance of 50 boids with hash partitioning and without nx" width="696" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally we check performance with Nx and no hash partitioning. The Nx utility used can be found &lt;a href="https://github.com/W3NDO/boids/blob/develop/adding_nx/lib/boids/utils/vector_nx.ex" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi1p2md4g2powmoova0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi1p2md4g2powmoova0w.png" alt="systems performance of 50 boids without hash partitioning but using nx" width="696" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Well, none of my optimizations performed better, which is OK. It just means there is room for improvement. The first implementation appears to be the best performing one. &lt;/p&gt;

&lt;p&gt;I find that the hash partitioning makes the boids roughly align along the partition edges&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkvf2h45cjk90gd08bt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkvf2h45cjk90gd08bt0.png" alt="hash partitioning boids makes rough alignment on the partition edges" width="800" height="839"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Further, I think the reason for terrible performance when using Nx, is that I am not using the correct functions. Perhaps using broadcast capabilities of Nx might be a better fit.&lt;/p&gt;

&lt;p&gt;Another optimization might be combining both Nx and hash partitioning. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is a lot more work to be done to make the system performance manageable. &lt;/p&gt;

&lt;p&gt;I think ECSx is very very neat for what it offers. It is simple to setup and understand. Further, Nx, while primarily for machine learning, is still an amazing library fr when you need high performance calculations. &lt;/p&gt;

&lt;p&gt;Liveview is still a work of art every time I use it. It is simple and gets more intuitive with practice. &lt;/p&gt;

&lt;p&gt;In the github repo, I have separate branches for &lt;a href="https://github.com/W3NDO/boids/tree/develop/hash_partitioning" rel="noopener noreferrer"&gt;hash_partitioning&lt;/a&gt; and &lt;a href="https://github.com/W3NDO/boids/tree/develop/adding_nx" rel="noopener noreferrer"&gt;nx optimisations. &lt;/a&gt;&lt;/p&gt;

</description>
      <category>ecsx</category>
      <category>liveview</category>
      <category>elixir</category>
      <category>simulation</category>
    </item>
    <item>
      <title>Let's build a test runner in Elixir.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 03 Nov 2025 20:15:46 +0000</pubDate>
      <link>https://forem.com/w3ndo/lets-build-a-test-runner-in-elixir-4cl0</link>
      <guid>https://forem.com/w3ndo/lets-build-a-test-runner-in-elixir-4cl0</guid>
      <description>&lt;p&gt;I have not interacted much with metaprogramming in Elixir, but I thought it was time to check it out. &lt;/p&gt;

&lt;p&gt;For this article, we will be building a test runner to explore the topic. &lt;/p&gt;

&lt;p&gt;So let's begin. &lt;/p&gt;

&lt;h2&gt;
  
  
  Quote
&lt;/h2&gt;

&lt;p&gt;First, we need to understand how ExUnit tests are internally represented on the AST. &lt;/p&gt;

&lt;p&gt;We use Elixir's &lt;code&gt;quote&lt;/code&gt; and &lt;code&gt;unquote&lt;/code&gt; methods. &lt;code&gt;Quote&lt;/code&gt; allows you to get an internal representation of your expression as the AST. For intance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; quote do: 1+2

{:+, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]], [1, 2]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first element, &lt;code&gt;:+&lt;/code&gt;, is an atom denoting the function call, or another tuple, representing a nested node in the AST.&lt;/li&gt;
&lt;li&gt;The second element, &lt;code&gt;[context: Elixir, imports: [{1, Kernel}, {2, Kernel}]]&lt;/code&gt;, represents metadata about the expression&lt;/li&gt;
&lt;li&gt;The third element is a list of arguments for the function call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interestingly, this AST representation &lt;code&gt;{:+, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]], [1, 2]}&lt;/code&gt; is exactly what the compiler sees. Other languages, such as flavours of Lisp will have you write the source directly as an AST. Elixir however allows you to convert from high-level source to low-level AST with a simple &lt;code&gt;quote&lt;/code&gt; invocation. &lt;/p&gt;

&lt;p&gt;Next thing we need to understand about ASTs in Elixir is that some literals will have the same representation as high-level literals. Namely, &lt;code&gt;atoms, numbers, strings, lists&lt;/code&gt; and &lt;code&gt;tuples&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; quote do: :atom #atoms
:atom
iex&amp;gt; quote do: 123 #numbers
123
iex&amp;gt; quote do: 3.14 #numbers
3.14
iex&amp;gt; quote do: [1, 2, 3] #lists
[1, 2, 3]
iex&amp;gt; quote do: "string" #strings
"string"
iex&amp;gt; quote do: {:ok, 1} #tuples
{:ok, 1}
iex&amp;gt; quote do: {:ok, [1, 2, 3]} #tuples
{:ok, [1, 2, 3]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unquote
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;unquote&lt;/code&gt; Macro allows values to be injected into the AST that is being defined. These allows the outside bound &lt;code&gt;variables, epxressions&lt;/code&gt; and &lt;code&gt;blocks&lt;/code&gt; to be injected into the AST. For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; number = 5
iex&amp;gt; ast = quote do
...&amp;gt;    number * 10
...&amp;gt; end
{:*, [context: Elixir, import: Kernel], [{:number, [], Elixir}, 10]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we see that the value of &lt;code&gt;number&lt;/code&gt; was not injected into the AST. We instead got a local reference for &lt;code&gt;number&lt;/code&gt; provided. However,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; number = 5
iex&amp;gt; ast = quote do
...&amp;gt;    unquote(number) * 10
...&amp;gt; end
{:*, [context: Elixir, import: Kernel], [5, 10]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here because we called &lt;code&gt;unquote(number)&lt;/code&gt; the value 5 gets injected into the AST.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Quote&lt;/code&gt; and &lt;code&gt;Unquote&lt;/code&gt; allow you to build ASTs without fumbling with the AST by hand. &lt;/p&gt;

&lt;h2&gt;
  
  
  Building the test runner.
&lt;/h2&gt;

&lt;p&gt;Now let's start from the bottom. What is the basic building block of a test? I think it is the &lt;code&gt;assert&lt;/code&gt; call. This checks the equivalency of your function being tested and the expected result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert MyFun.sum(2,5) == 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think we should build an implementation of this function.&lt;/p&gt;

&lt;p&gt;Side Note: I am a big proponent for TDD, so we start by builidng specs for our assert function. &lt;/p&gt;

&lt;p&gt;We define a function &lt;code&gt;assert/1&lt;/code&gt; which takes one argument that must be an expression checking equivalency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; Tahinix.assert(2 == 2)
:ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our tests, we check the assert cases where we use &lt;code&gt;:!=&lt;/code&gt; and &lt;code&gt;:==&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule TahinixTest do
  require Tahinix

  use ExUnit.Case

  test "assert returns non-zero value when tests fail equivalence" do
    assert Tahinix.assert(2 == 4) == {:error, "Assertion failed: 2 == 4"}
  end

  test "assert returns non-zero value when tests fail non-equivalence" do
    assert Tahinix.assert(2 != 2) == {:error, "Assertion failed: 2 != 2"}
  end

  test "assert returns 0 when tests pass equivalence" do
    assert Tahinix.assert(2 != 4) == :ok
  end

  test "assert returns 0 when tests pass non-equivalence" do
    assert Tahinix.assert(2 == 2) == :ok
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to make our tests pass, we start by implementing the code for &lt;code&gt;:==&lt;/code&gt; function first. We use pattern matching in the atributes in order to get our left hand side(lhs) and right hand side(rhs)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  #{:==, _, [lhs, rhs]}
  defmacro assert({:==, _, [lhs, rhs]}) do
    quote do
      lhs = unquote(lhs)
      rhs = unquote(rhs)
      result = lhs == rhs

      case result do
        false -&amp;gt; {:error, "Assertion failed: #{lhs} == #{rhs}"}
        _ -&amp;gt; :ok
      end
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will match expressions of the form &lt;code&gt;lhs == rhs&lt;/code&gt;, eg: &lt;code&gt;2 == 2&lt;/code&gt;. By having &lt;code&gt;lhs&lt;/code&gt; and &lt;code&gt;rhs&lt;/code&gt; in the head, we bind these values to the variable names, which we then pass to &lt;code&gt;unquote&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We then use case to get our return value. If the result if false, we return a tuple &lt;code&gt;{:error, reason_for_error}&lt;/code&gt;. Otherwise we retun &lt;code&gt;:ok&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Similarly for the assert &lt;code&gt;:!=&lt;/code&gt; we pattern match in the function head to get&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#{:!=, _, [lhs, rhs]}
  defmacro assert({:!=, _, [lhs, rhs]}) do
    quote do
      lhs = unquote(lhs)
      rhs = unquote(rhs)
      result = lhs != rhs

      case result do
        false -&amp;gt; {:error, "Assertion failed: #{lhs} != #{rhs}"}
        _ -&amp;gt; :ok
      end
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run our tests, we find that they are all green now. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwnu65cz1d8a8bp7qqbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwnu65cz1d8a8bp7qqbx.png" alt=" " width="474" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The question now remains, how complex an expression could we include in the left hand side? Let us right some tests and see what we can add in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test "Assert returns :ok when tests pass with a complex lhs function" do
    assert Tahinix.assert(5 * 2 == 10) == :ok
end

test "Assert returns :error when tests fail with complex lhs" do
    assert Tahinix.assert(5 * 2 == 12) == {:error, "Assertion failed: 5 * 2 == 12"}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, can we test assertions on the output of functions? For instance,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    iex&amp;gt; Tahinix.assert(MyMod.say_hello == :hello)
    :ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test blocks
&lt;/h2&gt;

&lt;p&gt;The next thing we would need to figure out is how to implement a test block in our runner. Let us inspect the AST that ExUnit test case returns when we pass it into quote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; test_ast = quote do
        test "sum test" do
            assert 2 + 2 == 4
        end
    end

{:test, [],
 [
   "sum test",
   [
     do: {:assert, [],
      [
        {:==, [context: Elixir, imports: [{2, Kernel}]],
         [
           {:+, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]], [2, 4]},
           6
         ]}
      ]}
   ]
 ]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember the breakdown we did earlier on the parts of the return value of &lt;code&gt;quote&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;Here we see that the function name is &lt;code&gt;test&lt;/code&gt; with no metadata(2nd arg), and its arguments are a do block. All we need to do for our test runner is build a function that returns a similar AST.&lt;/p&gt;

&lt;p&gt;We start by writing our tests as usual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe "testing test blocks." do
    test "A test block of a passing equivalence test" do
      assert Tahinix.test("equivalence of 2 and 2", do: Tahinix.assert(2 == 2)) ==
               {:ok, ["equivalence of 2 and 2"]}
    end

    test "A test block of a passing non-equivalence test" do
      assert Tahinix.test("non-equivalence of 2 and 2", do: Tahinix.assert(2 != 2)) ==
               {:error, ["non-equivalence of 2 and 2", "Assertion failed: 2 != 2"]}
    end

    test "A test block of a failing equivalence test" do
      assert Tahinix.test("equivalence of 2 and 3", do: Tahinix.assert(2 == 3)) ==
               {:error, ["equivalence of 2 and 3", "Assertion failed: 2 == 3"]}
    end

    test "A test block of a failing non-equivalence test" do
      assert Tahinix.test("non-equivalence of 2 and 3", do: Tahinix.assert(2 != 3)) ==
               {:ok, ["non-equivalence of 2 and 3"]}
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need an implementation to make the tests green.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmacro test(test_name, do: block) do
    quote do
      test_name = unquote(test_name)
      block = unquote(block)

      case block do
        :ok -&amp;gt; {:ok, [test_name]}
        {:error, reason} -&amp;gt; {:error, [test_name, reason]}
      end
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will execute whatever is passed in the do block (in our case we will assume it is an assertion). If the block runs without error, we return an &lt;code&gt;{:ok, [test_name]}&lt;/code&gt; tuple. Otherwise, we return a &lt;code&gt;{:error, [test_name, reason]}&lt;/code&gt; tuple. &lt;/p&gt;

&lt;p&gt;And now we can write blocks of code like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tahinix.test "Adding 2 numbers" do
    Tahinix.assert(MyFun.sum(2,1) == 3)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it will return whether or not our test has passed. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With all this, we already have a sample test runner with the basics working. Further improvements might be adding in describe blocks, accumulating the test that pass and fail and showing them to the users, and adding in other important functions like &lt;code&gt;refute&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And now we also have a better understanding of how metaprogramming in Elixir can help us write utilities like test runners. But remember, the first rule of writing Macros, &lt;code&gt;Don't write Macros&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The full repo can be found &lt;a href="https://github.com/W3NDO/tahinix" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://pragprog.com/book/cmelixir/metaprogramming-elixir" rel="noopener noreferrer"&gt;Metaprogramming in Elixir by Chris McCord&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>elixir</category>
      <category>metaprogramming</category>
    </item>
    <item>
      <title>Convention over configuration in the age of AI. ( Happy accident ? )</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Sun, 13 Jul 2025 18:58:27 +0000</pubDate>
      <link>https://forem.com/w3ndo/convention-over-configuration-in-the-age-of-ai-happy-accident--1b9j</link>
      <guid>https://forem.com/w3ndo/convention-over-configuration-in-the-age-of-ai-happy-accident--1b9j</guid>
      <description>&lt;p&gt;&lt;code&gt;Convention over configuration&lt;/code&gt; is a dogma touted in the ruby and rails ecosystem. What does this mean??&lt;/p&gt;

&lt;p&gt;Often when working with rails you find that a lot of the libraries focus on building in line with the Rails conventions. This is great! Makes it easier to get up to speed with new libraries in Ruby/Rails. &lt;/p&gt;

&lt;p&gt;But now we have LLMs. And while LLMs are great they tend to provide code that doesn't always follow convention. Not always, but it happens. &lt;/p&gt;

&lt;p&gt;I read &lt;a href="https://github.com/ash-project/.github/blob/main/AI_POLICY.md" rel="noopener noreferrer"&gt;this&lt;/a&gt; post for the contribution policy on AI for the &lt;a href="https://ash-hq.org/" rel="noopener noreferrer"&gt;Ash Framework in Elixir&lt;/a&gt; and it got me thinking. With RAG(Retrieval augemnted generation) trying to control(somewhat) the results AI gives us, does that not mean that systems with built convention would tend to be more correct than those without? Especially because all the code these LLMs would be trained on would have (for the most part) followed convention?&lt;/p&gt;

&lt;p&gt;I think that the Rails community was onto something with convention over configuration, not even because of AI. But because it helps developers understand code faster. That AI would learn from this would be a great boon. &lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Exploring elixir processes using merge sort</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 14 Apr 2025 22:41:51 +0000</pubDate>
      <link>https://forem.com/w3ndo/exploring-elixir-processes-using-merge-sort-27m2</link>
      <guid>https://forem.com/w3ndo/exploring-elixir-processes-using-merge-sort-27m2</guid>
      <description>&lt;p&gt;In this article, I use the word &lt;strong&gt;parallel&lt;/strong&gt; and &lt;strong&gt;concurrent&lt;/strong&gt; interchangeably. I need the readers to know that they are not the same. Parallel means solving smaller problems of the same chunk of work at the same time. Concurrent means solving multiple problems in what &lt;em&gt;appears to be&lt;/em&gt; the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sorting.
&lt;/h2&gt;

&lt;p&gt;A classic problem in computer science. We always need things in the right order for a variety of reasons. There are many sorting algorithms each with their merits and demerits and some made for the fun of it(I'm looking at you Bogosort). A popular algorithm is merge sort. This algorithm uses a divide and conquer approach, subdividing the list into individual elements and then merging those elements in the correct order. This is a great problem to teach yourself how to get around the recursive nature of functional languages like Elixir or Erlang. &lt;/p&gt;

&lt;h2&gt;
  
  
  Elixir &amp;amp; its processes.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Elixir runs on the Erlang VM, known for creating low latency, distributed, and fault-tolerant systems. &lt;a href="https://elixir-lang.org/" rel="noopener noreferrer"&gt;Elixir Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A cool thing that Elixir inherits from Erlang are its processes. All Elixir code runs inside processes that are isolated from each other, run concurrently and communicate via message passing. This allows Elixir developers to build distributed and fault tolerant processes. Of importance is the fact that &lt;strong&gt;Elixir processes are not Operating system processes.&lt;/strong&gt; Instead, they are lightweight in terms of memory and CPU, which allows a programmer to run tens or even hundreds of thousands of processes running simultaneously.There is a limit to how many processes you can spawn though(&lt;em&gt;definitely not foreshadowing&lt;/em&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Light weight processes and merge sort
&lt;/h2&gt;

&lt;p&gt;Well, if we have the ability to spawn light weight processes, a functional language and a sorting algorithm which we may be able to parallelize, the obvious next step is to absolutely misuse all of these ingredients until we have a working algorithm, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's cook
&lt;/h2&gt;

&lt;p&gt;Ok, if I recall from my multicore programming classes, the first thing you want to do when attempting to parallelize a problem that is  sequential is to identify which parts of the algorithm can be done in parallel. So we look at the parts of merge sort&lt;/p&gt;

&lt;h3&gt;
  
  
  Parts of the merge sort algorithm
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Find the mid-point of an array and divide the array into two halves, left and right&lt;/li&gt;
&lt;li&gt;Perform Mergesort on the left &lt;/li&gt;
&lt;li&gt;Perform Mergesort on the right&lt;/li&gt;
&lt;li&gt;Merge the two sorted halves(left and right)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementation 1
&lt;/h2&gt;

&lt;p&gt;What if in our first solution, every time we want to perform merge sort on a sub_array, we spawn a new process and let it handle that sorting for us? That sounds like a great idea. Let us do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def psort([]), do: []
  def psort([x]), do: [x]

  def psort(list) do
    {sub_arr1, sub_arr2} = Enum.split(list, floor(length(list) / 2))
    parent = self()

    child1 = spawn(fn -&amp;gt; send(parent, {:sorted, self(), psort(sub_arr1)}) end)
    child2 = spawn(fn -&amp;gt; send(parent, {:sorted, self(), psort(sub_arr2)}) end)

    sorted_sub_arr1 = receive_sorted(child1)
    sorted_sub_arr2 = receive_sorted(child2)

    merge(sorted_sub_arr1, sorted_sub_arr2)
  end

  defp receive_sorted(child_pid) do
    receive do
      {:sorted, ^child_pid, sorted_list} -&amp;gt;
        sorted_list

      # {:die} -&amp;gt;
      #   Process.exit(self(), :normal)
    end
  end

  def merge(l1, l2) do
    new_list = has_elements(l1, l2)
    new_list
  end

  def has_elements([], l2, c), do: Enum.reverse(c, l2)
  def has_elements(l1, [], c), do: Enum.reverse(c, l1)

  def has_elements([hd1 | r1], [hd2 | r2], c \\ []) do
    if hd1 &amp;gt; hd2 do
      has_elements([hd1 | r1], r2, [hd2 | c])
    else
      has_elements(r1, [hd2 | r2], [hd1 | c])
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, that's a lot of code, but let us focus on this part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    {sub_arr1, sub_arr2} = Enum.split(list, floor(length(list) / 2))
    parent = self()

    child1 = spawn(fn -&amp;gt; send(parent, {:sorted, self(), psort(sub_arr1)}) end)
    child2 = spawn(fn -&amp;gt; send(parent, {:sorted, self(), psort(sub_arr2)}) end)

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

&lt;/div&gt;



&lt;p&gt;We split the list into 2 sub_arrays and then spawn 2 processes to implement the merge_sort on those sub_arrays. `{:sorted, self(), psort(list)} is a message pattern that the parent process will expect to receive. You can read more about &lt;a href="https://dev.toSending%20and%20receiving%20messages"&gt;sending and receiving messages for processes in Elixir here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking implementation 1 vs a sequential sort algorithm.
&lt;/h2&gt;

&lt;p&gt;You only ever see the benefits of parallelization when you get some benchmarks and comparison. So let us compare our implementation with a sequential merge sort algorithm. &lt;/p&gt;

&lt;p&gt;In our benchmark, we do 40 runs of random lists with varying sizes for both the sequential and parallel implementations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa901qj9nolexgar7kpvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa901qj9nolexgar7kpvs.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait, that's not what we want. Our parallel execution is consistently slower, regardless of the number of elements. We wanted to see some form of efficiency. Why?&lt;/p&gt;

&lt;h3&gt;
  
  
  Processes are not a free lunch
&lt;/h3&gt;

&lt;p&gt;Typically, parallelization will incur some overhead. Spawning process takes some time. Message passing takes some more time. All the while the sequential algorithm just chugs along undisturbed(so to speak).&lt;/p&gt;

&lt;p&gt;The way to use processes, it to use them when they would offer a clear benefit over a a sequential execution. So how do we do that?&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation 2
&lt;/h2&gt;

&lt;p&gt;What if we kept the implementation 1 method, but only do it depending on the size of a list passed. This means that is we want to sort a list of 100 elements, we could do this sequentially, but if the list has 1_000_000 elements, perhaps we could split the load among multiple processes?&lt;/p&gt;

&lt;p&gt;We add a simple check before splitting the array and instruct it to use our sequential merge sort implementation&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
if length(list) &amp;lt;= @list_threshold do&lt;br&gt;
      SequentialMergeSort.seq_sort(list)&lt;br&gt;
else&lt;br&gt;
   ...&lt;br&gt;
end&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
I set the threshold at 1000 elements in a list.&lt;/p&gt;

&lt;p&gt;This gives us the following results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvhu3fybqrqbz3g7sfhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvhu3fybqrqbz3g7sfhd.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we notice is that all we end up with a similar trend to the sequential algorithm. Which means that we are not really getting any speed up. And if we are, it is practically negligible. Interestingly though, the initial parallel implementation fails when we get to 1 million elements in a list because we spawn too many processes. But the simple solution allows us to go up to a million with no ill effect. So there is some benefit, but there has to be a better improvement somewhere. &lt;/p&gt;

&lt;p&gt;I will be working on this a bit more to find out more performance optimizations where I can find them. Feel free to checkout and contribute to the &lt;a href="https://github.com/W3NDO/Parallel-Merge-Sort" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>elixir</category>
      <category>sorting</category>
      <category>parallelcomputing</category>
      <category>distributedcomputing</category>
    </item>
    <item>
      <title>Using regex named capture groups to process lines in a CSV file in ruby.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Sun, 16 Mar 2025 07:07:50 +0000</pubDate>
      <link>https://forem.com/w3ndo/using-regex-named-capture-groups-to-process-lines-in-a-csv-file-in-ruby-5egj</link>
      <guid>https://forem.com/w3ndo/using-regex-named-capture-groups-to-process-lines-in-a-csv-file-in-ruby-5egj</guid>
      <description>&lt;p&gt;Imagine you are processing a CSV file with information from weather stations.  single line might 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;Hamburg;22.0,Berlin;18.45,Tokyo;11.23,New York;4.20\n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The regex library in ruby allows for named captures. What this means is that you can specify a name for the text being matched. For instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/(?&amp;lt;city&amp;gt;[\w\s]+)/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;?&amp;lt;city&amp;gt;&lt;/code&gt; is the name of the capture group &lt;code&gt;w+(\s\w+)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If we run the code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hamburg;22.0".match(/(?&amp;lt;city&amp;gt;[\w\s]+)/).named_captures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return a ruby Hash that looks 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;{"city"=&amp;gt;"Hamburg"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use multiple named captures like this. However, if we want to return all matched captures in the string, we use the &lt;code&gt;.scan&lt;/code&gt; method instead. This will return an array of arrays, with each internal array being a matched capture. &lt;/p&gt;

&lt;p&gt;For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hamburg;22.0,Berlin;18.45,Tokyo;11.23,New York;4.20\n".scan(/(?&amp;lt;city&amp;gt;[\w\s]+);(?&amp;lt;temp&amp;gt;\d+(\.\d+)?)/)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will return&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[["Hamburg", "22.0"], ["Berlin", "18.45"], ["Tokyo", "11.23"], ["New York", "4.20"]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it markedly easier to process the data. &lt;/p&gt;

&lt;p&gt;Named captures are pretty cool.&lt;/p&gt;

&lt;p&gt;Reference: &lt;br&gt;
&lt;a href="https://docs.ruby-lang.org/en/3.2/regexp_rdoc.html#label-Named+Captures" rel="noopener noreferrer"&gt;Regex Named Captures&lt;/a&gt;&lt;br&gt;
&lt;a href="https://rubular.com/" rel="noopener noreferrer"&gt;Rubular (Regex playground for Ruby)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>regex</category>
    </item>
    <item>
      <title>Using meta-programming in Ruby to build a REST API from a JSON file</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 21 Oct 2024 17:47:50 +0000</pubDate>
      <link>https://forem.com/w3ndo/using-meta-programming-in-ruby-to-build-a-rest-api-from-a-json-file-909</link>
      <guid>https://forem.com/w3ndo/using-meta-programming-in-ruby-to-build-a-rest-api-from-a-json-file-909</guid>
      <description>&lt;p&gt;So I asked ChatGPT, as you do, for stuff I could do with meta-programming in Ruby. If you don't know Ruby has amazing meta-programming support. And meta-programming is basically code that can modify itself while it's running. if you want to get technical with it, meta-programming is a computer programming technique in which computer programs have the ability to treat other programs as their data. Sometimes the program being used as data is the program running. Ruby excels at this. &lt;/p&gt;

&lt;p&gt;In this post I would introduce you to AutoAPI. The goal is that you could just write your endpoint specifications in a JSON file and then  the program starts a sinatra server that then has all the endpoints. As of now, the program only works for GET endpoints and I will update it as I go. It also returns either JSON or static HTML files. Further  updates would be to serve other MIME types. Let's begin.&lt;/p&gt;

&lt;p&gt;First of all, I wanted to run this as a shell script (cause I want to practice my scripting) so we start that shebang &lt;code&gt;#!/usr/bin/env ruby&lt;/code&gt; at the top of our file. Because I wanted it to be a shell script that would run from any folder, we have the script looking for a json file called &lt;code&gt;endpoints.json&lt;/code&gt; in the current folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get the file and parse the entire file into a ruby hash
file = File.read("#{Dir.pwd}/endpoints.json")
endpoints_hash = JSON.parse(file)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use JSON to parse the file into a ruby Hash. This provides us with quality of life methods that we could use later, should we need to.&lt;/p&gt;

&lt;p&gt;Now because we are using &lt;a href="https://sinatrarb.com" rel="noopener noreferrer"&gt;Sinatra&lt;/a&gt; as our server, we would need a way to dynamically define new endpoints from the file. Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort. &lt;/p&gt;

&lt;p&gt;Let's first think about the method &lt;code&gt;send&lt;/code&gt; or &lt;code&gt;public_send&lt;/code&gt;. What these methods do is that they basically perform a method call to a class instance. For instance, if we have a class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Class
    def hello
        puts "hello"
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we did &lt;code&gt;class.send(:hello)&lt;/code&gt; our result would be &lt;code&gt;hello&lt;/code&gt;.&lt;br&gt;
You could also pass parameters to send if the method takes in any arguments. &lt;/p&gt;

&lt;p&gt;To create a GET endpoint in Sinatra, we would write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get '/hello' do
  'Hello world!'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we could dissect this and find that &lt;code&gt;:get&lt;/code&gt; is the method name, &lt;code&gt;'/hello&lt;/code&gt; is the path name and everything in the do block we shall call the &lt;code&gt;do_block&lt;/code&gt;. We could therefore also mentally re-write this as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get('/hello') do
    'Hello World'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;send(:get, '/hello', &amp;amp;block)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;&amp;amp;block&lt;/code&gt; is is the &lt;code&gt;do_block&lt;/code&gt; passed to the send method. &lt;/p&gt;

&lt;p&gt;All this to say, we need to define a method that will read the endpoint names and their associated methods to define new routes. It looks 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;def create_endpoint(method, name, &amp;amp;block)
  Sinatra::Application.instance_eval do
    name = "/#{name}" if not name.start_with?(/\//)
    send(method, name, &amp;amp;block)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes in the REST method(GET, POST, PUT, DELETE), endpoint name and a code block. It then uses instance_eval to create a new route on the running instance of Sinatra. I added a check to ensure that the the endpoint name is preceded with a forward-slash because I ran into this random bug where the route would seem to be defined, but not accessible because it does not start with a forward-slash. finally, we just send the method as shown above. Simple, right?? Honestly, it's that simple.&lt;/p&gt;

&lt;p&gt;Now we should specify that the &lt;code&gt;endpoints.json&lt;/code&gt; file has a specific structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "GET": {
        "json_response": {
            "header": {"Content-Type": "application/json"},
            "response": {
                "content": { "message": "Hello AutoAPI"},
                "file": false
            }
        },
        "json_response_file": {
            "header": {"Content-Type": "application/json"},
            "response": {
                "file": true,
                "content": "endpoints.json"
            }
        },
        "html_file": {
            "header": {"Content-Type": "text/html"},
            "response": {
                "file": true,
                "content": "test.html"
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a sample of the endpoints file. We shall go through each endpoint one at a time. So all the REST verbs act as keys, that way all the GET routes are in the GET values etc etc. Our first endpoint is the &lt;code&gt;json_response&lt;/code&gt;. This one was supposed to test if I could get a hard coded response. The header is a nested object containing what you would expect in a typical HTTP GET request. Here we are passing the Content-Type only. For the response, we have a file key that specifies if the endpoint should send a file, or if it should send the value of content as JSON. This file should also be in the same folder as the script when running it. In this example, the second endpoint actually just returns the &lt;code&gt;endpoints.json&lt;/code&gt; file. The third endpoint has a different content type and returns a HTML file. &lt;/p&gt;

&lt;p&gt;To process these endpoints, this is the code I wrote&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoints_hash.each do |method, paths|
  paths.each do |path, params|
    create_endpoint(method.downcase.to_s, "#{path.to_s}") do
      content_type :json if params["Content-Type"] == "application/json"
      content_type :html if params["Content-type"] == "text/html"
      if params["response"]["file"]
        send_file "#{Dir.pwd}/#{params["response"]["content"]}"
      else
        params["response"]["content"].to_json 
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All it does is iterate through all the endpoints and paths and defines routes for them. Note that I have to specify the content_type and I just use the passed headers to figure that out. The code might be a bit breakable and is a work in progress, but thus far, it works as seen below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68h1q7iqvbwa0yj832rh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68h1q7iqvbwa0yj832rh.png" alt="JSON response file" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3rxgghhbbb459tecyj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3rxgghhbbb459tecyj5.png" alt="HTML file" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd40oz12h8892zhiinp02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd40oz12h8892zhiinp02.png" alt="JSON response" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For all 3 defined routes, we manage to get a response. And all with about 29 lines of code. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasxixv7dhkrj8w4kcltl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasxixv7dhkrj8w4kcltl.jpg" alt="METAPROGRAMMING" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All code is available at &lt;a href="https://github.com/W3NDO/AutoAPI" rel="noopener noreferrer"&gt;my github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>metaprogramming</category>
      <category>ruby</category>
      <category>sinatra</category>
    </item>
    <item>
      <title>Random VS Code finds</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Fri, 11 Oct 2024 08:55:04 +0000</pubDate>
      <link>https://forem.com/w3ndo/random-vs-code-finds-3m11</link>
      <guid>https://forem.com/w3ndo/random-vs-code-finds-3m11</guid>
      <description>&lt;p&gt;Code OSS, (or VS Code) as an IDE are both really powerful when you get to leverage their available extensions. If you follow the VS Code tiktok you always find helpful tips and extensions that come in handy. In this series I will try and highlight some of my favourite extensions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Thunderclient
&lt;/h2&gt;

&lt;p&gt;If you develop APIs and you want to test as you go, &lt;a href="https://www.thunderclient.com/" rel="noopener noreferrer"&gt;Thunderclient&lt;/a&gt; is a great alternative to Postman or Curl. With it being within your IDE you don't have to jump between applications whenever testing is required. I came across it when I was building a rails backend for a react application I was working on. Their documentation is easy enough to understand. If you are in any way versed with Postman, you will feel right at home with Thunderclient. &lt;/p&gt;

&lt;h2&gt;
  
  
  Todo Tree
&lt;/h2&gt;

&lt;p&gt;I write a lot on paper when I am working on a problem. The problem is usually that when I need to move around my work always gets messed up. I have also been in meetings where I add all my todos in a &lt;code&gt;todo.txt&lt;/code&gt; file. &lt;a href="https://github.com/Gruntfuggly/todo-tree" rel="noopener noreferrer"&gt;Todo Tree&lt;/a&gt; however is a bit of a saving grace. By just adding a comment starting with the word todo for instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// TODO write tests for this function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can then check the todo side tab and see all the todos left for me to do. Just don't forget to clear your todos before pushing to prod :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawio Integration
&lt;/h2&gt;

&lt;p&gt;During my college days I used to use &lt;a href="https://drawio.com" rel="noopener noreferrer"&gt;Drawio&lt;/a&gt; to draw wireframes and flowcharts. When I found that there is a &lt;a href="https://open-vsx.org/extension/hediet/vscode-drawio" rel="noopener noreferrer"&gt;VS Code extension&lt;/a&gt; that allows me to do it in the IDE it was a no brainer. I have found it is also useful whenever I am screen sharing to use it as a whiteboard during meetings. All you have to do is create a new file with the &lt;code&gt;.drawio&lt;/code&gt; extension and you're off to the races. You can then export to &lt;code&gt;.svg&lt;/code&gt; and &lt;code&gt;.png&lt;/code&gt; as you see fit. However, it is an unofficial extension, so you should beware. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwindcss Intellisense
&lt;/h2&gt;

&lt;p&gt;This was a recommendation from a friend. &lt;a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss" rel="noopener noreferrer"&gt;Tailwindcss Intellisense&lt;/a&gt; provides insight into which CSS properties your tailwind code affects. Great for anyone who  does a lot of frontend with tailwindcss. &lt;/p&gt;

</description>
      <category>development</category>
      <category>vscode</category>
    </item>
    <item>
      <title>What are some fun or scary vulnerabilities you heard about recently??</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 12 Feb 2024 11:18:40 +0000</pubDate>
      <link>https://forem.com/w3ndo/what-are-some-fun-or-scary-vulnerabilities-you-heard-about-recently-mml</link>
      <guid>https://forem.com/w3ndo/what-are-some-fun-or-scary-vulnerabilities-you-heard-about-recently-mml</guid>
      <description></description>
      <category>discuss</category>
      <category>security</category>
    </item>
    <item>
      <title>Rails is Pretty Intuitive once you get used to it.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 21 Aug 2023 10:47:53 +0000</pubDate>
      <link>https://forem.com/w3ndo/rails-is-pretty-intuitive-once-you-get-used-to-it-295c</link>
      <guid>https://forem.com/w3ndo/rails-is-pretty-intuitive-once-you-get-used-to-it-295c</guid>
      <description>&lt;p&gt;I am currently working with background jobs in Rails through Active Job. And I needed some code to run before the job starts. So I thought, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Typically when you are working with the controllers and you want to run some code before an action you have a &lt;code&gt;before_action&lt;/code&gt; callback. In stimulus reflex, we have the &lt;code&gt;before_reflex&lt;/code&gt; callback. It should be safe to assume that Active Job must have a &lt;code&gt;before_perform&lt;/code&gt; callback&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I just set that up real quick and what do you know it run. I checked the docs just to make sure I was not having some vivid hallucination and true enough there is a &lt;code&gt;before_perform&lt;/code&gt; callback, as well as a couple other useful ones. &lt;/p&gt;

&lt;p&gt;This may not seem like much, but the ability to guesstimate what type of functions may be defined on a class is one of the few things I love about rails and ruby in general. It's like how the Enumerable class from which arrays, sets and hashes all inherit allows you to know that there are some methods that will always exist between these classes. And how a function ending in a question mark will return a boolean while one ending in an exclamation mark will do some potentially destructive action on whatever object calls it.&lt;/p&gt;

&lt;p&gt;Rails and Ruby is pretty awesome when it comes to the developer experience.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>coding</category>
    </item>
    <item>
      <title>Fly.io: Just 2 commands and the app is live.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Sun, 30 Jul 2023 15:54:07 +0000</pubDate>
      <link>https://forem.com/w3ndo/just-2-commands-and-the-app-is-live-flyio-is-amazing-1cae</link>
      <guid>https://forem.com/w3ndo/just-2-commands-and-the-app-is-live-flyio-is-amazing-1cae</guid>
      <description>&lt;p&gt;I am a rails developer. I started out my developer life as a rails developer. I mention this because ruby on rails helps you build a lot very fast. If you are looking for the fastest way to move from idea to MVP, rails is almost always one of the top suggestions. When I wanted to pivot to mobile dev, I started with React Native, but I felt a lot more comfortable working with flutter. Then now, I was working on the ruby on rails hackathon this past weekend and one of the goals was to try out &lt;a href="https://fly.io" rel="noopener noreferrer"&gt;fly.io&lt;/a&gt; as a hosting provider. And well, fly.io gave me the same level of comfort that rails and flutter do. That comfort I think comes from the adherance, at least somewhat, to the doctrine of convention over configuration. &lt;/p&gt;

&lt;p&gt;Ruby on rails works hard to scaffold a lot for you. Similarly to flutter compared to React Native at least. And now, I find that Fly does the same thing. When I was using heroku and render to host my projects, there is often a lot of jumping between my terminal, and the browser in order to set up a postgres database, a redis server and to actually set up the rails server. Fly.io just gives you the cli tool &lt;code&gt;flyctl&lt;/code&gt; and gets you up and running in no time flat. Let me explain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorize the login for &lt;code&gt;flyctl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;After you download the tool and install it you would need to login using the command &lt;code&gt;flyctl auth login&lt;/code&gt;. If you have an account, it will open up your browser and log you in, and this is the last time you may need to visit your browser until your deployment is done. (I promise)&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get deploying.
&lt;/h3&gt;

&lt;p&gt;So now we stay within the terminal. Make sure you're in the working directory of your project. In this case it is a rails project. First command we run is &lt;code&gt;fly launch&lt;/code&gt;. This command will detect the type of app within the directory, be it rails, Phoenix, Django or Laravel. The following are a list of prompts it will ask you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If a configuration file(fly.toml) is found, it will as if you want to copy the configuration to the new app&lt;/li&gt;
&lt;li&gt;The name of your app.&lt;/li&gt;
&lt;li&gt;If the app already exists, it will ask if you want to launch into that app.&lt;/li&gt;
&lt;li&gt;The region in which you want to deploy your app&lt;/li&gt;
&lt;li&gt;Whether or not you want to create a postgres database for your app&lt;/li&gt;
&lt;li&gt;Whether or not you want to create a redis server for your app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's about it for that command. Flyctl tool will do the rest.&lt;/p&gt;

&lt;p&gt;Once that part is done, the next command we run is &lt;code&gt;fly deploy&lt;/code&gt;&lt;br&gt;
The &lt;code&gt;fly deploy&lt;/code&gt; command gets the app name from the fly.toml file. Then flyctl will start the process of deploying your application to the Fly Platform and return you to the command line when it’s done. If this command runs successfully, then the app has been successfully deployed. The last command you can run is &lt;code&gt;fly open&lt;/code&gt; and this will open your app on your your browser.&lt;/p&gt;

&lt;p&gt;So that's it. No really, that's it. 2 commands and your app is up and running. Idk about you, but I think it's pretty  amazing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is the first time I have used fly.io and I think that the developers over there are putting in a lot of work to help with the developer experience of deploying. The great thing is, a lot of the configuration files are also copied to your local machine allowing you to make changes as you see fit, but if you are looking to get from idea to MVP, I think that using fly.io for hosting is such a win. &lt;/p&gt;

&lt;p&gt;To the team at fly.io, if you're reading this, ABSOLUTELY STUNNING WORK!!!.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>devops</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Convergent Evolution in Code.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Fri, 09 Dec 2022 19:32:07 +0000</pubDate>
      <link>https://forem.com/w3ndo/convergent-evolution-in-code-31f9</link>
      <guid>https://forem.com/w3ndo/convergent-evolution-in-code-31f9</guid>
      <description>&lt;p&gt;Convergent evolution is when two different and separate organisms evolve the same mechanism to solve a similar problem. Like wings in insects and birds, or fins in Whales and fish. &lt;/p&gt;

&lt;p&gt;Recently I was explaining to my friend, a JavaScript developer, about a helper function I wrote in Rails that would auto-generate rows on a table given the correct data. Their response was, &lt;/p&gt;

&lt;p&gt;"Congratulations, you have built your first react component" &lt;/p&gt;

&lt;p&gt;Now, I have used react before, but it did not occur to me at all that by building this helper in Rails was akin to building a component in react. So my response was, &lt;/p&gt;

&lt;p&gt;" Did I build a react component, or is it convergent evolution? "&lt;/p&gt;

&lt;p&gt;Regardless, it made me wonder, what other pieces of code or way of doing things have we as developers all converged upon, regardless of language or framework?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Resist the urge to push and move on immediately.</title>
      <dc:creator>Patrick Wendo</dc:creator>
      <pubDate>Mon, 21 Nov 2022 15:27:16 +0000</pubDate>
      <link>https://forem.com/w3ndo/resist-the-urge-to-push-and-move-on-immediately-46d5</link>
      <guid>https://forem.com/w3ndo/resist-the-urge-to-push-and-move-on-immediately-46d5</guid>
      <description>&lt;p&gt;It never hurts to read through your code one more time. But how you read through it is fairly important too. I have gotten used to the mentality of "make sure it works then optimize later", which is fairly ok for the most part. But sometimes, I will write a piece of code that works, tell myself I will optimize it later, then start working on something else entirely and I forget to optimize my code. Which would leave me having to try and explain why I did not do a rather obvious optimization.&lt;/p&gt;

&lt;p&gt;So for the past couple weeks, I have decided to commit my code, but not push until I have re-checked my work. How does this look like? Well, say I am implementing feature A today. I will write the tests, and try to make them pass. Once the tests are passing, I will commit and walk away from my code( By walk away I mean literally not even look at anything remotely associated with the codebase.) I'll watch a youtube video or go outside for a well deserved break. The goal here is to make sure that when you go back to your code, you have a fresh pair of eyes on the issue. A hack I was taught by &lt;a class="mentioned-user" href="https://dev.to/jeremyf"&gt;@jeremyf&lt;/a&gt; , is to just walk through a door way. No idea why it works, but it does. &lt;/p&gt;

&lt;p&gt;Coming back I will ask myself, "What does this line/block do? Is it critical?" for each line or block of code I had previously written. This helps me remove those pesky bits of dead code or random logs. Similarly, I will go through the tests and start thinking about the random edge cases. If it is a UI issue, I will ask myself, "is this the best look for the system?" "Can it perhaps be made to look better than this?", and other questions pertaining to UX. &lt;/p&gt;

&lt;p&gt;Making sure your code works correctly seems like a pretty obvious thing to do, but it's always good to remind yourself the goals that you are striving for in your code. Makes for much better and well thought out code. &lt;/p&gt;

</description>
      <category>api</category>
    </item>
  </channel>
</rss>
