<?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: Santiago Carmuega</title>
    <description>The latest articles on Forem by Santiago Carmuega (@scarmuega).</description>
    <link>https://forem.com/scarmuega</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%2F340241%2Fb4faab37-152f-49cf-94a8-c3eb17d9b202.jpeg</url>
      <title>Forem: Santiago Carmuega</title>
      <link>https://forem.com/scarmuega</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/scarmuega"/>
    <language>en</language>
    <item>
      <title>How do you fight the developer instinct of trying to reinvent the wheel?</title>
      <dc:creator>Santiago Carmuega</dc:creator>
      <pubDate>Fri, 07 Aug 2020 12:54:20 +0000</pubDate>
      <link>https://forem.com/scarmuega/how-do-you-fight-the-developer-instinct-of-trying-to-reinvent-the-wheel-3e1d</link>
      <guid>https://forem.com/scarmuega/how-do-you-fight-the-developer-instinct-of-trying-to-reinvent-the-wheel-3e1d</guid>
      <description>&lt;p&gt;your brain is saying "use the existing tool", but deep inside you believe that building something from scratch would be better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anybody relates?&lt;/li&gt;
&lt;li&gt;Any success stories about "reinventing the wheel" and gaining something from it?&lt;/li&gt;
&lt;li&gt;Do you have any practical technique for approaching these decisions?&lt;/li&gt;
&lt;li&gt;Where do you draw the line?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Finding middle ground between Monorepo and Polyrepo</title>
      <dc:creator>Santiago Carmuega</dc:creator>
      <pubDate>Wed, 05 Aug 2020 23:34:04 +0000</pubDate>
      <link>https://forem.com/scarmuega/finding-middle-ground-between-monorepo-and-polyrepo-kif</link>
      <guid>https://forem.com/scarmuega/finding-middle-ground-between-monorepo-and-polyrepo-kif</guid>
      <description>&lt;p&gt;A lot has been said against and in favor of each option. The discussion seems as visceral as tabs vs spaces.&lt;/p&gt;

&lt;p&gt;Can't we find middle ground between the two?&lt;/p&gt;

&lt;p&gt;Nobody really likes having a single 30gb-sized repo, with 200 developers pushing commits at all times, with 1000+ branches, 10+ languages and a myriad of incompatible toolchains.&lt;/p&gt;

&lt;p&gt;At the same time, is very frustrating having to constantly switch between 20 different repos in a single day, opening and closing another 20 matching PRs, while publishing 10 different libraries just get your shinny new button into the frontend.&lt;/p&gt;

&lt;p&gt;How do you strike a good balance between the two?&lt;/p&gt;

&lt;p&gt;(FYI, my questions are not rhetoric, I'm really asking)&lt;/p&gt;

&lt;p&gt;I'm inclined to think that the "scope" of a repo should be tied to two, sometimes contradicting, dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ownership boundaries&lt;/li&gt;
&lt;li&gt;bounded contexts&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Repo by Ownership Boundary
&lt;/h3&gt;

&lt;p&gt;Having a single repo for all of the code owned by a single team is very practical, and by "team" I mean a group ~10 developers working together on the same backlog.&lt;/p&gt;

&lt;p&gt;It will never grow to the size of a "mega repo" (unless your team is composed by 10x developers working 24x7 hours 😉), so you shouldn't hit any VCS limits.&lt;/p&gt;

&lt;p&gt;Your repo interactions (PRs, issues, branching, labels, etc) can reflect a workflow tailor-made for the team, instead of compromising a workflow that fits the whole company.&lt;/p&gt;

&lt;p&gt;The stack / toolchain of the repo should (?) be relatively cohesive since it only contains stuff selected by the members of the team.&lt;/p&gt;

&lt;p&gt;Last but not least, if you live by the "you build it, you run it" motto, all of the CI/CD workflows would fit very nicely within the scope of this unique repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repo by Bounded Context
&lt;/h3&gt;

&lt;p&gt;Imagine a relatively simple subsystem within your company, composed of a web frontend, an API layer and a couple worker services. All of the above nicely orchestrated to perform intrinsically related tasks (as &lt;a class="comment-mentioned-user" href="https://dev.to/alxgrk"&gt;@alxgrk&lt;/a&gt;
 posted in the comments, a concept very well explained by DDD as &lt;a href="https://martinfowler.com/bliki/BoundedContext.html"&gt;Bounded Context&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Having all of the components in a unique repo allows us to push new features that span changes across all of the layers in a single cohesive and self-contained PR.&lt;/p&gt;

&lt;p&gt;If you need to change something in your API contracts, the same PR would include the changes to the frontend layer that consumes the API, and the changes to workers that execute the actual task. Very easy to visualize, review and to fit in your mental model as a whole.&lt;/p&gt;

&lt;p&gt;As a bonus, your deployment pipeline jobs (meaning test, QA, rollout, etc) would have a 1:1 relationship with your PRs. Nice for changelogs, awesome for rollback procedures.&lt;/p&gt;




&lt;p&gt;Sadly, these two dimensions don't always go hand-in-hand. For example, when companies split their developers between frontend and backend teams (a very common example of independent teams handling very coupled components).&lt;/p&gt;

&lt;p&gt;In a perfect world, your team has full ownership over a cohesive set of components, coupled between each other as much as they want, but very loosely coupled with the outside world. Under this assumption, I would most certainly prefer a single repo to manage all of the team's components.&lt;/p&gt;

&lt;p&gt;Wouldn't you?&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>architecture</category>
      <category>devops</category>
    </item>
    <item>
      <title>Asimov's "Foundation" in retrospective</title>
      <dc:creator>Santiago Carmuega</dc:creator>
      <pubDate>Fri, 06 Mar 2020 12:43:40 +0000</pubDate>
      <link>https://forem.com/scarmuega/asimov-s-foundation-in-retrospective-hm5</link>
      <guid>https://forem.com/scarmuega/asimov-s-foundation-in-retrospective-hm5</guid>
      <description>&lt;p&gt;If you had to summarize Isaac Asimov's novel "Prelude to Foundation" in today's terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The story of a Data Scientist named Hari Seldon and his quest for Labeled Data to train his new Machine Learning algorithm called Psychohistory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Novel published more than 30 years ago!&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>useCallForward: like a callback, but forward ;)</title>
      <dc:creator>Santiago Carmuega</dc:creator>
      <pubDate>Sun, 23 Feb 2020 14:01:25 +0000</pubDate>
      <link>https://forem.com/scarmuega/usecallforward-like-a-callback-but-forward-39bm</link>
      <guid>https://forem.com/scarmuega/usecallforward-like-a-callback-but-forward-39bm</guid>
      <description>&lt;p&gt;We all know about callbacks in react, they provide a way for a parent component to provide the implementation of a function that is triggered by a nested component. What happens when you need the opposite? How do you trigger a command that is implemented in a nested component?&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;For example, lets say that you have the following app that displays a video:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+----------------------------------------------------+
|Root                                                |
|                                                    |
| +------------+ +---------------------------------+ |
| |Sidebar     | | Content                         | |
| |            | |                                 | |
| |            | |  +---------------------------+  | |
| |  +------+  | |  |                           |  | |
| |  |play  |  | |  |       video player        |  | |
| |  |button|  | |  |                           |  | |
| |  +------+  | |  |                           |  | |
| |            | |  +---------------------------+  | |
| |            | |                                 | |
| +------------+ +---------------------------------+ |
+----------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Sidebar&lt;/code&gt; and the &lt;code&gt;Content&lt;/code&gt; components are independent, they are oblivious of the existence of each other. The sidebar has a "play" button that needs to trigger the &lt;code&gt;video.play()&lt;/code&gt; method that exists within the scope of the &lt;code&gt;Content&lt;/code&gt; component. How would you solve that?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;alternative #1, using state&lt;/strong&gt;: The &lt;code&gt;Root&lt;/code&gt; component has an &lt;code&gt;isPlaying&lt;/code&gt; flag in the state, listens to the click callback of the play button and then propagates the state down to the nested &lt;code&gt;Content&lt;/code&gt; component using props. The &lt;code&gt;Content&lt;/code&gt; component would compare changes in the props and call the &lt;code&gt;play()&lt;/code&gt; method accordingly. It works, but you loose the "imperative" nature of just calling a function; and you'll trigger an, otherwise unnecessary, render of the &lt;code&gt;Root&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;alternative #2, using refs&lt;/strong&gt;: The &lt;code&gt;Content&lt;/code&gt; component bubbles up a ref of the video player onto the &lt;code&gt;Root&lt;/code&gt; component. The &lt;code&gt;Root&lt;/code&gt; component creates an &lt;code&gt;onClick&lt;/code&gt; handler that triggers the &lt;code&gt;play()&lt;/code&gt; inside the ref and then it passes the handler into the &lt;code&gt;onClick&lt;/code&gt; callback of the &lt;code&gt;Sidebar&lt;/code&gt; component. It also works, but bubbling things up goes against the "composite" nature of our react components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution (?)
&lt;/h2&gt;

&lt;p&gt;I drafted an alternative solution as a lib called &lt;a href="https://github.com/scarmuega/react-callforward"&gt;react-callforward&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea of a &lt;code&gt;callforward&lt;/code&gt;  is to divide a method call into two parts: the &lt;em&gt;trigger&lt;/em&gt; and the &lt;em&gt;placeholder&lt;/em&gt;. The trigger is just a proxy of the actual method call. The placeholder is an empty wrapper that needs to be "implemented" by some other child component.&lt;/p&gt;

&lt;p&gt;Take the above video app example, this is how you would solve the problem using a &lt;code&gt;callforward&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;onPlay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doPlay&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCallForward&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onPlay&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt; &lt;span class="na"&gt;doPlay&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;doPlay&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;play&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;doPlay&lt;/span&gt; &lt;span class="p"&gt;})&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;videoEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;useCallHolder&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="nx"&gt;videoEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;doPlay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;videoEl&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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 above example has been simplified for brevity. To see a running example, check the following codesandbox:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/call-forward-example-upqk5?fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pzpI10jk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://codesandbox.io/static/img/play-codesandbox.svg" alt="Edit call-forward-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Potential
&lt;/h2&gt;

&lt;p&gt;I imagine several use cases where components could be stripped away of opinionated control UI (buttons, inputs, etc), but still provide the "logic" to execute such actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a simple "video" component providing play, pause, scrubbing methods&lt;/li&gt;
&lt;li&gt;any type of "data list" component providing a "refresh" method&lt;/li&gt;
&lt;li&gt;dialogs and popup components providing an imperative "open" / "close" method (thus, hiding the open/close state within the component itself)&lt;/li&gt;
&lt;li&gt;long text components providing "scrolling" (eg: "go to top") methods&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feedback
&lt;/h2&gt;

&lt;p&gt;So... is this just another example of overengineering a simple problem? Is the idea of components exposing "methods" against the basic premise of React? Is there a more "elegant" approach that could be used in these scenarios?&lt;/p&gt;

</description>
      <category>react</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
