<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Matthew Buscemi on Medium]]></title>
        <description><![CDATA[Stories by Matthew Buscemi on Medium]]></description>
        <link>https://medium.com/@matthew.buscemi?source=rss-7ebc64b27fde------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*NPSfkuW8odqjxhy9yt7zdA.jpeg</url>
            <title>Stories by Matthew Buscemi on Medium</title>
            <link>https://medium.com/@matthew.buscemi?source=rss-7ebc64b27fde------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 11:45:52 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@matthew.buscemi/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Abstraction in Elm: Conclusion]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/6ea7adcf398e</guid>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[abstraction]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[elm]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:03:26 GMT</pubDate>
            <atom:updated>2018-01-16T23:03:26.331Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><strong>Conclusion</strong></li></ol><h3>Summary</h3><p>Our code communicates implementation details (<em>what</em> the application does) best when we make it as concrete as it can possibly be.</p><p>Our code communicates our intent (<em>why</em> we made the implementation choices we did) best when we make it as abstract as it can possibly be.</p><p>When our code is perfectly concrete, intent in unclear, duplication is rampant, and change is hard because engineers attempting to read it experience detail-overload.</p><p>When our code is perfectly abstract, implementation details are unclear, meaningless partitions are rampant, and change is hard because engineers attempting to read it experience partition-overload.</p><p>When our code is perfectly concrete, the relationships between various parts of our code are unclear, because everything is in one enormous function, and so nothing exists to help distinguish the relationships.</p><p>When our code is perfectly abstract, the relationships between various parts of our code are unclear, because every single part is behind a partition. The partitions are therefore meaningless, and so nothing exists to help distinguish the relationships.</p><p>The relationships between various parts of our code are clear when we implement the best partitions for the given behavior, living within a given function, living within a given module, living within a given application, living within a given ecosystem. The definition of “best” will depend upon context, but it will always be somewhere between the two extremes of total concreteness and total abstraction, which are the least desirable configurations for any software project of significant size.</p><h3>Takeaways for Elm</h3><p>Component-based architecture forces the creation of partitions that are not tied to meaningful utilities or domains for a particular application. As a result, large component-based systems typically end up with some amount of abstraction that obscures clarity of detail without adding clarity of intent. One of the greatest aspects of programming in Elm as that the only abstractions we are beholden to are the signatures of the functions that we pass to Program.</p><p>However, I would love to see the Elm community discuss more openly which kinds of abstraction choices are good and which kinds of abstraction choices are bad, rather than urging individuals away from abstraction entirely. The time to start thinking about your application’s structure is not when it reaches six hundred lines. That time, in my experience, is always right now. Especially on a team, choosing any kind of arbitrary boundary, (for example, waiting until your data structures have such-and-such number of fields or until files become such-and-such lines long), is a recipe for engineers to proceed <em>without </em>thinking about structure. Then, the code will end up either overly concrete or overly abstract, and the team will have to deal with all the baggage that comes with that particular extreme.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6ea7adcf398e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Wrappers and Generics for Everything]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/4f54313d1a83</guid>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[abstraction]]></category>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[design-patterns]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:03:18 GMT</pubDate>
            <atom:updated>2018-01-16T23:03:18.447Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><strong>Wrappers and Generics for Everything</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><p>Let’s suppose that I don’t care about how hard others have to work to find the details of my system’s behavior. Let’s say that clarifying my intent through complex structure is my highest goal. Let’s say I decide to go for extreme abstraction. I could do something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6f9c36439d2fe8c91517f5f7e6c7995f/href">https://medium.com/media/6f9c36439d2fe8c91517f5f7e6c7995f/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d69e1fce8ea2afc6920a3a9b144abb98/href">https://medium.com/media/d69e1fce8ea2afc6920a3a9b144abb98/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b5f62fdfa3d8810a7b656d836180805/href">https://medium.com/media/5b5f62fdfa3d8810a7b656d836180805/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/90dd052d0696ed64a213fda755c28dfd/href">https://medium.com/media/90dd052d0696ed64a213fda755c28dfd/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7edc471de30fde78bdd8056a808bc42e/href">https://medium.com/media/7edc471de30fde78bdd8056a808bc42e/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/98d20cb1ac1da59a99bffedd41a3521f/href">https://medium.com/media/98d20cb1ac1da59a99bffedd41a3521f/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0bff1b63f1fbdd64ae686e30ac55cc53/href">https://medium.com/media/0bff1b63f1fbdd64ae686e30ac55cc53/href</a></iframe><h3>Discussion</h3><p>This code is now thoroughly more abstract than it needs to be. ColorMode might become worthwhile some day if we get to a point where we need four or five color values associated with each RunStatus, but this seems highly unlikely. Also, is there really a lot of value in abstracting the transition out of each part of oscillate? This has “solved” a duplication issue of only two elements that were unlikely to change (because they are tied to an external library). And making Model.RunStatus’s setters more generic has improved clarity of intent only marginally while introducing a new parameter to be parsed and understood by readers.</p><p>A little abstraction applied to concrete code initially yielded enormous returns in the form of duplication removal and readability. However, this code’s overly complex nature actively degrades its readability.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>We have given names and partitions to all parts of the system in which even the minutest intent was present. <em>Why</em> we have the code that we do (our intent) is utterly clear.</li></ul><h4>Cons</h4><ul><li>Learning simple concepts within the system requires learning about an enormous number of relationships between partitioned chunks of code. Some of these partitions have nothing to do with either utility or domain concerns.</li><li>Discovering implementation details (the <em>what</em>) is time-consuming and involves mental contortions in order to hold the structure of the system in mind. This is necessary for even the simplest of operations.</li><li>The relationships between various parts of the system, which initially started to improve as we added abstraction, have now degraded. This heavily abstract system is as unclear as the heavily concrete system in terms of how the parts of the system relate to one another.</li></ul><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Abstraction in Elm: Conclusion</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4f54313d1a83" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Domain-Based Modularization]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/91145dacbda5</guid>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[abstraction]]></category>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[design-patterns]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:03:08 GMT</pubDate>
            <atom:updated>2018-01-16T23:03:08.972Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><strong>Domain-Based Modularization</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><p>Did you think that we got rid of all the duplication when we introduced local functions? In fact, I intentionally kept a light touch on that first pass. There is still much more we could do.</p><p>In the previous section, we took the functions that were similar in their utility and grouped them into modules, hence the title of “utility-based modularization.” Utility, in this sense, means that we grouped functions together because they operated on similar data structures (RunStatus) or because they described a particular runtime behavior (ColorOscillation).</p><p>There is another kind partitioning that can be useful, and it can help us tease out some of the more subtle forms of duplication: abstraction based on domain.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/71a3ef04f9e36f51f56033d716b110bc/href">https://medium.com/media/71a3ef04f9e36f51f56033d716b110bc/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4222f7c2783018ad89f0e00d1e9367c5/href">https://medium.com/media/4222f7c2783018ad89f0e00d1e9367c5/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/28ec5a45eaf9e2710b478f68e048deb7/href">https://medium.com/media/28ec5a45eaf9e2710b478f68e048deb7/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/64249cf5c9c307f0e9010527b4a276b7/href">https://medium.com/media/64249cf5c9c307f0e9010527b4a276b7/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3f8b03b0e1d118d0f79cb7056b6a2bb9/href">https://medium.com/media/3f8b03b0e1d118d0f79cb7056b6a2bb9/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f62bf78637709ba5ba86c68d32751e4b/href">https://medium.com/media/f62bf78637709ba5ba86c68d32751e4b/href</a></iframe><h3>Discussion</h3><p>In the <em>domain </em>of returning a value from the update function, we need to wrap our model into a tuple with a Cmd. The And module abstracts this behavior and will attract other kinds of Cmds that our system needs to generate (one can imagine And.execute for simple port functionality or And.doSomeOtherBehavior for more complex situations.</p><p>In the <em>domain</em> of making changes to the model, we have four actions in this system, and those seem to belong to two categories. One pair of actions is concerned with making changes to runStatus, while the other is concerned with initiating animation effects. I partitioned these domains by introducing two new modules: Model.RunStatus and Model.Animation.</p><p>On the one hand, this kind of domain-driven partitioning can make the high levels of code extremely descriptive:</p><pre>model<br>    |&gt; Model.RunStatus.setToGeneratingTests<br>    |&gt; Model.Animation.initiateColorOscillation<br>    |&gt; And.doNothing</pre><p>This reads wonderfully: “Take the model, set the run status to ‘generating tests’, then initiate a color oscillation animation, and then complete the update with no additional commands.”</p><p>The other side of this coin is that the specific behavior of this code is more obscure than ever. What do any of these lines of code <em>really do</em>? In order to go find that out, I’m now going to have to examine five other files, and additionally, I’ll have to keep the relationships of those five files to each other and to Main.elm in my head as I go.</p><p>Now, if my system is comprised of thirty message constructors (as Elm Test Runner happens to be at the time of this writing), then this kind of structure can be worth its weight, precisely for that supposed drawback. Think about how you go about understanding a large and complex system. When I first approach such a system, I don’t <em>want</em> to have to figure out how the entire application works in order to make a change to color animations! I just want to understand the color animation sub-system. Even though these pithy lines in main obscure the details, well-crafted partitions can make very large projects easier to comprehend, because they delineate sub-systems, allowing the engineer to learn those sub-systems one at a time.</p><p>This situation is much preferable to a large, low-abstraction software system, in which a sea of details must be waded and sifted for the bits relevant to the sub-system one wants to learn about. In my experience, large, low-abstraction projects are much more difficult to read, comprehend, and make changes to, than are large, high-abstraction projects, but only if the partitions delineate the sub-systems rather than slicing them to pieces.</p><p>Engineers coming to Elm from React, Angular, and Vue will do well to let go of DOM-based components as a default abstraction mechanism, and instead consider the various ways they could partition based on utility and domain in their Elm applications.</p><p>At the same time, the heavy level of abstraction described in this section must be used judiciously and is most useful when a system is so large that no normal human being is ever going to attempt to hold the whole thing in mind at a given moment.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>If we’ve done a good job with our names, then the highest levels of our application (Main) read extraordinarily well.</li><li>It is clearer than ever <em>why</em> the system was constructed the way it was. Intent is approaching crystal clarity.</li></ul><h4>Cons</h4><ul><li>The details of our system, <em>what</em> it specifically does, have become hidden in an expanse of lower-level files.</li><li>Multiple modules must be traversed to get from main to the specific behavior, and an engineer attempting to decipher the system must hold all of those module relationships in their head in order to figure out what’s going on.</li><li>Interestingly, we have begun, once again, to obscure the relationships between various parts of the code. Domain-based partitions cause engineers to have to do extra work in order to form a mental picture of system cohesion.</li><li>High-level readability has also come at the expense of ease-of-reasoning about the system as a whole. (This is mitigated somewhat if we have a very large system. Since it’s impossible for a human being to keep the whole system in mind anyway, having partitions that delineate the sub-systems makes it easier to learn whichever sub-system an engineer is interested in at a given time.)</li></ul><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Abstraction in Elm: Wrappers and Generics for Everything</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=91145dacbda5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Utility-Based Modularization]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/a48cff1d867e</guid>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[abstraction]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[elm-lang]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:03:01 GMT</pubDate>
            <atom:updated>2018-01-16T23:03:01.611Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><strong>Utility-Based Modularization</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><p>In the last section, we saw a lot of benefit from a little bit of abstraction. We introduced a handful of functions, and all of a sudden a bunch of relationships came into focus. Let’s take abstraction a step further and see what happens. Let’s introduce modules.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4594e0c47e8d8d36b3486ed6e3155270/href">https://medium.com/media/4594e0c47e8d8d36b3486ed6e3155270/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/27d6f4d5732f4910866f61c9749369f1/href">https://medium.com/media/27d6f4d5732f4910866f61c9749369f1/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a98e91480db4c4627433847ab343819e/href">https://medium.com/media/a98e91480db4c4627433847ab343819e/href</a></iframe><h3>Discussion</h3><p>In the previous section, we grouped together chunks of intermediate logic and put each one into its own function. In this section, we’ve grouped together functions and put them into separate modules. This act of putting like things together and separating them from unrelated parts of the system is called <em>partitioning</em>.</p><p>What do these new partitions get us?</p><p>Some would argue that this particular partitioning is superficial. And, for a chunk of code that was originally only forty lines, I would agree that this indeed seems to be more abstraction than is strictly necessary for a code sample of this size. However, most programs do not remain a mere forty lines for very long.</p><p>File-level partitioning abstractions (modules in Elm, classes in object-oriented languages) serve another important purpose that often goes unremarked, both in object-oriented and functional paradigms. Such abstractions act as “behavior attractors,” as Corey Haines describes in his book <a href="https://leanpub.com/4rulesofsimpledesign"><em>Understanding the Four Rules of Simple Design</em></a>. The idea is that a well-considered partition acts as a magnet for new behaviors that “belong” conceptually inside its boundaries.</p><p>In the example above, say I need a new function that converts any given RunStatus to a display string. In the early examples, I would just throw that function in any old where, and maybe I wouldn’t even bother to wrap that behavior in a function. With my partitions in place, it is clear to anyone using this system that such behavior belongs in the RunStatus module.</p><p>Building a team attitude of always searching out the right partitions for the job makes everyone’s lives easier, because the placement and integration of new functionality will be both obvious and simple. In the extremely concrete systems we saw at the very beginning of this article, a new feature could be placed trivially, but correct integration of that behavior would be significantly more cumbersome.</p><p>The downside of this level of abstraction should be obvious. In our previous section, we introduced a level of indirection that caused us to go searching the <em>file</em> for other <em>functions</em>. In this section, we introduced a new level of indirection. Now, when seeing an unfamiliar symbol, we may additionally have to go searching our <em>project</em> for other <em>files</em>.</p><p>We can now see a pattern emerging. Every step we take in using structure to clarify <em>why </em>our code is the way it is, comes at the cost of another form of clarity: that of <em>what</em> the application specifically does.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>Logical groups of functions, called modules in Elm, add increased clarity as to <em>why </em>our code is the way it is, and what its intended behavior is.</li><li>Modules act as behavior attractors, making it easier to fit new features into the system (assuming the partitions are well-drawn).</li><li>Relationships between the various parts of the code are clearer than ever, as we now have two tiers of partitions (functions and modules) that distinguish code as being more or less related to other parts of the system.</li></ul><h4>Cons</h4><ul><li>The ease of discovery of <em>what</em> our code does has taken another hit. It is no longer possible to find out everything a program does by looking at a single file. When encountering an unknown symbol, the module it belongs to must be identified, found, opened, and scanned before we can know how it works.</li></ul><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Abstraction in Elm: Domain-Based Modularization</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a48cff1d867e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Introduce Local Functions]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/cd1ad9689521</guid>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[abstraction]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:02:55 GMT</pubDate>
            <atom:updated>2018-01-16T23:02:55.062Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><strong>Introduce Local Functions</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0794701ec55b465b2e1f92cc6c0e9076/href">https://medium.com/media/0794701ec55b465b2e1f92cc6c0e9076/href</a></iframe><h3>Discussion</h3><p>This code demonstrates a refactor in which many portions of the monolithic expression have been reorganized into separate functions. We are no longer living in a world of a single mega-function, but rather many small functions that each serve a discrete purpose.</p><p>What effects have these changes had?</p><p>The first and most obvious effect is the obliteration of the duplication present in both of the previous code examples. If I want to change the duration of the fade effect in the oscillation, I can now change it in one place and the entire system is affected. If I want to add a third animation transition to the oscillation and have it affect all oscillations in the system, there is one place to do that.</p><p>But the removal of duplication is not the only positive effect. This code communicates its intent at least as well as the comment method. But, unlike the comment method, the intent is baked into the structure of the code. In order to change that intent, an engineer will have to restructure the code in some new way, and they will be beholden to the compiler.</p><p>In addition, all these new functions we’ve added come with names, and those names provide additional contextual clues. If an engineer starts to make a change that violates the intent, a good name can give them pause to reconsider their change’s effect on the system.</p><p>And finally, we have created a new situation in our case statement that wasn’t possible before. Look how small it is compared to previous incarnations. And not only is it smaller, but examine how it reads: statusBarColorStyle = colorOscillation GeneratingTests model.statusBarColorStyle. If I am coming to this code for the first time, and I see this line, I know immediately, after reading only five discrete symbols, that this code likely starts a color oscillation effect on the status bar, based on the current status of GeneratingTests. This was not possible with our previous code. In order to arrive at this same conclusion in previous examples, we had to carefully read eleven full lines of code and probably also compare those eleven lines to other parts of our system just to be sure.</p><p>There is one downside, and it is non-trivial. In order to find out <em>the details </em>of how the colorOscillation works, the engineer has to go searching for its definition.</p><p>By introducing this abstraction, we’ve made our intent both clear and resilient to accidental change, but at the cost of making some of the details of our system harder to find.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>The duplication has been eliminated.</li><li>It is clearer <em>why </em>the code is the way it is, and it is difficult to change the code behavior independently of this communication.</li><li>Relationships between different portions of code are clearer as well.</li></ul><h4>Cons</h4><ul><li>We have slightly obscured <em>what </em>the code does. This is because we have introduced a small amount of indirection. Upon seeing colorOscillation for the first time, an engineer must go searching for its definition in order to discover how it works.</li></ul><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Abstraction in Elm: Utility-Based Modularization</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cd1ad9689521" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Introduce Comments]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/77e69d98c3ca</guid>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[abstraction]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:02:45 GMT</pubDate>
            <atom:updated>2018-01-16T23:02:45.814Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><strong>Introduce Comments</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a5830f2341f9da25ce2e411e982b5e5f/href">https://medium.com/media/a5830f2341f9da25ce2e411e982b5e5f/href</a></iframe><h3>Discussion</h3><p>It has been suggested that commenting is an appropriate mechanism for making code relationships clear. In some senses, commenting does the job. It can no longer be said that this code is completely ambiguous. The author’s intent is now clear, and the relationship between the run status and the animation is apparent as well.</p><p>However, I tend to call this level of abstraction (if that is an even appropriate term) “superficial abstraction.” There are two reasons for this. Comments do not address duplication, and they are highly prone to becoming stale.</p><p>Let’s suppose that, in the above code, I want to make a change to the duration of the color oscillation effect. With the current structure (which, to be clear, is the same as the previous example — utterly concrete), I must go searching for all instances of setting duration in a color oscillation and update them all individually. The rampant duplication is still a major problem. I can understand the code’s intent, but making changes remains cumbersome and error-prone.</p><p>The problems become more severe if I have a large team. Because comments have no impact on the compiler or the execution of the compiled software, it is possible to change the software’s behavior to do something other than what the comments say it does. When comments are the abstraction pattern of choice, engineers who change the code must remember to change both the source code <em>and </em>the associated comments. As the system grows more complex, comments may come to describe parts of the code that are not in their immediate vicinity (such as line 46 above). An engineer is unlikely to go searching through the code to find all the comments they have affected with a change to the code’s behavior, and the compiler will not be able to stop them. Comments such as these inevitably become lies, and when that happens, ambiguity will return in full force.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>There is zero ambiguity in terms of <em>what</em> is being executed.</li><li>Comments provide a simple way to clarify <em>why </em>the code is doing what it’s doing.</li><li>Relationships between various portions of the code are now clear.</li></ul><h4>Cons</h4><ul><li>The clarity of the <em>why</em> and the relationships are contingent upon engineers maintaining the cohesion of the code’s behavior and all associated comments with every change they make. As a system grows larger, comments will start to refer to parts of the code further and further from their own location, and dissolution becomes inevitable. At this point, the relationships and the <em>why</em> will become as muddled as having no abstraction at all.</li></ul><p>Continue to Abstraction in <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Elm: Introduce Local Functions</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=77e69d98c3ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: One Expression to Rule Them All]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/957726f3ad5a</guid>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[elm]]></category>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[abstraction]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:02:39 GMT</pubDate>
            <atom:updated>2018-01-16T23:02:39.629Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba">Introduction</a></li><li><strong>One Expression to Rule Them All</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Code</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4649dc08fd9ee09aee9ce2be0ccfffb4/href">https://medium.com/media/4649dc08fd9ee09aee9ce2be0ccfffb4/href</a></iframe><h3>Discussion</h3><p>Above are two branches of a case statement inside <a href="https://github.com/mbuscemi/elm-test-runner">Elm Test Runner</a>’s update function. However, I have adjusted the code to be as concrete as it can possibly be. I have removed all abstractions, save for those coming from an external library (<a href="https://github.com/mdgriffith/elm-style-animation">elm-style-animation</a>).</p><p>This code is very direct. It tells us exactly what it does, and it tells us all of what it does in one single chunk of one single file. However, at only forty lines, it is already, in some senses, “too much to grok.” runStatus is being set to Processing, and this is perhaps mostly clear. But what is the relationship between these particular status changes and the bar color being interrupted and looped in an animation? Why is the duration of each part of each loop 660? Can I change one duration number and not the others? And what are those color values for? Why are they all different?</p><p>And this is only forty lines. What if it were six hundred? If one were completely new to this code, it would take quite a while to work through all those lines and figure out why each and every detail does what it does. We would have to run the application, observe the behavior, and try to correlate it to various parts of the expression. All of this work would be made exponentially harder by the fact that, lacking any structure, it is unclear how any one part of our single mega-function relates to any other part.</p><p>To make matters even worse, this method of perfect concreteness is highly susceptible to duplication. In only forty lines, this code already manifests numerous duplicate structures. This is a side effect of our desire to have no abstraction — we must explicitly declare each function invocation with its specific parameters.</p><h3>Analysis</h3><h4>Pros</h4><ul><li>The code does exactly what it says it does. There is zero ambiguity in terms of <em>what</em> is being executed.</li></ul><h4>Cons</h4><ul><li>This code lacks any information as to <em>why</em> any part of it is the way it is. Engineer intent is highly obscure.</li><li>Relationships between various portions of the function are unclear. As the code grows linearly, this becomes exponentially more problematic.</li><li>Duplication is inevitable.</li></ul><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Abstraction in Elm: Introduce Comments</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=957726f3ad5a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abstraction in Elm: Introduction]]></title>
            <link>https://medium.com/@matthew.buscemi/abstraction-in-elm-introduction-db0922bde3ba?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/db0922bde3ba</guid>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[abstraction]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[elm]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Tue, 16 Jan 2018 23:02:33 GMT</pubDate>
            <atom:updated>2018-01-16T23:02:33.191Z</atom:updated>
            <content:encoded><![CDATA[<h3>Table of Contents</h3><ol><li><strong>Introduction</strong></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">One Expression to Rule Them All</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-comments-77e69d98c3ca">Introduce Comments</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-introduce-local-functions-cd1ad9689521">Introduce Local Functions</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-utility-based-modularization-a48cff1d867e">Utility-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-domain-based-modularization-91145dacbda5">Domain-Based Modularization</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-wrappers-and-generics-for-everything-4f54313d1a83">Wrappers and Generics for Everything</a></li><li><a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-conclusion-6ea7adcf398e">Conclusion</a></li></ol><h3>Why Should We Care about Abstraction in Elm?</h3><p>One of the largest challenges facing the Elm community today is creating an environment where React, Angular, and Vue engineers feel comfortable trying Elm, both as a language and a framework, while at the same time coercing them away from the “component-based design” abstraction pattern that React, Angular, and Vue have taught them. While necessary in order to work with those frameworks, it’s an unnecessary impediment when working with Elm.</p><p>The heavy push to discourage reliance on the component abstraction pattern is a good one, but it has also, in my opinion, led to some questionable conclusions. Notable examples would be Evan Czaplicki’s recommendation in “The Life of a File” <a href="https://www.youtube.com/watch?v=XpDsk374LDE&amp;t=6m30s">that engineers not think about abstraction in Elm until a file is six-hundred lines long</a>. I have also witnessed numerous instances in Elm Slack of community members discouraging abstraction outright, even making claims to the effect that “all abstraction obscures clarity.”</p><p>In this series, I will show that abstraction is not necessarily bad. Its effect on our code can vary enormously depending on the context and manner of its application. To demonstrate this, I will take two branches of an Elm case statement and take them from their most concrete state possible to their most abstract state possible, and I’ll talk about the effects that each of the changes has.</p><p>I will show that the phrase “all abstraction obscures clarity” is only half-true. Abstraction does decrease clarity of <em>details</em> (<em>what</em> our code actually does), but it also increases clarity of <em>intent </em>(<em>why</em> our code does what it does). Our goal when coding should be neither to maximize clarity of detail nor clarity of intent, for both strategies are fraught with significant drawbacks. We should instead optimize for <em>clarity of relationships</em> by using abstraction to draw meaningful partitions between various portions of our application. This can only be achieved if we correctly balance concreteness and abstraction when building our software.</p><p>Continue to <a href="https://medium.com/@matthew.buscemi/abstraction-in-elm-one-expression-to-rule-them-all-957726f3ad5a">Abstraction in Elm: One Expression to Rule Them All</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db0922bde3ba" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Elm Lens v0.3 Released]]></title>
            <link>https://medium.com/@matthew.buscemi/elm-lens-v0-3-released-6eeab7201c83?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/6eeab7201c83</guid>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[atom]]></category>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[elm]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Sun, 14 Jan 2018 00:53:21 GMT</pubDate>
            <atom:updated>2018-01-14T00:53:21.022Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O-AYDSb-v1T0Z9tcLDNAmA.png" /><figcaption>The Elm Lens Plugin Settings</figcaption></figure><p>Elm Lens 0.3 is out today! In this release, I’ve introduced the settings panel. You can reach the settings panel for Elm Lens by opening Atom preferences, clicking on “Packages” in the sidebar, then clicking the “Settings” button on the Elm Lens package.</p><p>You can now toggle off individual pieces of the Elm Lens markup, if you decide you’d rather be without them. You can also adjust the opacity of the markup, if you’d rather it be less pronounced than the rest of your code.</p><p>Additionally, you can quickly toggle all of the display control checkboxes on and off with Ctrl-L.</p><p>There are a few other improvements in this release. Those of you who have been seeing weird square icons where the loading spinner and warning flag should be, should now see those icons correctly. Also, external references from unqualified imports should now be counted correctly.</p><p>But, let’s have a word about unqualified imports…</p><h3>The Problem with Unqualified Imports</h3><p>Way back in my early software engineering days, I became enamored of a feature in PHP that I thought was really cool. I discovered that you could configure the language to go looking for a class file auto-magically whenever you invoked its name with new. This allowed me to forego having to write a require statement for each class dependency at the top of my files. I could just new anything anywhere I wanted and PHP magic handled the rest.</p><p>As I gained more experience, I reached the inevitable conclusion: this feature was making my code worse. The convenience of not having to think about what I was newing and where made me prone to dependency clusters and less likely to think about my partitioning strategy.</p><p>Elm doesn’t have a lot of the troublesome baggage of PHP, but it does have dependencies. While there is no magic in Elm that will tell the compiler to import whole modules for you based on references, there is a syntax that allows you to leave out the specification for what you’re importing.</p><p>Instead of doing:</p><p>import ModuleA exposing (ModuleA, blarg, frangle)</p><p>It is possible to do this:</p><p>import ModuleA exposing (..)</p><p>This will import everything that’s exposed in ModuleA. From a dependency perspective, this is not great for your code. It means that if ModuleB imports ModuleA in this way, then it is potentially importing symbols that it doesn’t use. If I forget that ModuleB imports ModuleA in this way, I can add a ton of exposed functions to it, which will increase the coupling to ModuleB in a non-obvious way. It also creates a readability issue. In order to figure out which symbols in ModuleB come from ModuleA, I either have to comment out the import and see what breaks, or I have to go scan ModuleB. It would be better just to declare the imports explicitly.</p><p>I want Elm Lens to show you the right information about your dependencies, regardless of how your import statements are structured. However, you will get better performance with Elm Lens, and, I’m convinced, better code, if you declare your dependencies explicitly. I’ve found this principle to be true in any language with an import syntax (which is the vast majority of them). Explicit imports always end up paying back their cost in typing time and then some.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6eeab7201c83" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Elm Lens v0.2 Released]]></title>
            <link>https://medium.com/@matthew.buscemi/elm-lens-v0-2-released-97db1c92d07e?source=rss-7ebc64b27fde------2</link>
            <guid isPermaLink="false">https://medium.com/p/97db1c92d07e</guid>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[elm-lang]]></category>
            <category><![CDATA[atom]]></category>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[elm]]></category>
            <dc:creator><![CDATA[Matthew Buscemi]]></dc:creator>
            <pubDate>Thu, 04 Jan 2018 11:06:34 GMT</pubDate>
            <atom:updated>2018-01-04T11:06:34.558Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K_Y4hV3hHq093DQIXlM-zg.png" /><figcaption>Elm Lens v0.2.0 Introduces the Reference Panel</figcaption></figure><p>Elm Lens’s initial functionality introduced contextual markup for individual functions. Two out of three pieces of that metadata concerned references: places that the function in question got called. <a href="https://medium.com/@matthew.buscemi/introducing-elm-lens-2d21e05d95">Elm Lens 0.1</a> showed you <em>how many</em> references each function had, but there was no way to see details of those references or quickly navigate to them.</p><p>Elm Lens 0.2 changes that. Now, when you click on the phrase “n internal references” or “n external references,” a detailed list of references displays in the new references panel at the bottom of the editor. Clicking on a reference in the panel will navigate the editor to the file and location of the reference.</p><p>You can get the new functionality by upgrading <a href="https://atom.io/packages/elm-lens">Elm Lens</a> to the most recent version in Atom. If you haven’t tried Elm Lens yet, now’s a great time to check it out.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=97db1c92d07e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>