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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/eiji" rel="nofollow">@Eiji</a> true, you could define a generic module that could handle this, however …</p>
<p>With the same argument you would remove all of the shortcut syntax and only have fully qualified function names (no sigels, no `[..|..], …).<br>
Even though it might be worthwhile to have those functions for newbies, it would be very cumbersome for those common cases.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367036" 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/changes-to-the-struct-update-syntax/71232/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-367036" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367036"
                     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="367037" data-post-id="367037">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="adamu" data-post="23" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/adamu/48/31482_2.png" class="avatar"> adamu:</div>
<blockquote>
<p>is there a way to realise that <code>foo</code> is always a <code>Foo</code></p>
</blockquote>
</aside>
<p>Yes and no. Look that depending on how you write the code it may be less obvious:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">user_input
|&gt; Code.eval_string()
|&gt; then(fn {struct, _bindings} -&gt; struct end)
|&gt; then(&amp;apply(SomeModule, :update, [&amp;1])
</code></pre>
<p>This way all compilers and tools would have to parse every string to support it and I guess there are much more cases that makes things like that complex.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367037" 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/changes-to-the-struct-update-syntax/71232/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-367037" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367037"
                     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="367038" data-post-id="367038">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="a-maze-d" data-post="25" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/a-maze-d/48/31720_2.png" class="avatar"> a-maze-d:</div>
<blockquote>
<p>With the same argument you would remove all of the shortcut syntax and only have fully qualified function names (no sigels, no `[..|..], …).</p>
</blockquote>
</aside>
<p>Sigils are macros and that’s off-topic.</p>
<p>We have a functions for them and they’re called <code>hd(list)</code> and <code>tl(list)</code>. Both could be used in pattern-matching instead of syntax notation. <code>[head | tail]</code> notation is for a <code>List</code> and not a sub-type (like structs are for maps), so it’s not the best example here.</p>
<p>Look that by default every struct does not implement access behaviour and there are hex packages to fix that and I wanted to propose something exactly like that i.e. extend the specific <code>struct</code> with the functions that are known well from a <code>Map</code> module (like <code>merge</code>, <code>put</code> or <code>update</code>), but with a help of metaprogramming we can make them more helpful for <code>LSP</code> user, so that the editor could propose the keys based on the oldest known patterns in the language like <code>pattern-matching</code> and <code>spec</code>.</p>
<p>From a <code>credo</code> user perspective this also reduces module dependencies, so that your module does not depend on <code>Map</code> and <code>MyStruct</code>, but only <code>MyStruct</code>. The code is still clear and we don’t lose any editor features.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367038" 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/changes-to-the-struct-update-syntax/71232/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-367038" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367038"
                     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="367045" data-post-id="367045">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Slightly off topic, but personally I believe the best practice is to have all structure mutations encapsulated in the respective functions and then invoke those functions from outside of the structure module (instead of updating the structure directly), e.g</p>
<p>ideally:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Foo do
  defstruct [ :a, :b]

  def update_a( foo, updater) do
    Map.update!( foo, :a, updater)
  end

  def update_b( foo, updater) do
    Map.update!( foo, :b, updater)
  end
end
</code></pre>
<p>or at least</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Foo do
  defstruct [ :a, :b]

  def update( foo, field, updater) do
    Map.update!( foo, field, updater)
  end

  def update( foo, changes) do
     Map.merge( foo, changes)
  end
end
</code></pre>
<p>This approach enables far easier and less error prone refactoring and debugging as well as having the abstraction in question have the last say on validating the mutation intent.</p>
<p>My 2c</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367045" 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/changes-to-the-struct-update-syntax/71232/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-367045" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367045"
                     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>
    <div class="postbit" id="367054" data-post-id="367054">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This only gives readability. I made one step forward in my example. The pattern-matching in function heads and specifications should be more than enough for <code>LSP</code> and other tools to make autocomplete working. This is very easy solution and gives people more opportunity to care about docs and specs.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367054" 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/changes-to-the-struct-update-syntax/71232/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-367054" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367054"
                     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 #32"></div>
  </section>
</div>
    <div class="postbit" id="367061" data-post-id="367061">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="1" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Not only that, pattern matching helps us find other bugs in the code too. For example, imagine you have this code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def trim_address(user) do
  %User{user | address: String.trim(user.adress)}
end
</code></pre>
<p>In this case, there is a typo when reading the field name, which is not caught by the update syntax, but it would have been caught if you pattern matched on the <code>%User{}</code> struct.</p>
</blockquote>
</aside>
<p>Couldn’t the type system catch this bug without the pattern match, inferring from the update syntax that <code>user</code> is <code>%User{}</code>?</p>
<aside class="quote no-group" data-username="NobbZ" data-post="6" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nobbz/48/27235_2.png" class="avatar"> NobbZ:</div>
<blockquote>
<p>For now I strictly prefer the struct update syntax, as I get field completion there.</p>
</blockquote>
</aside>
<p>100% agreed</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367061" 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/changes-to-the-struct-update-syntax/71232/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-367061" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367061"
                     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 #33"></div>
  </section>
</div>
    <div class="postbit" id="367064" data-post-id="367064">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Membrane-Core-Team" data-username="mat-hek" data-post="34" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mat-hek/48/38168_2.png" class="avatar"> mat-hek:</div>
<blockquote>
<p>Couldn’t the type system catch this bug without the pattern match, inferring from the update syntax that <code>user</code> is <code>%User{}</code>?</p>
</blockquote>
</aside>
<p>Unfortunately not in all scenarios. In this particular example yes, it would, but once you add conditionals and other constructs, it gets blurrier. Here is an example of a warning that would not be caught with the current inference but would with pattern matching:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def absolute_z(condition, point) do
  point.w

  if condition do
    %Point{point | z: abs(point.z)}
  else
    point
  end
end
</code></pre>
<p>Any conditional is problematic because we can only assume that point is a <code>%Point{}</code> in a specific branch, so we cannot propagate the inference up. If we assumed it to be a Point on all branches, it could lead to false positives. If you do <code>%Point{} = point</code>, it always works.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367064" 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/changes-to-the-struct-update-syntax/71232/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-367064" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367064"
                     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 #34"></div>
  </section>
</div>
    <div class="postbit" id="367065" data-post-id="367065">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Also people sometimes tends to overuse some patterns like binding different values to the “same” variable.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">user = struct(User, user)
# instead of
user = struct(User, user_params)
</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="367065" 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/changes-to-the-struct-update-syntax/71232/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-367065" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367065"
                     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 #35"></div>
  </section>
</div>
    <div class="postbit" id="367066" data-post-id="367066">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It’s the same when we pattern match in the if branch:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def absolute_z(condition, point) do
  point.w

  if condition do
    %Point{} = point
    %{point | z: abs(point.z)}
  else
    point
  end
end
</code></pre>
<p>but I get the <em>point</em></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367066" 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/changes-to-the-struct-update-syntax/71232/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-367066" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367066"
                     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 #36"></div>
  </section>
</div>
    <div class="postbit" id="367092" data-post-id="367092">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Membrane-Core-Team" data-username="mat-hek" data-post="37" data-topic="71232">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mat-hek/48/38168_2.png" class="avatar"> mat-hek:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">def absolute_z(condition, point) do
  point.w

  if condition do
    %Point{} = point
    %{point | z: abs(point.z)}
  else
    point
  end
end
</code></pre>
</blockquote>
</aside>
<p>This made me think that pattern matching inside a branch (actually after the first usage of a variable in the scope) should <em>be warned</em> for variables from the outer scope in the same way struct updates are warned.</p>
<p>I am positive this is doable.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367092" 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/changes-to-the-struct-update-syntax/71232/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-367092" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367092"
                     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 #37"></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/71232/load_more?page=4">Load more posts (42 remaining)</a>
</div></template></turbo-stream>