<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="40708" data-post-id="40708">
  <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="svarlet" data-post="11" data-topic="6743" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/svarlet/48/10907_2.png" class="avatar"> svarlet:</div>
<blockquote>
<p><a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> so instead of drowning in validations, you would just code the happy path and crash for all players of this party?</p>
</blockquote>
</aside>
<p>Crash back to the wrapper, which then returns the original untouched state and the error.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40708" 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/whats-your-approach-to-domain-modelling/6743/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-40708" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40708"
                     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="40712" data-post-id="40712">
  <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>What about using tuples as a poor man’s <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Either.html" rel="noopener nofollow ugc">Either</a>, returning an error tuple in a catch all function clause and using the approach you described <a href="https://forum.elixirforum.com/t/type-and-spec-dialyzer-not-detecting-error/6608/10" rel="nofollow">here</a>?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40712" 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/whats-your-approach-to-domain-modelling/6743/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-40712" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40712"
                     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="40713" data-post-id="40713">
  <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">
								<p>Exactly.  <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="40713" 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/whats-your-approach-to-domain-modelling/6743/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-40713" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40713"
                     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="40784" data-post-id="40784">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="svarlet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/svarlet/120/10907_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  svarlet
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for recommending <code>Exceptional</code>. I already had a look at it not so long ago but without context I didn’t give it enough importance.</p>
<p>That helped me quite a bit this time and put on a better track too. Essentially, I refactored a bit my code from something like this:</p>
<pre><code>def user_action(state, param) do
  cond do
    validate_param() -&gt;
      {:error, :reason1}
    validate_state() -&gt;
      {:error, :reason2}
    ...
    true -&gt;
      # the actual logic
end
</code></pre>
<p>to</p>
<pre><code>def user_action(state, param) do
  param
  |&gt; validate_param()
  ~&gt; validate_state()
  ~&gt; do_user_action()
end
</code></pre>
<p>where <code>validate_xxx</code> function return either the param unchanged or an exception (return, not raise). You could say that it’s not much but the code is much more readable that way. Validators are defined as simple functions and I can now define them outside my module if I need to.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40784" 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/whats-your-approach-to-domain-modelling/6743/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-40784" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40784"
                     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="40794" data-post-id="40794">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="svarlet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/svarlet/120/10907_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  svarlet
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Now, back to the original topic, what is your usual approach: top down, bottom up? do you represent everything with structs?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40794" 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/whats-your-approach-to-domain-modelling/6743/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-40794" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40794"
                     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="40809" data-post-id="40809">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Qqwy" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Qqwy/120/1349_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Qqwy
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>TypeCheck Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="svarlet" data-post="16" data-topic="6743" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/svarlet/48/10907_2.png" class="avatar"> svarlet:</div>
<blockquote>
<p>Now, back to the original topic, what is your usual approach: top down, bottom up? do you represent everything with structs?</p>
</blockquote>
</aside>
<p>Top-down and bottom-up both work well, and in practice which one I pick depends on the problem (and often I sort of do both at the same time and <a href="http://i.dailymail.co.uk/i/pix/2016/10/09/15/393DE57E00000578-0-image-a-60_1476025005744.jpg" rel="noopener nofollow ugc">meet in the middle</a>).<br>
I do <em>not</em> represent everything with structs. In this example, I’d define a <code>%Card{}</code> (with a suit and a rank), a <code>%Player{}</code> (with the amount of money bet thus far, their hand and possibly some other meta-info to link it to an external user) and a <code>%Game{}</code> (which is the high-level State Machine representation, containing a queue of players, the current round of the game, the shuffled deck of hidden cards, and the visible cards that form the street/river or what it is called again in Poker).</p>
<p>Most other things are either atoms (as “poor man’s sum types”) or integers.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40809" 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/whats-your-approach-to-domain-modelling/6743/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-40809" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40809"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="40834" data-post-id="40834">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve had decent success with a module per state and module-defined state, managed by (in this case) a <code>GenServer</code> that basically just forwards calls to <code>state.current_state_module.do_something(state.module_state)</code>. For example, my <a href="https://github.com/cdegroot/palapa/tree/master/apps/erix/lib/erix/server" rel="noopener nofollow ugc">Raft library</a> has a module for “Leader”, “Follower” and “Candidate” and functions <code>transition_from</code> in each one to handle state transitions (with pattern matching on the old state - there is no <code>transition_from(:follower, ...)</code> in the Leader module so that’s automatically an invalid state transition.</p>
<p>It’s simple to test (I usually want to write code in a mix of top-down and bottom-up, mostly guided by tests).</p>
<p>(also, I need to write log compaction for that library so I can call it mostly done ;-))</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="40834" 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/whats-your-approach-to-domain-modelling/6743/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-40834" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="40834"
                     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>