<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="29516" data-post-id="29516">
  <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="gon782" data-post="51" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/eada6e/48.png" class="avatar"> gon782:</div>
<blockquote>
<p>This is largely the reason no one seems to be using Mnesia, as well. It’s odd, because it’s such a great resource to have and use out of the box. People won’t use it even when what they have is generally perfect for it. I think it stems from records being something Elixir programmers generally know nothing about and all they know is “they’re bad” even though they’ve never had to work with them and so they don’t even know what’s bad about them (the syntax, that’s all). This, coupled with that no one in the core team seems to ever mention Mnesia, means that it’s something people don’t even consider.</p>
</blockquote>
</aside>
<p>Wait what?  Records are bad?  Since when?  I use them quite heavily!  They give the same ‘structural static typing’ that Elixir Structs do, but since they are tuples underneath they are a ‘little bit’ faster until they start getting too large.  ^.^</p>
<p>Although in my opinion it is safer to let Struct’s ‘leak out’ from your module definitions then it is to let Records leak out, for various reasons.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29516" data-batch-url="/posts/batch_likers">
                        0
                      </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/discussion-about-uses-for-agent-processes/4214/52">Post #51</a>
	                </div>
	            </div>
              <div id="likers-container-29516" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29516"
                     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 #51"></div>
  </section>
</div>
    <div class="postbit" id="29517" data-post-id="29517">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="gon782" data-post="51" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/eada6e/48.png" class="avatar"> gon782:</div>
<blockquote>
<p>This is largely the reason no one seems to be using Mnesia, as well.</p>
</blockquote>
</aside>
<p>The reason no one is using <code>:mnesia</code> is because its netsplit story is “deal with it manually”. Sure there’s <a href="https://github.com/uwiger/unsplit" class="inline-onebox" rel="nofollow">GitHub - uwiger/unsplit: Resolves conflicts in Mnesia after network splits · GitHub</a> but you’ve gotta pick your functions wisely to avoid data loss. This is hardly a beginner subject, and there’s zero beginner oriented literature on the matter.</p>
<p><code>:mnesia</code> needs an <code>Mnesia in Anger</code> book that goes through all the gotchas that can happen, appropriate ways to manage them, and so on. Without that it’s simply too perilous as a beginner to use as a primary data store of anything, and if you don’t need it as a primary data store you can probably just get by with <code>:ets</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29517" 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/discussion-about-uses-for-agent-processes/4214/53">Post #52</a>
	                </div>
	            </div>
              <div id="likers-container-29517" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29517"
                     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 #52"></div>
  </section>
</div>
    <div class="postbit" id="29521" data-post-id="29521">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is mostly entirely a non-issue, since as a beginner you have absolutely nothing you could conceivably lose from this. Nothing is going to come for free and the whole Elixir community sticking its collective head in the sand won’t make them understand when and how to use Mnesia.</p>
<p>No one is (hopefully) creating important production systems in languages and with technologies they don’t know enough about. When not doing important production systems considerations like these are pointless and only serve for procrastination.</p>
<p>If you want to say that Mnesia is simply bad, that’s another story. But the beginner argument is just a non-starter.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29521" 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/discussion-about-uses-for-agent-processes/4214/54">Post #53</a>
	                </div>
	            </div>
              <div id="likers-container-29521" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29521"
                     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 #53"></div>
  </section>
</div>
    <div class="postbit" id="29523" data-post-id="29523">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="sasajuric" data-post="47" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I agree with this as long as there is some notable difference in complexity between correct and fast. For a k-v, here’s how it looks with Agents:</p>
<p>{:ok, pid} = Agent.start_link(fn -&gt; %{} end)<br>
Agent.update(pid, &amp;Map.put(&amp;1, :foo, :bar))<br>
Agent.get(pid, &amp;Map.get(&amp;1, :foo))</p>
<p>and this is how it looks with ETS:</p>
<p>ets = :ets.new(:table_name, <span class="chcklst-box fa fa-square-o"></span>)<br>
:ets.insert(ets, {:foo, :bar})<br>
:ets.lookup(ets, :foo)</p>
<p>In terms of code complexity these are mostly similar.</p>
</blockquote>
</aside>
<p>Those are <strong>very</strong> different in terms of code complexity. Sure, in terms of characters is about the same, but reasoning about them is very very very different. If data is shared across multiple processes, who creates the ETS? How to reason about failures with your ETS table? What about race conditions?</p>
<p>I completely understand that some would rather introduce GenServer directly and skip Agents, but starting out with ETS is asking for trouble unless you know what you are doing. If people are having trouble with the functional mindset and they think they need to use mutable state, then I would a thousand times prefer them to use an Agent rather than ETS.</p>
<p>It reminds me of Joe Armstrong saying “you shouldn’t use GenServer, you should start from scratch”. That’s a great advice from Joe to Robert or Mike but I certainly won’t be doing it.</p>
<p>For learning purposes, I find the Agent a very natural step to teach developers how to think about processes and data boundaries. What is part of the client and what is part of the server. I also prefer them when reading my code too. In my experience, when teaching them, the Agent clicks much faster than a GenServer.</p>
<p>Maybe they are more likely to be misused exactly because they are much easier to grasp? It is probably a topic where the documentation and guides could reflect on.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29523" 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/discussion-about-uses-for-agent-processes/4214/55">Post #54</a>
	                </div>
	            </div>
              <div id="likers-container-29523" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29523"
                     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 #54"></div>
  </section>
</div>
    <div class="postbit" id="29526" data-post-id="29526">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="gon782" data-post="54" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/eada6e/48.png" class="avatar"> gon782:</div>
<blockquote>
<p>the whole Elixir community sticking its collective head in the sand won’t make them understand when and how to use Mnesia.</p>
</blockquote>
</aside>
<p>This is a caricature of what I’m arguing for. I’m providing reasons why introductory material does not generally present <code>:mnesia</code> as an  option, and instead opts for genservers / ets for local node work, and traditional databases (ecto / postgres) for persistent data. I am not arguing that the “whole Elixir community” ought not to look at <code>:mnesia</code> at all, the two arguments are not the same thing.</p>
<aside class="quote no-group" data-username="gon782" data-post="54" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/eada6e/48.png" class="avatar"> gon782:</div>
<blockquote>
<p>If you want to say that Mnesia is simply bad, that’s another story. But the beginner argument is just a non-starter.</p>
</blockquote>
</aside>
<p>I’m not necessarily saying that it’s bad at everything, but it does have very distinct limits that make it difficult to use. Distributed databases in general are exceptionally difficult to operate, even by experts in the field (see any blog post involving Jepsen). Mnesia takes one of the most difficult parts of distributed database management, netsplit healing, and as best I can tell basically just throws up its hands and tells you to fix it yourself.</p>
<aside class="quote no-group" data-username="gon782" data-post="54" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/eada6e/48.png" class="avatar"> gon782:</div>
<blockquote>
<p>No one is (hopefully) creating important production systems in languages and with technologies they don’t know enough about.</p>
</blockquote>
</aside>
<p>Of course. However, many people come to Elixir looking to learn stuff that, once they become more familiar, they can in fact use in production. I’m arguing that the bar for using mnesia in production is much, much higher than GenServers, :ets, Postgres, and so forth, and so it shouldn’t be much of a surprise that material aimed at getting people up to speed with Elixir doesn’t feature <code>:mnesia</code> prominently.</p>
<p>Don’t get me wrong, I would LOVE to see a well written book on using :mnesia that covers this kind of information, but without a focused and detailed walk through of doing so I’m not really sure what the value of having folks use it in a merely cursory manner is.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29526" data-batch-url="/posts/batch_likers">
                        0
                      </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/discussion-about-uses-for-agent-processes/4214/56">Post #55</a>
	                </div>
	            </div>
              <div id="likers-container-29526" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29526"
                     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 #55"></div>
  </section>
</div>
    <div class="postbit" id="29538" data-post-id="29538">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>For learning purposes, I find the Agent a very natural step to teach developers how to think about processes and data boundaries. What is part of the client and what is part of the server. I also prefer them when reading my code too. In my experience, when teaching them, the Agent clicks much faster than a GenServer.</p>
</blockquote>
</aside>
<p>I think then, that it’s important to emphasise that one of their main purposes is to be a teaching tool, rather than a core piece of the Elixir infrastructure that you should construct your codebase out of. I do agree that when I was starting out, considering Agents first allowed the actual messaging model to sink in before I had to worry how callbacks and behaviours worked.</p>
<aside class="quote no-group" data-username="benwilson512" data-post="56" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/48/1457_2.png" class="avatar"> benwilson512:</div>
<blockquote>
<p>However, many people come to Elixir looking to learn stuff that, once they become more familiar, they can in fact use in production.</p>
</blockquote>
</aside>
<p>I am one of the people at the stage where I feel I have a very good grasp on the “basics” of Elixir / OTP, which is what the literature seems to focus on. I have a couple of simple, non-critical apps in production. I know how processes and supervision trees and releases and applications and clusters work. However I definitely feel frustrated by the lack of literature which covers more advanced topics and how and when you should actually deploy these more advanced tools like ETS or Mnesia when dealing with “real” systems, and the gotchas and caveats that apply.</p>
<p>I did breeze through the introductory material—most likely because I had already been exposed to functional programming as well as traditional “formal” concurrency models like CSP—and I feel like I’ve suddenly hit a wall in terms of further learning; for now the only way forward has been to push forward, make my own mistakes and learn from them (often with the help of the wonderful community here).</p>
<p>I think that if we want to encourage more people without an Erlang background to actually build non-trivial, production apps which take advantage of the power of OTP, and not just treat it as an interesting and powerful language, but only for side projects, this space definitely needs to be developed some more.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29538" 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/discussion-about-uses-for-agent-processes/4214/57">Post #56</a>
	                </div>
	            </div>
              <div id="likers-container-29538" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29538"
                     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 #56"></div>
  </section>
</div>
    <div class="postbit" id="29556" data-post-id="29556">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Those are very different in terms of code complexity. Sure, in terms of characters is about the same, but reasoning about them is very very very different. If data is shared across multiple processes, who creates the ETS? How to reason about failures with your ETS table? What about race conditions?</p>
</blockquote>
</aside>
<p>Not sure I understand the problem here. The same questions you raise apply to agents as well.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>but starting out with ETS is asking for trouble unless you know what you are doing</p>
</blockquote>
</aside>
<p>No disagreements there <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> The same thing IMO also holds for processes, especially for the cases where Agents are misused where plain in-proc data structure would work just fine.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>If people are having trouble with the functional mindset and they think they need to use mutable state, then I would a thousand times prefer them to use an Agent rather than ETS.</p>
</blockquote>
</aside>
<p>My point about starting out with ETS was about “simple” shared data, such as k-v. The word “simple” here is pretty vague, but mechanically speaking it is about atomic guarantees of ETS. If I need to keep some shared in-memory data (say some kind of a cache), and ETS supports that scenario (e.g. for simple key-based lookups and writes), then I go immediately for ETS.</p>
<p>Misusing ETS to bypass FP is as bad as doing it with Agents. I’m guilty of both sins in the past, so my position is based on my own experience <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>For learning purposes, I find the Agent a very natural step to teach developers how to think about processes and data boundaries.</p>
</blockquote>
</aside>
<p>There’s no denying that Agents are easy to grasp. I’m not sure though how well do they work in explaining process boundaries. Because of their simple usage, the fact that data is being passed across processes is maybe not as clear as with GenServer, where you explicitly need to invoke cast or call, which is perhaps a stronger indication that something is being sent to another process.</p>
<p>Maybe I’m too used to the “old ways” of teaching, but IMO the bottom up approach of explaining plain spawns with message passing, followed by teaching GenServer is much more explicit about what goes on. It takes more time, yes, but I believe it is more geared toward idiomatic ways and deeper understanding.</p>
<p>Also, speaking of the learning curve, I personally don’t think spawning, message passing, and GenServer are hard concepts to learn. As someone who came to Erlang with OO background (Ruby, C#, C++) I had no problem learning those. I struggled more with getting used to FP, understanding how to organize supervision trees, and properly produce OTP releases. Therefore, if it comes to learning advantages, I wonder if Agent is solving a problem which is not so huge in the first place. I’m not saying Agents are not helping, but I don’t think they’re helping that much.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Maybe they are more likely to be misused exactly because they are much easier to grasp?</p>
</blockquote>
</aside>
<p>That’s precisely my sentiment! Given that, and what I said above, I’m not really sure that Agent pulls enough weight. In fact, I sometimes wonder if it muddies the water more than it helps. Over years I’ve repeatedly seen newcomers wondering should they use Agent or GenServer. And then there are a bunch of misuse examples, with agents being used where plain in-proc struct would work.</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="55" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>It is probably a topic where the documentation and guides could reflect on.</p>
</blockquote>
</aside>
<p>That would be a good idea, yes.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29556" data-batch-url="/posts/batch_likers">
                        3
                      </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/discussion-about-uses-for-agent-processes/4214/58">Post #57</a>
	                </div>
	            </div>
              <div id="likers-container-29556" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29556"
                     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 #57"></div>
  </section>
</div>
    <div class="postbit" id="29617" data-post-id="29617">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mjadczak" data-post="57" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mjadczak/48/3537_2.png" class="avatar"> mjadczak:</div>
<blockquote>
<p>I think then, that it’s important to emphasise that one of their main purposes is to be a teaching tool, rather than a core piece of the Elixir infrastructure that you should construct your codebase out of.</p>
</blockquote>
</aside>
<p>Except I don’t agree with this. It is not what I said. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> As I mentioned in my earlier replies, I find the Agent usage clearer when it fits and I do use it in different applications such as Mix and Ecto.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29617" data-batch-url="/posts/batch_likers">
                        0
                      </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/discussion-about-uses-for-agent-processes/4214/59">Post #58</a>
	                </div>
	            </div>
              <div id="likers-container-29617" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29617"
                     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 #58"></div>
  </section>
</div>
    <div class="postbit" id="29618" data-post-id="29618">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="58" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Not sure I understand the problem here. The same questions you raise apply to agents as well.</p>
</blockquote>
</aside>
<p>Sure. But you learn how to reason about processes much earlier than you do with ETS.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="58" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I’m not sure though how well do they work in explaining process boundaries. Because of their simple usage, the fact that data is being passed across processes is maybe not as clear as with GenServer</p>
</blockquote>
</aside>
<p>I agree with the data copying. By process boundary, I meant to explain “what happens in the client and what happens in the server”. With agent it is visually in the same function, like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def do_something do
  # client
  Agent.put(..., fn -&gt; # server end)
end
</code></pre>
<p>and I think that helps drive the point that process execution is orthogonal to code layout. With the GenServer, you end-up with functions and callbacks all at the same level and that is neither here nor there. It would probably be clearer if we wrote client and server modules instead (but I am not quite proposing that).</p>
<aside class="quote no-group" data-username="sasajuric" data-post="58" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Maybe I’m too used to the “old ways” of teaching, but IMO the bottom up approach of explaining plain spawns with message passing, followed by teaching GenServer is much more explicit about what goes on.</p>
</blockquote>
</aside>
<p>Using agents and such approaches are probably complimentary. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="sasajuric" data-post="58" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Also, speaking of the learning curve, I personally don’t think spawning, message passing, and GenServer are hard concepts to learn. As someone who came to Erlang with OO background (Ruby, C#, C++) I had no problem learning those.</p>
</blockquote>
</aside>
<p>That’s interesting because spawning and message passing was quite straight-forward but a GenServer took me quite some time to master (especially in understand all of the trade-offs regarding call, cast, termination, etc). So it definitely throws a lot at you upfront. I guess that’s the point though, different people are going to get stuck at different places, and different paths are likely helpful.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="58" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>That’s precisely my sentiment! Given that, and what I said above, I’m not really sure that Agent pulls enough weight. In fact, I sometimes wonder if it muddies the water more than it helps.</p>
</blockquote>
</aside>
<p>Here is something that just came to my mind: if we didn’t have agents, those folks would likely end-up just using the process dictionary, because that’s what happens in Erlang to a certain extend. And I am not quite sure if that is better or worse.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29618" 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/discussion-about-uses-for-agent-processes/4214/60">Post #59</a>
	                </div>
	            </div>
              <div id="likers-container-29618" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29618"
                     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 #59"></div>
  </section>
</div>
    <div class="postbit" id="29619" data-post-id="29619">
  <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 group-livebook_core_team" data-username="josevalim" data-post="60" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>That’s interesting because spawning and message passing was quite straight-forward but a GenServer took me quite some time to master (especially in understand all of the trade-offs regarding call, cast, termination, etc). So it definitely throws a lot at you upfront. I guess that’s the point though, different people are going to get stuck at different places, and different paths are likely helpful.</p>
</blockquote>
</aside>
<p>Huh, I had no issues with GenServer either when I hit erlang a decade ago, and I was heavy C++ for over a decade by then.  Call’s have reply messages.  Casts are fire-and-forget.  Etc… etc…  It all seemed pretty obvious?</p>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="60" data-topic="4214">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Here is something that just came to my mind: if we didn’t have agents, those folks would likely end-up just using the process dictionary, because that’s what happens in Erlang to a certain extend. And I am not quite sure if that is better or worse.</p>
</blockquote>
</aside>
<p>If they can use the process dictionary at all then they should <em>not</em> be using agents and instead should be threading their state through their process calls, like they are ‘already’ doing with the Agents PID.  This does not seem like a use case for agents at all to me?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29619" data-batch-url="/posts/batch_likers">
                        0
                      </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/discussion-about-uses-for-agent-processes/4214/61">Post #60</a>
	                </div>
	            </div>
              <div id="likers-container-29619" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29619"
                     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 #60"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/4214/load_more?page=7">Load more posts (16 remaining)</a>
</div></template></turbo-stream>