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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>i see, so once i know elixir and phoenix, this book will be the next step.. should I also know OTP and Erlang before this book?</p>
<p>How come this book doesn’t cover elixir 1.4 and phoenix 1.3?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29375" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/56">Post #55</a>
	                </div>
	            </div>
              <div id="likers-container-29375" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29375"
                     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="29377" data-post-id="29377">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Definitely you don’t need to know Erlang to follow this book. I don’t know Erlang and I had no problem at all following the book. After all it is an elixir book <img src="https://forum.elixirforum.com/images/emoji/apple/laughing.png?v=15" title=":laughing:" class="emoji" alt=":laughing:" loading="lazy" width="20" height="20">.</p>
<p>You also don’t need to know OTP. This is one of the things this book will teach you.</p>
<blockquote>
<p>How come this book doesn’t cover elixir 1.4 and phoenix 1.3?</p>
</blockquote>
<p>The book is still in beta. Who knows in what ways the author will change it until the final release.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29377" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/57">Post #56</a>
	                </div>
	            </div>
              <div id="likers-container-29377" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29377"
                     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="29416" data-post-id="29416">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29416" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/58">Post #57</a>
	                </div>
	            </div>
              <div id="likers-container-29416" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29416"
                     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="29537" data-post-id="29537">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lance" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lance
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Functional Web Development with Elixir, OTP, and Phoenix</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for your interest in the book!</p>
<p>I think that if you feel pretty comfortable in Elixir, you’ll be fine. As <a class="mention" href="/u/voger" rel="nofollow">@voger</a> said, we’ll walk you through all the steps, and you’ll learn a good chunk of OTP along the way. The main element of Phoenix that we work with is a channel, and we’ll build that step by step as well.</p>
<p>When the next beta is released, all the code will work with Elixir 1.4.  As things currently stand, for the context of this book, the only thing that will change for Phoenix 1.3 is the pathname to the channel we’ll build and the output of the “tree” command inside a newly generated project. We’ll definitely update those things in an upcoming beta release.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29537" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/59">Post #58</a>
	                </div>
	            </div>
              <div id="likers-container-29537" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29537"
                     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="29539" data-post-id="29539">
  <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">
								<p>I grabbed the book and had a (virtual) leaf through, and I would have two main comments:</p>
<p>First, perhaps I didn’t read the book page properly, but I had the impression going in that this was going to be much more advanced than it was. The PragProg page shows the skill level as “intermediate to expert”, and while I agree that it is not a beginner book, I would not call it expert-level either. By “have previous experience with Phoenix and Elixir” I took “have built complete, if maybe simple, applications with them” rather than “know how the syntax works and how a Phoenix interface is structured”. I think clarifying exactly the target audience of the book may be beneficial.</p>
<p>Second, I take issue with the way that the entire game state is represented in a bunch of processes referring to each other by holding PIDs. I think the best way to say what I mean is to simply refer to <a href="http://theerlangelist.com/article/spawn_or_not" rel="noopener nofollow ugc">this great article by Saša Jurić</a>. The way this is implemented in the book smells really strongly of trying to make Agents behave like objects, which is a common mistake for those moving over from OOP, but should in fact be explicitly called out in a book like this, instead of impliedly encouraged.</p>
<p>I think at a certain point you mentioned that “trying to store the whole game state in a functional tree structure is a recipe for bugs because coordinates can belong to both islands and board and we’d have to update them in both places”. The answer to that problem is to normalise the way you’re storing the coordinate data, so you’re only storing it once. It’s certainly not to make each little piece of your state be a separate process!</p>
<p>As has been discussed many times over on this forum, separate processes should be used when a separate concern, either separate in time or separate in failure domain, is present.</p>
<p>Further, what happens when these processes die? They are all linked it seems, so one failure will take down the entire system. If you insist on using them to model the state, perhaps it is at least an opportune time to put them into a custom Supervisor and use Registry to register them with the coordinate/board they represent?</p>
<p>I’m sure it is not the intention of the book to do so, but while I applaud the decoupled, “Phoenix is not your app” approach, I feel it either itself falls or encourages people to fall into common traps when structuring Elixir apps and modelling their domains therein.</p>
<p>I don’t mean to be too negative—I think the concept of the book is great, and a practical walkthrough of how to build something fun but useful is a great way to convey the concepts, but I also think it’s crucial that the approaches set by the book are 100% defensible (to avoid saying “right”) and push people towards actually using the great many tools Elixir gives us in the way they were designed to be used.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29539" data-batch-url="/posts/batch_likers">
                        17
                      </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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/60">Post #59</a>
	                </div>
	            </div>
              <div id="likers-container-29539" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29539"
                     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="29546" data-post-id="29546">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Good points! I too think it’s much more advanced than I thought, but so far, so good.</p>
<p>One thing that worried me a bit is the absence of tests, on development cyrcle… but I’m sure the author’s purpose was to be more practical. So, the dev should have a good base <em>before</em> reading the book.</p>
<p>As I said, good points of view!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29546" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/61">Post #60</a>
	                </div>
	            </div>
              <div id="likers-container-29546" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29546"
                     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>
    <div class="postbit" id="29589" data-post-id="29589">
  <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="mjadczak" data-post="60" data-topic="4231">
<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 at a certain point you mentioned that “trying to store the whole game state in a functional tree structure is a recipe for bugs because coordinates can belong to both islands and board and we’d have to update them in both places”. The answer to that problem is to normalise the way you’re storing the coordinate data, so you’re only storing it once. It’s certainly not to make each little piece of your state be a separate process!</p>
</blockquote>
</aside>
<p>Absolutely this!  I see this being done wrong in <em>so</em> many places (not just Elixir) in regards to functional design.  Normalize the data so if coords need to be shared then have them share an ‘id’ to a coord in some coord storing table.  I find data-flow and/or (pure) ECS designs <em>fantastic</em> for this (I use these both in C++ <em>heavily</em>).  But they definitely should not be stored in different processes!  That is an entirely wrong abstraction here.</p>
<p>Plus everything else <a class="mention" href="/u/mjadczak" rel="nofollow">@mjadczak</a> 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"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29589" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/62">Post #61</a>
	                </div>
	            </div>
              <div id="likers-container-29589" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29589"
                     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 #61"></div>
  </section>
</div>
    <div class="postbit" id="29645" data-post-id="29645">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is a very good post. This is why I love the Elixir community.</p>
<p>Lance and I are working with some great reviewers to make sure we address this feedback. We’re going to shift the approach for the two chapters in question, the chapter on modeling and the chapter on wrapping the result in OTP.</p>
<p>As a popular book in the community, we want to make sure that the guidance we give is sound.</p>
<p>Thanks again for a great post.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="29645" data-batch-url="/posts/batch_likers">
                        21
                      </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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/63">Post #62</a>
	                </div>
	            </div>
              <div id="likers-container-29645" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="29645"
                     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 #62"></div>
  </section>
</div>
    <div class="postbit" id="30671" data-post-id="30671">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’d love to learn more about using OTP for the business logic in our web apps, but skipping over persistence makes this kind of pointless. Does it at least describe how to hook into the OTP processes to save their state somewhere?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="30671" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/64">Post #63</a>
	                </div>
	            </div>
              <div id="likers-container-30671" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="30671"
                     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 #63"></div>
  </section>
</div>
    <div class="postbit" id="30676" data-post-id="30676">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I still got a lot out of the book, but I agree with you.  Showing how to store the state and regenerate it is the missing piece.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="30676" 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/functional-web-development-with-elixir-otp-and-phoenix-pragprog/4231/65">Post #64</a>
	                </div>
	            </div>
              <div id="likers-container-30676" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="30676"
                     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 #64"></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/4231/load_more?page=7">Load more posts (64 remaining)</a>
</div></template></turbo-stream>