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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>we’ve deviated considerably from the main point, but I don’t think it’s bikeshedding and helping people craft clear code is important enough to merit discussion.</p>
<p>In the specific example you gave, I think if you’re creating a work function in a module called Accept.List, it probably shouldn’t take “nil” as a parameter defensively.  It should only take lists.  Already from how it’s been coded I can tell that the upstream caller is using get inappropriately and should instead be using, fetch! or fetch function instead.  Understandably, not everyone follows these naming conventions, naming is hard and even I screw this up… a lot… in my private code, and periodically i have to go thorough and clean them up.  Fetch is too tempting a name to refer to “going some long distance and getting data” instead of “this returns error/ok tuples”, but I do also think that respecting conventions is important.</p>
<p><em>if</em> you have a function that can emit nil, you should probably be <em>immediately</em> consuming it in something that can deal with nils, and usually something that comes from stdlib/stdlib adjacent, so if, cond, to_string, List.wrap.  Phoenix.HTMLSafe, etc.</p>
<p>For example, this is a pattern I use a lot:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Enum.flat_map(list_of_selected_keys, &amp;List.wrap(if value = Map.get(map, &amp;1), do: value))
</code></pre>
<p>That one could be a matter of taste because you can certainly do a filter on the list of selected keys, noting that the filter alternative does result in you potentially iterating through the list of keys twice.</p>
<p>But the one that is hard is when you have a cond:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">cond do
  attempt1 = get_from_source_1(key) -&gt; attempt1
  attempt2 = get_from_source_2(key) -&gt; attempt2
  attempt3 = get_from_source_3(key) -&gt; attempt3
  ...
end
</code></pre>
<p>I somewhat dislike doing a reverse with, which is the most legible alternative:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  with :error &lt;- fetch_from_source_1(key),
         :error &lt;- fetch_from_source_2(key)
  ...
  else
   {:ok, result} -&gt; result
  end
</code></pre>
<p>I think it is a good thing to be used to reading railroad code as a list of successes.  I find that reading over code that I myself wrote where I have a reverse with, even though I <em>always</em> put a comment warning me that this with statement is a reverse with, will still cause my brain to trip up and have to recontextualize, so I have stopped writing reverse withs.</p>
<p>There’s another List.wrap example</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">developing_list = [...] ++
  List.wrap(if must_be_2nd_last = Keyword.get(opts, :foo), do: must_be_2nd_last) ++
  List.wrap(if must_be_last = Keyword.get(opts, :bar), do: must_be_last)
</code></pre>
<p>if you only had one, you could do it pretty easily with a case statement and Keyword.fetch, avoiding nils, but it gets hairy with more than 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="286713" 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/conditional-piping-part-of-the-language/55524/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-286713" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286713"
                     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 #21"></div>
  </section>
</div>
    <div class="postbit" id="286717" data-post-id="286717">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="ityonemo" data-post="22" data-topic="55524">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ityonemo/48/11341_2.png" class="avatar"> ityonemo:</div>
<blockquote>
<p><code>Enum.flat_map(list_of_selected_keys, &amp;List.wrap(if value = Map.get(map, &amp;1), do: value))</code></p>
</blockquote>
</aside>
<p>Why not this?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Enum.flat_map(list_of_selected_keys, &amp;Map.get(map, &amp;1, []))
</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="286717" 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/conditional-piping-part-of-the-language/55524/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-286717" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286717"
                     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 #22"></div>
  </section>
</div>
    <div class="postbit" id="286745" data-post-id="286745">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/derek-zhou" rel="nofollow">@derek-zhou</a> It’s interesting you can do that but very unintuitive if you ask me. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" loading="lazy" width="20" height="20"><br>
Btw, you can probably simplify the <code>quote</code> expression like this:<br>
<code>unquote(name) = unquote(value) || unquote(name)</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="286745" 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/conditional-piping-part-of-the-language/55524/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-286745" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286745"
                     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 #23"></div>
  </section>
</div>
    <div class="postbit" id="286747" data-post-id="286747">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="ityonemo" data-post="22" data-topic="55524">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ityonemo/48/11341_2.png" class="avatar"> ityonemo:</div>
<blockquote>
<p>There’s another List.wrap example</p>
</blockquote>
</aside>
<p>I don’t wanna get involved in the sidetracked discussion, but I was curious what your example would look like with the <code>then?/3</code> macro:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">[]
|&gt; then?(must_be_2nd_last = opts[:foo], &amp;[must_be_2nd_last | &amp;1])
|&gt; then?(must_be_last = opts[:bar], &amp;[must_be_last | &amp;1])
</code></pre>
<p>vs.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">developing_list = [...] ++
  List.wrap(if must_be_2nd_last = Keyword.get(opts, :foo), do: must_be_2nd_last) ++
  List.wrap(if must_be_last = Keyword.get(opts, :bar), do: must_be_last)
</code></pre>
<p>The <code>then?</code> version looks way more readable and cleaner to me. What do you think?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286747" 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/conditional-piping-part-of-the-language/55524/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-286747" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286747"
                     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 #24"></div>
  </section>
</div>
    <div class="postbit" id="286754" data-post-id="286754">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m looking at the code that I have and actually it’s this, no need for if, silly me:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Enum.flat_map(..., &amp;List.wrap(Map.get(map, &amp;1))
</code></pre>
<p>You need the List wrap, because flat_map needs to have the lambda return lists.</p>
<p>For the <code>++ List.wrap...</code> example, if you use cons operator, the order will be wrong.  This is something I use when, e.g. building AST because the order of those lists matters a lot.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286754" 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/conditional-piping-part-of-the-language/55524/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-286754" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286754"
                     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 #25"></div>
  </section>
</div>
    <div class="postbit" id="286755" data-post-id="286755">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Not the same (list order). I prefer:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">developing_list = List.flatten([
[...],
List.wrap(Keyword.get(opts, :foo)),
List.wrap(Keyword.get(opts, :bar))
])
</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="286755" 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/conditional-piping-part-of-the-language/55524/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-286755" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286755"
                     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 #26"></div>
  </section>
</div>
    <div class="postbit" id="286756" data-post-id="286756">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="ityonemo" data-post="26" data-topic="55524">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ityonemo/48/11341_2.png" class="avatar"> ityonemo:</div>
<blockquote>
<p>For the <code>++ List.wrap...</code> example, if you use cons operator, the order will be wrong. This is something I use when, e.g. building AST because the order of those lists matters a lot.</p>
</blockquote>
</aside>
<p>I see. In that case <code>|&gt; Enum.reverse()</code> at the end would be enough, right?</p>
<aside class="quote no-group quote-modified" data-username="derek-zhou" data-post="27" data-topic="55524">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/derek-zhou/48/19943_2.png" class="avatar"> derek-zhou:</div>
<blockquote>
<p>Not the same (list order). I prefer:<br>
…</p>
</blockquote>
</aside>
<p>Also a possible solution. <img src="https://forum.elixirforum.com/images/emoji/apple/+1.png?v=15" title=":+1:" class="emoji" alt=":+1:" 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="286756" 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/conditional-piping-part-of-the-language/55524/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-286756" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286756"
                     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 #27"></div>
  </section>
</div>
    <div class="postbit" id="286868" data-post-id="286868">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Wanting a dedicated conditional pipe construct still feels like a smell to me.  I could be wrong, of course!  Does anyone have any concrete examples (ie, that aren’t speaking abstractly and using identifiers like <code>foo</code> and <code>condition</code>)?</p>
<p>Stuff I come across:</p>
<p>I often have a <code>:preload</code> option in my context functions that make db calls:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def list_posts(opts \\ []) do
  preload = Keyword.get(opts, :preload, [])

  Post
  |&gt; Repo.all()
  |&gt; Repo.preload(preload)
end
</code></pre>
<p>Passing an empty list to <code>Repo.preload</code> is a a no-op so the conditional just lives in <code>Keyword.get/3</code>.</p>
<p>Another thing would be filters in which case I use a reduce which gives me a reusable, pipeable filter function:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def apply_filters(query, filters) do
  Enum.reduce(filters, query, fn filter, query_acc -&gt;
    case filter do
      {:limit, limit} -&gt;
        from q in query_acc, limit: ^limit

      {:order_by, order_by} -&gt;
        from q in query_acc, order_by: ^order_by

      # etc...
    end
  end)
end
</code></pre>
<p>Better yet I just use <a href="https://hexdocs.pm/flop" rel="noopener nofollow ugc">Flop</a>.  Maybe possibly likely I should be using <a href="https://ash-hq.org/" rel="noopener nofollow ugc">Ash</a> but I still haven’t made the leap.</p>
<p>Recently I came across the situation where I have forms with nested children and they require at least one child, so only when there are no children yet, I want to show an empty field to the user.  Again, I make a generic, reusable function:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def maybe_build_assoc(changeset, key, assoc_struct) do
  if get_assoc(changeset, key) == [] do
    put_assoc(changeset, key, [assoc_struct])
  else
    changeset
  end
end
</code></pre>
<p>The last example seems to be the sticking point.  I do agree that the <code>if thing, do: transform(thing), else: thing</code> is a little clunky, but it lives tucked away in a helper file that I barely look at and when I do, it’s very nice and explicit.</p>
<p>My examples are, of course, heavily Ecto-y and I’m just wondering where a conditional pipe would shine as I’ve personally never even thought about needing one.</p>
<p>Otherwise I do like <a class="mention" href="/u/aziz" rel="nofollow">@aziz</a>’s <code>then?</code> example expect that I would call it <code>maybe_then</code>.  While it does read surprisingly nicely with the <code>?</code>, <code>?</code> functions in Elixir conventionally return booleans.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286868" 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/conditional-piping-part-of-the-language/55524/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-286868" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286868"
                     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 #28"></div>
  </section>
</div>
    <div class="postbit" id="286873" data-post-id="286873">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I never bought into the whole conventions thing e.g. <code>?</code> and <code>!</code>. What matters most is what your team finds convenient. <img src="https://forum.elixirforum.com/images/emoji/apple/person_shrugging.png?v=15" title=":person_shrugging:" class="emoji" alt=":person_shrugging:" loading="lazy" width="20" height="20"> In most Elixir project I was in there was no mindset of “our project can raise” or “our project must NEVER raise” so we kind of knew the default by heart and this was not enforced with syntax conventions.</p>
<p>RE: naming, I’d prefer <code>maybe_then</code> as well, it conveys 100% of what it [could] do right in the name because you should know what <code>Kernel.then</code> does and then prepending <code>maybe_</code> to it makes it clear what you can expect.</p>
<p>A not-super-on-topic example is this Rust code that I wrote a few years ago:</p>
<pre data-code-wrap="rust"><code class="lang-rust">pub fn time_from_millis(timestamp: i64) -&gt; Option&lt;DateTime&lt;Utc&gt;&gt; {
    if timestamp == 0i64 {
        None
    } else {
        Some(Utc.timestamp(timestamp / 1_000, ((timestamp % 1_000) * 1_000_000) as u32))
    }
}

// ...
order.received_time.and_then(time_from_millis)
</code></pre>
<p>…which, if you know Rust, basically says “fetch this field that could be <code>None</code> (non-existing) but if it does exist, invoke this function on the value and return it; if not, return <code>None</code>” i.e. fallible chains of actions where short-circuiting does not require boilerplate. You can have a chain of 20 transformers but if something at step 3 returns an <code>Err</code> or <code>None</code> value, it will just fall through and you don’t have to do anything else except just having your <code>.and_then</code> and other fallible functions strung together.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286873" 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/conditional-piping-part-of-the-language/55524/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-286873" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286873"
                     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 #29"></div>
  </section>
</div>
    <div class="postbit" id="286876" data-post-id="286876">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I find the idea of “this function can raise” rather silly, because 90% of your code can raise and I bet most people don’t see pattern matching in function heads as a source of FunctionClauseExceptions and don’t add a <code>!</code> to them. I also don’t like to “color” my functions that way, it gets super messy when it taints all the callers and it’s not clear what you gain with that. I’d rather reserve the <code>!</code> for the cases where you explicitly <code>raise</code> by providing a custom error message, or when you also provide an alternative non-bang function</p>
<p>On topic: I’ve seen helpers like <code>tap_if_ok</code>, <code>do_if</code>, etc, and I have no issue with that at all. Since it’s something conventional, I like that being implemented in userland rather in elixir itself, neither elixir nor erlang impose a particular structure to the atom or the number of tuples in the result tuple to make it viable to add such constructs to the language itself, in my opinion.</p>
<p>Maybe something that would make more sense to me would be this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Utils do
  defmacro match(data, pattern, do: block) do
    quote location: :keep do
      case unquote(data) do
        unquote(pattern) -&gt; unquote(block)
        other -&gt; other
      end
    end
  end
end
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir">import Utils

42
|&gt; do_something()
|&gt; match {:ok, val} do
  val
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="286876" 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/conditional-piping-part-of-the-language/55524/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-286876" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286876"
                     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 #30"></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/55524/load_more?page=4">Load more posts (15 remaining)</a>
</div></template></turbo-stream>