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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<h2><a name="p-328431-chapter-3-1" class="anchor" href="#p-328431-chapter-3-1" aria-label="Heading link" rel="nofollow"></a>Chapter 3</h2>
<p>This was a rather pleasant read. If I hadn’t known about pattern matching, this could have been full of AHA moments and WOWs.</p>
<p>I feel like, if anyone experienced with at least one programming language reads chapter 3 before chapter 2, they wouldn’t have as deteriorated experience as one would think. With a little tweak and assumption, these chapters can be read in any order.</p>
<p>Recursion was well explained. I like to think tail recursion became my second nature if I need to use them (Thanks to Project Euler and 99 Problems back in the days), but I agree with the sidebar on Tail vs Body recursion. I might add an article on this: <a href="https://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html" class="inline-onebox" rel="noopener nofollow ugc">Erlang's Tail Recursion is Not a Silver Bullet</a> as a nice supplementary read.</p>
<p>I wish JavaScript wasn’t used as the initial example for reduce though. It’s not a fault of the book, but a fault with my intolerance of that language.</p>
<p>With my distaste for poorly designed language aside (sorry not sorry), let me add that <code>Enum</code> is one of my favourite modules, in any language. What it (along with its cousins <code>Map</code>, <code>MapSet</code> etc - House of Enumerable) provides never fail to impress me whenever I think about solving problems.</p>
<p>The explanations were fantastic, and the shift to <code>Stream</code> felt natural. My only complain there is that I wanted a bit more piped up examples, but I can understand how the focus is on “Higher Order Functions” and pipes, while it sure feels like it, but really involves macros and overusage of it would shift the focus a little.</p>
<p>The section on <code>Stream</code> deserves a re-read, especially in November when Advent of Code approaches.</p>
<p>I wonder if a few utilities of <code>Enumerable</code> should have been explored in this chapter (i.e. <code>reduce_while</code>, <code>group_by</code> etc), I see especially in Clojure books where they often dedicate a nice summary of useful and thought provoking sequence functions.</p>
<p>All in all, a great chapter that is at par with chapter 2 in terms of foundation building, but a much smaller one.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="328431" data-batch-url="/posts/batch_likers">
                        5
                      </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/elixir-in-action-book-club/63088/52">Post #51</a>
	                </div>
	            </div>
              <div id="likers-container-328431" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328431"
                     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="328502" data-post-id="328502">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Just finished Chapter 3 - I found it to be concise and very well written!</p>
<p>Perhaps the most important line for me was…</p>
<p><em>If an error is raised from inside the guard, it won’t be propagated, and the guard expression will return false.</em></p>
<p>Also, good to read again about Streams - must see if I could/ should work them into my code a bit more.</p>
<p>One more Chapter to go and then onto Part 2 - where the real fun starts <img src="https://forum.elixirforum.com/images/emoji/apple/rocket.png?v=15" title=":rocket:" class="emoji" alt=":rocket:" 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="328502" data-batch-url="/posts/batch_likers">
                        5
                      </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/elixir-in-action-book-club/63088/53">Post #52</a>
	                </div>
	            </div>
              <div id="likers-container-328502" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328502"
                     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="328507" data-post-id="328507">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi AstonJ,</p>
<p>I am interested in this book-club.</p>
<p>Do you meet in person or via video-conference?<br>
Where are you located?</p>
<p>Chrichton</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="328507" 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/elixir-in-action-book-club/63088/54">Post #53</a>
	                </div>
	            </div>
              <div id="likers-container-328507" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328507"
                     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="328534" data-post-id="328534">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Part 2 (and Part 3)!!!</p>
<p>I am going to do extra time and finish up Chapter 4 so I don’t miss out all the great discussions we will be having on those chapters.</p>
<p>I believe true power of this book club will be experienced when that comes!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="328534" 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/elixir-in-action-book-club/63088/55">Post #54</a>
	                </div>
	            </div>
              <div id="likers-container-328534" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328534"
                     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="328546" data-post-id="328546">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="AstonJ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/AstonJ/120/15_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  AstonJ
                    <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">
								<aside class="quote no-group" data-username="Chrichton" data-post="54" data-topic="63088" 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/chrichton/48/34984_2.png" class="avatar"> Chrichton:</div>
<blockquote>
<p>I am interested in this book-club.</p>
<p>Do you meet in person or via video-conference?<br>
Where are you located?</p>
</blockquote>
</aside>
<p>This thread is the meeting place <a class="mention" href="/u/chrichton" rel="nofollow">@Chrichton</a> - this means anyone from any timezone (or skill-level) can take part <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<p>If you’d like to join, just jump right it <img src="https://forum.elixirforum.com/uploads/default/original/2X/a/a1c41c89c299189a3f85edfeb4973563d8bac781.gif?v=15" title=":023:" class="emoji emoji-custom" alt=":023:" 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="328546" 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/elixir-in-action-book-club/63088/56">Post #55</a>
	                </div>
	            </div>
              <div id="likers-container-328546" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328546"
                     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="328584" data-post-id="328584">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I have now read chapter 3. Overall it is another excellent chapter. I only have a few comments.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="43" data-topic="63088">
<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>To some extent I feel the same about chapter 3. For the next edition I’m considering splitting that one into two parts: conditionals and loops, with the loops part getting some more detailed treatment.</p>
</blockquote>
</aside>
<p>Actually, I think it could be cleanly split into three chapters:</p>
<ul>
<li>conditionals and pattern matching</li>
<li>recursion</li>
<li>high-order functions and comprehensions</li>
</ul>
<hr>
<p>The sidebar named “Tail vs. non-tail recursion” contains good advice, but in my opinion it needs some qualifications.</p>
<p>It is true that tail-recursion is over-used, and in many cases body-recursion would work just as well or better than tail-recursion. One reason for the popularity of tail-recursion is that it was usually much more efficient than body-recursion in the original JAM virtual machine. To a lesser degree, that also applies to ancient versions of BEAM.</p>
<p>The advice in the sidebar applies to tasks for which tail-recursion and body-recursion use the same amount of memory and have roughly the same performance. In general, that applies to most functions that return a list.</p>
<p>The advice in the sidebar does not apply to tasks where the tail-recursive implementation runs in constant space, while the body-recursive implementation uses stack space in proportion to the size of the input. There is never a good reason to use body-recursion for such tasks. Generally, such tasks don’t return lists but simpler terms such as integers. Some examples of such tasks are:</p>
<ul>
<li>Calculating the sum of a list of integers (as the <code>sum/1</code> example)</li>
<li>Calculating factorials</li>
<li>Printing a sequence of numbers</li>
</ul>
<p>I think that the distinction between tasks that should always use tail-recursion and for tasks for which there is a choice should be pointed out.</p>
<p>While writing this comment, I started out writing more elaborate rules for when one had a choice of tail-recursion vs body-recursion. I then realized that I could boil it down to this simple rule-of-thumb that should work in most cases:</p>
<blockquote>
<p>If a function returns a single list, it probably doesn’t matter efficiency-wise whether it is implemented using tail-recursion or body-recursion. However, if it returns something else, a tail-recursive implementation is almost always more efficient.</p>
</blockquote>
<hr>
<p>In 3.4.3, High-order functions, there is a lambda for determining whether an integer is odd:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">fn x -&gt; rem(x, 2) == 1 end
</code></pre>
<p>That will not work for negative integers because <code>rem</code> produces a negative result:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(1)&gt; rem(-1, 2)
-1
</code></pre>
<p>Elixir has inherited that behaviour from Erlang, which in turn has inherited it from the <code>%</code> operator in C.</p>
<p>I suggest rewriting the lambda to:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">fn x -&gt; rem(x, 2) != 0 end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="328584" data-batch-url="/posts/batch_likers">
                        11
                      </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/elixir-in-action-book-club/63088/57">Post #56</a>
	                </div>
	            </div>
              <div id="likers-container-328584" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328584"
                     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="328633" data-post-id="328633">
  <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 no-group" data-username="chuggingCoffee" data-post="44" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chuggingcoffee/48/34518_2.png" class="avatar"> chuggingCoffee:</div>
<blockquote>
<p>An arbitrarily sized <strong>what</strong>?</p>
</blockquote>
</aside>
<p>Binary <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"> Somehow the word disappeared from the text <img src="https://forum.elixirforum.com/images/emoji/apple/frowning.png?v=15" title=":frowning:" class="emoji" alt=":frowning:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="juhalehtonen" data-post="51" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/juhalehtonen/48/21791_2.png" class="avatar"> juhalehtonen:</div>
<blockquote>
<p>found it interesting that the book chooses not to showcase the <code>else</code> branch of a <code>with</code> in this introduction. I wonder if this is done to avoid accidentally nudging readers down the path of <a href="https://hexdocs.pm/elixir/code-anti-patterns.html#complex-else-clauses-in-with" rel="noopener nofollow ugc">complex else clauses in with -anti-pattern</a>?</p>
</blockquote>
</aside>
<p>Yeah, that’s basically the reason. There are occasional good cases for <code>else</code> in <code>with</code> (e.g. convert each type of error into <code>:error</code>, e.g. while authenticating), but most of what I’ve seen are abuses of complex <code>else</code> clauses as mentioned in the anti-pattern docs.</p>
<aside class="quote no-group" data-username="code-shoily" data-post="52" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/code-shoily/48/8052_2.png" class="avatar"> code-shoily:</div>
<blockquote>
<p>I wish JavaScript wasn’t used as the initial example for reduce though. It’s not a fault of the book, but a fault with my intolerance of that language.</p>
</blockquote>
</aside>
<p>I used it because it would arguably be understandable to most of the readers.</p>
<aside class="quote no-group" data-username="code-shoily" data-post="52" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/code-shoily/48/8052_2.png" class="avatar"> code-shoily:</div>
<blockquote>
<p>let me add that <code>Enum</code> is one of my favourite modules</p>
</blockquote>
</aside>
<p><code>Enum</code> has some great functions, but what I like even more is how it works with multiple data structures (maps, lists, ranges, …), and how you can make it work with other types (including the ones you don’t own). A bit more on that in chapter 4 <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<aside class="quote group-Erlang-Core-Team" data-username="bjorng" data-post="57" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bjorng/48/13187_2.png" class="avatar"> bjorng:</div>
<blockquote>
<p>The advice in the sidebar does not apply to tasks where the tail-recursive implementation runs in constant space, while the body-recursive implementation uses stack space in proportion to the size of the input.</p>
</blockquote>
</aside>
<p>The advice there aims to be deliberately vague, partially because I didn’t want to go into elaborate discussions, and partially because in practice <code>n</code> is often too small to matter <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"> Another reason is that in my impression many people consider tail to be universally superior to body, so I tried to counter that sentiment. In my experience, the perf diff is often insignificant, and body is often clearer than tail.</p>
<p>That said, your observation about the constant space is great, and I’ll see about rewording and expanding this sidebar in the next edition, or perhaps even turn it into a full paragraph or two.</p>
<aside class="quote group-Erlang-Core-Team" data-username="bjorng" data-post="57" data-topic="63088">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bjorng/48/13187_2.png" class="avatar"> bjorng:</div>
<blockquote>
<p>That will not work for negative integers because <code>rem</code> produces a negative result:</p>
</blockquote>
</aside>
<p>Great catch!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="328633" data-batch-url="/posts/batch_likers">
                        7
                      </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/elixir-in-action-book-club/63088/58">Post #57</a>
	                </div>
	            </div>
              <div id="likers-container-328633" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="328633"
                     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="329542" data-post-id="329542">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve now read chapter 4. (I’ll stop repeating myself by using word “excellent” in the beginning of every post; take it as read.) Here follows my thoughts.</p>
<p>For <code>Fraction</code>, there could be an exercise to make <code>Fraction.add/2</code> construct the smallest possible fraction, and also to implement the other arithmetic operations.</p>
<p>In 4.2, <em>Working with hierarchical data</em>, it is assumed that <em>CRUD</em> is already known to the reader. It wasn’t known to me. The text sort of explains what it means, but it would be easier to read if it were explained up front.</p>
<p>The part about Protocols raises some questions that don’t seem to be answered. It is said that:</p>
<blockquote>
<p>It’s important to notice that the protocol implementation doesn’t need to be part of any module.</p>
</blockquote>
<ul>
<li>
<p>Is there any practical difference between putting an implementation inside or outside a module?</p>
</li>
<li>
<p>What is best praxis for putting a protocol implementation for your own data structure? Inside the module for the data structure? Outside in the same source file? In a separate file?</p>
</li>
</ul>
<p>Perhaps there should be some exercises for Protocols. For example:</p>
<ul>
<li>Implement the <code>Enumerable</code> protocol for <code>TodoList</code>.</li>
<li>Implement the <code>Inspect</code> and <code>String.Chars</code> protocol for <code>Fraction</code>.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="329542" data-batch-url="/posts/batch_likers">
                        8
                      </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/elixir-in-action-book-club/63088/59">Post #58</a>
	                </div>
	            </div>
              <div id="likers-container-329542" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="329542"
                     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="329580" data-post-id="329580">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve just finished Chapter 4. All in all another great Chapter!</p>
<p>I would have appreciated some comparison between Protocols and Behaviours when discussing polymorphism as I’ve previously struggled with the idea of when to use one over the other. But I also understand that Behaviours are discussed later in the book.</p>
<p>Onto Part 2 <img src="https://forum.elixirforum.com/images/emoji/apple/tada.png?v=15" title=":tada:" class="emoji" alt=":tada:" 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="329580" data-batch-url="/posts/batch_likers">
                        5
                      </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/elixir-in-action-book-club/63088/60">Post #59</a>
	                </div>
	            </div>
              <div id="likers-container-329580" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="329580"
                     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="329732" data-post-id="329732">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Chapter 4 done <img src="https://forum.elixirforum.com/images/emoji/apple/white_check_mark.png?v=15" title=":white_check_mark:" class="emoji" alt=":white_check_mark:" loading="lazy" width="20" height="20"></p>
<p>Another great introductory chapter to Elixir. The more I read through the chapters, the more I wish I had read and found the first edition of the book back when I was getting started with Elixir.</p>
<p>I like that MapSets are introduced here, as they’re something that might otherwise be easy to forget, and the unique benefits of MapSets can sometimes help solve certain problems very simply and easily. Similarly, I appreciate that even records gained a mention, even though they’re such a rarely seen (for me!) tool in the Elixir toolbox. Generally, it’s great that these things are brought up at least in passing so that one knows what’s available, even if they were rarely the chosen tool.</p>
<p>I also really appreciated the explanation of how to achieve polymorphism with protocols, as I recall it was one of the more difficult topics to grok back when I first got acquainted with Elixir. Saša does a great way of explaining them in a way that’s easy to understand, and highlights their unique value proposition very well.</p>
<p>How about others, how was your experience through chapter 4? <img src="https://forum.elixirforum.com/images/emoji/apple/eyes.png?v=15" title=":eyes:" class="emoji" alt=":eyes:" 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="329732" 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/elixir-in-action-book-club/63088/61">Post #60</a>
	                </div>
	            </div>
              <div id="likers-container-329732" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="329732"
                     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/63088/load_more?page=7">Load more posts (36 remaining)</a>
</div></template></turbo-stream>