<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="61441" data-post-id="61441">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Jim" data-post="11" data-topic="10730" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/j/ac91a4/48.png" class="avatar"> Jim:</div>
<blockquote>
<p>Elixir Best Practices: When to Use Structs, String-keyed Maps, and Atom-keyed Maps</p>
</blockquote>
</aside>
<p>Link doesn’t load, certificate is invalid.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61441" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-61441" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61441"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="61444" data-post-id="61444">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="NobbZ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/NobbZ/120/27235_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  NobbZ
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="12" data-topic="10730">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>Link doesn’t load, certificate is invalid.</p>
</blockquote>
</aside>
<p>It is not, indeed, but you can bypass the check, then the link loads, for reading some content I feel OK with that, I’d not submit anything via a form or so to them, also I deactivated JS for in-secure (meaning invalid, untrusted or expired certificates) HTTPS resources.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61444" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-61444" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61444"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="61445" data-post-id="61445">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="peerreynders" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/peerreynders/120/5826_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  peerreynders
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>A (slow) web archive link for the squeamish</p><aside class="onebox allowlistedgeneric" data-onebox-src="https://web.archive.org/web/20160709171333/https://engineering.appcues.com/2016/02/02/too-many-dicts.html">
  <header class="source">

      <a href="https://web.archive.org/web/20160709171333/https://engineering.appcues.com/2016/02/02/too-many-dicts.html" target="_blank" rel="noopener nofollow ugc">Appcues Engineering Blog</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://web.archive.org/web/20160709171333/https://engineering.appcues.com/2016/02/02/too-many-dicts.html" target="_blank" rel="noopener nofollow ugc">Elixir Best Practices: When to Use Structs, String-keyed Maps, and Atom-keyed...</a></h3>

  <p>Elixir, much like its foundation language Erlang and its syntactic muse
Ruby, makes a distinction between character strings, like</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61445" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-61445" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61445"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="61448" data-post-id="61448">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="NobbZ" data-post="13" data-topic="10730">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nobbz/48/27235_2.png" class="avatar"> NobbZ:</div>
<blockquote>
<p>It is not, indeed, but you can bypass the check, then the link loads, for reading some content I feel OK with that</p>
</blockquote>
</aside>
<p>Actually I cannot, my work has the policies setup so websites must be https and invalid certificates cannot be overridden.  ^.^;</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61448" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-61448" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61448"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="61456" data-post-id="61456">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="NobbZ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/NobbZ/120/27235_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  NobbZ
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Oh, yeah, company networks can get in the way sometimes.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61456" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-61456" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61456"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="61527" data-post-id="61527">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Jim" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Jim
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="15" data-topic="10730">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>Actually I cannot, my work has the policies setup so websites must be https and invalid certificates cannot be overridden.  ^.^;</p>
</blockquote>
</aside>
<p>Sorry about that, although it’s not my site. It’s worth bypassing for the read, maybe when you’re at home or using your phone or something.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61527" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-61527" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61527"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="63237" data-post-id="63237">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="irfan.aloha" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/irfan.aloha/120/7797_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  irfan.aloha
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The use of correct Data Structure is depends upon requirement.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="63237" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-63237" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="63237"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="174048" data-post-id="174048">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lkuty" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lkuty/120/34879_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lkuty
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Copy/pasted here for reference. I hope it doesn’t break any rule of ToS or copyright. If it does, feel free to remove the post or ask me to do it.</p>
<h1><a name="p-174048-elixir-best-practices-when-to-use-structs-string-keyed-maps-and-atom-keyed-maps-1" class="anchor" href="#p-174048-elixir-best-practices-when-to-use-structs-string-keyed-maps-and-atom-keyed-maps-1" aria-label="Heading link" rel="nofollow"></a>Elixir Best Practices: When to Use Structs, String-keyed Maps, and Atom-keyed Maps</h1>
<p>Feb 2, 2016 • Pete Gamache</p>
<p>Elixir, much like its foundation language Erlang and its syntactic muse Ruby, makes a distinction between <em>character strings</em> , like <code>"hi_mom"</code> , and <em>atoms</em> , like <code>:hi_mom</code> .</p>
<p>Elixir also offers several ways to pass around key-value data. There’s <a href="https://web.archive.org/web/20160709171333/http://elixir-lang.org/docs/v1.1/elixir/Map.html" rel="noopener nofollow ugc">Map</a>, whose keys can be either keys or atoms; <a href="https://web.archive.org/web/20160709171333/http://elixir-lang.org/docs/v1.1/elixir/Keyword.html" rel="noopener nofollow ugc">Keyword</a> lists, which are <a href="https://web.archive.org/web/20160709171333/https://en.wikipedia.org/wiki/Association_list" rel="noopener nofollow ugc">association lists</a> (or <em>alists</em> ) consisting of <code>{atom, any_value}</code> tuples; and there are association lists of <code>{string, any_value}</code> tuples, such as the HTTP headers returned by <a href="https://web.archive.org/web/20160709171333/https://hexdocs.pm/plug/Plug.Conn.html" rel="noopener nofollow ugc">Plug.Conn.req_headers</a>.</p>
<p>Elixir <a href="https://web.archive.org/web/20160709171333/http://elixir-lang.org/getting-started/structs.html" rel="noopener nofollow ugc">structs</a> are represented as Maps with atom keys, additionally restricting the user to a predefined set of keys, and allowing a shorter syntax for field access than non-struct Maps.</p>
<p>Maps (and structs) and keyword lists implement the Elixir <a href="https://web.archive.org/web/20160709171333/http://elixir-lang.org/docs/v1.1/elixir/Dict.html" rel="noopener nofollow ugc">Dict</a> behaviour, whereas the string-keyed alist does not.</p>
<p>Given that these different data structures are not compatible, the programmer must choose which to use at any given place in an application’s code. But how? This is the source of frustration and confusion in noobs and greybeards alike.</p>
<p>In this post, we explore the right times to use each.</p>
<h2><a name="p-174048-about-atoms-and-strings-2" class="anchor" href="#p-174048-about-atoms-and-strings-2" aria-label="Heading link" rel="nofollow"></a>About Atoms and Strings</h2>
<p>Atoms (called “symbols” in Ruby and Lisp, among others) are much like integers; they are <a href="https://web.archive.org/web/20160709171333/http://elixir-lang.org/getting-started/basic-types.html#atoms" rel="noopener nofollow ugc">constants where their name is their own value</a>. Importantly, <strong>atoms are not garbage-collected</strong> , so allocating them at runtime can lead to RAM exhaustion over time.</p>
<p>Atoms are also the “preferred” keys for maps and dicts; this is to say, the Elixir language provides syntactic sugar to encourage their use. Writing <code>%{a: 1}</code> is shorter than the equivalent <code>%{:a =&gt; 1}</code> and shorter still than the string-keyed version <code>%{"a" =&gt; 1}</code> .</p>
<p>Strings are the same character strings you find in most languages: the same string can be allocated multiple times, and strings are GCed alongside other data. There is no penalty to using strings as map or dict keys, but there is a slight friction to doing so, so many programmers tend to use symbols as map keys as a default instead.</p>
<h2><a name="p-174048-rule-1-always-use-string-keyed-maps-for-external-data-3" class="anchor" href="#p-174048-rule-1-always-use-string-keyed-maps-for-external-data-3" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#1:</span> Always Use String-Keyed Maps for External Data</h2>
<p>Data which comes from outside your application, broadly speaking, can’t be trusted. Given that atom allocation can lead to memory exhaustion in a long-running Erlang system, using atoms for external data opens up your app for a potential denial of service (DoS) attack.</p>
<p>This fact is reflected in many Elixir libraries, for example the popular JSON parser <a href="https://web.archive.org/web/20160709171333/https://github.com/devinus/poison" rel="noopener nofollow ugc">Poison</a>. Well-behaved libraries will generally use strings as map keys when converting external data into an internal data structure. We recommend the same.</p>
<h2><a name="p-174048-rule-2-convert-external-data-to-structs-asap-4" class="anchor" href="#p-174048-rule-2-convert-external-data-to-structs-asap-4" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#2:</span> Convert External Data to Structs ASAP</h2>
<p>Elixir structs have some attractive properties. They enforce a (weak) schema on your application data, so that code may rely on the structure that the model struct provides. Like other atom-keyed maps, they allow access to the member values using dot notation; e.g., <code>some_struct.foo</code> rather than the equivalent <code>some_struct[:foo]</code> .</p>
<p>Structs enforce that you aren’t cramming in non-schematic data, discouraging you from reverting to the “freeform bags of data” mindset. And they are easy to specify in pattern matches in function definitions or case statements, to add a bit of runtime type safety to code.</p>
<p>The basic approach to this procedure is to define a model module with a struct inside it, then write a function to create and populate a struct with a map of externally-sourced data. This is a better idea than scattering code to populate the structs around your code; it’s more DRY and allows you to make changes in one place and test across the board.</p>
<p>Appcues has released a Hex project called <a href="https://web.archive.org/web/20160709171333/https://github.com/appcues/exconstructor" rel="noopener nofollow ugc">ExConstructor</a> to aid in this process. ExConstructor automatically builds constructor functions for structs, handling map-vs-dict, string-vs-atom, and even camelCase-vs-under_score key format automatically. Using ExConstructor means that your code may never have to use string-keyed maps directly.</p>
<h2><a name="p-174048-rule-3-use-structs-in-all-other-code-5" class="anchor" href="#p-174048-rule-3-use-structs-in-all-other-code-5" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#3:</span> Use Structs in All Other Code</h2>
<p>If code in your app uses data which originated from the outside world, and it’s not the one piece of code dedicated to converting that type of data into a struct, it should be explicitly written against the model structs.</p>
<p>Write function definitions which make it clear that struct input is required:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def some_func(input) do ...               # no
def some_func(%{}=input) do ...           # no
def some_func(%MyStruct{}=input) do ...   # yes
</code></pre>
<p>Structs provide guarantees. Guarantees strengthen your code by removing the need for pervasive error/anomaly checking. This leads to better code in less time.</p>
<p>Note: Phoenix/Ecto models are simply structs with some nice features around changesets. Using them across your app is encouraged, though it’s wise to decouple the database access from the rest of your app, perhaps using a data access object, if there is any chance you may move to a different database backend.</p>
<h2><a name="p-174048-rule-4-use-structs-for-output-data-6" class="anchor" href="#p-174048-rule-4-use-structs-for-output-data-6" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#4:</span> Use Structs for Output Data</h2>
<p>Using structs for output data is a good idea for the same reasons that using it internally is a good idea: guarantees, DRY, and, well, structure.</p>
<p>Structs convert to JSON maps quite easily, through either <code>Map.from_struct/1</code> , or custom solutions like <code>@derive [Poison.Encoder]</code> .</p>
<h2><a name="p-174048-rule-5-avoid-using-atom-keyed-maps-that-arent-structs-7" class="anchor" href="#p-174048-rule-5-avoid-using-atom-keyed-maps-that-arent-structs-7" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#5:</span> Avoid Using Atom-keyed Maps That Aren’t Structs</h2>
<p>Using a plain map for passing data around your app may be convenient to write the first time, but over the lifecycle of an app, it leads to decreased expressivity and more confusion about the exact shape of the data at any given point. Creating structs to represent state, even state completely internal to a module, reduces this confusion by plainly advertising (and enforcing) the structure of the underlying data.</p>
<p>There will be times to use plain maps, of course, but if your code has more bare maps than model structs, this may be an indication that your app’s state objects should be better-defined.</p>
<p>When you do use them, don’t fight the language; use atoms as keys.</p>
<h2><a name="p-174048-rule-6-use-keyword-lists-only-for-function-arguments-8" class="anchor" href="#p-174048-rule-6-use-keyword-lists-only-for-function-arguments-8" aria-label="Heading link" rel="nofollow"></a>Rule <span class="hashtag-raw">#6:</span> Use Keyword Lists Only for Function Arguments</h2>
<p>Keyword lists are the idiomatic Elixir way to provide keyword arguments to a function. Since only the programmer should be writing these arguments – <a href="https://web.archive.org/web/20160709171333/https://xkcd.com/327/" rel="noopener nofollow ugc">sanitize your inputs!</a> – atom-related DOS is not a problem.</p>
<h2><a name="p-174048-summary-9" class="anchor" href="#p-174048-summary-9" aria-label="Heading link" rel="nofollow"></a>Summary</h2>
<p>The choice between maps, structs, and keyword lists, or between string keys and atom keys, is not always clear, and improper decisions can lead to headaches.</p>
<p>This article promotes simple guidelines to keep the Elixir programmer out of trouble:</p>
<ul>
<li>Use string-keyed maps for data which has just arrived from an external source.
<ul>
<li>Convert external data to structs as soon as possible.</li>
<li>Use <a href="https://web.archive.org/web/20160709171333/https://github.com/appcues/exconstructor" rel="noopener nofollow ugc">ExConstructor</a> or something similar to abstract away the handling of string-keyed maps.</li>
</ul>
</li>
<li>Use structs almost everywhere else in your program.</li>
<li>Use other atom-keyed maps sparingly.</li>
<li>Use keyword lists only to provide arguments to a function.</li>
</ul>
<p>These rules of thumb have improved the quality of our code here at Appcues, and we hope they can help you out too.</p>
<p><em>Thanks to <a href="https://web.archive.org/web/20160709171333/https://github.com/montague" rel="noopener nofollow ugc">Ian Asaff</a> for reading drafts of this post.</em></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="174048" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-174048" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="174048"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
    <div class="postbit" id="234795" data-post-id="234795">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="IvanR" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/IvanR/120/25095_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  IvanR
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>In support of <code>Rule #2: Convert External Data to Structs ASAP</code>, here are two libraries to try:</p>
<ol>
<li>
<p><a href="https://hexdocs.pm/nestru/" rel="noopener nofollow ugc">Nestru</a> - serializes between nested structs and maps, relating like Book - Order - LineItem. It provides a hook for mapping string keys of any syntax to struct’s fields. Furthermore, it supports serialization of type dependant fields when the map’s key points to a value of one or another struct kind.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/domo/" rel="noopener nofollow ugc">Domo</a> - not only adds a constructor function to a struct module but also makes it validate the data to match the type spec of the struct. These are <code>new!/1</code>, <code>new/1</code>, <code>esure_type!/1</code>, <code>ensure_type/1</code> functions.</p>
</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="234795" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/when-to-use-which-data-structure/10730/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-234795" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234795"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>