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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>What I actually need is a “safe navigation” through Phoenix “models”, exactly the case brought on the very beginning of this thread. A quick test shows the <code>get_in</code> to work so it looks to me that either things changed or there are some gotchas I am not aware of</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="230243" 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/maybe-nil-protection-for-nested-structs/468/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-230243" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="230243"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="230244" data-post-id="230244">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hmmm…</p>
<p>For me I can not use <code>get_in</code> on an arbitrary struct…</p>
<pre data-code-wrap="txt"><code class="lang-txt">iex(1)&gt; defmodule S do
...(1)&gt;   defstruct [:a, :b]
...(1)&gt; end
iex(2)&gt; get_in(%S{}, [:a])
** (UndefinedFunctionError) function S.fetch/2 is undefined (S does not implement the Access behaviour)
    S.fetch(%S{a: nil, b: nil}, :a)
    (elixir 1.11.4) lib/access.ex:286: Access.get/3
</code></pre>
<p>What have you done?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="230244" 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/maybe-nil-protection-for-nested-structs/468/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-230244" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="230244"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="230248" data-post-id="230248">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>To be frank I don’t know. Now it doesn’t work. So I must have done something differently and can no longer reproduce it <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>
<p>UPDATE:<br>
The thing that works for my case is something like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">row = MyApplication.MyContext.MyModel |&gt; MyApplication.Repo.one()
column_value = if is_nil(row), do: nil, else: row.column
</code></pre>
<p>Yet I am surely not happy with how it looks. OTOH <code>get_in(row, [:column])</code> works nicely when row is nil but fails when it is not. <code>get_in(row, [Access.key(:column)])</code> does the opposite. It works when row is not nil, but fails when it is. And I didn’t come up with a more elegant one-liner to cover both cases. And this doesn’t even touch nested structures/associations.</p>
<p>This makes me wonder.. is there really no need for something like an equivalent of Rails’ <code>try</code> in Elixir/Phoenix? Sure I could probably implement something like that somewhere in every project, but that kind of “safe traversal” does look like a very common case to me. At least coming from the Rails (and a few other languages/frameworks) world.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="230248" 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/maybe-nil-protection-for-nested-structs/468/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-230248" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="230248"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="230266" data-post-id="230266">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I ran into a similar issue where I had lots of structs that were basically wrappers for maps, where I just wanted the compile time guarantee of the structs. I wrote a small using macro that I can add to the top of a struct and then use it with the Access module</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmacro __using__(_) do
    quote do
      @behaviour Access

      defdelegate fetch(term, key), to: Map
      defdelegate get(term, key, default), to: Map
      defdelegate get_and_update(term, key, fun), to: Map
      defdelegate pop(date, key), to: Map
    end
  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="230266" 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/maybe-nil-protection-for-nested-structs/468/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-230266" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="230266"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="239231" data-post-id="239231">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Well, I for one just came into need of this today. Given how clever a language Elixir is, I’m actually surprised there isn’t a feature like this already</p>
<p>Syntax wise I wonder if <code>?</code> (in place of <code>.</code>) could work.</p>
<pre><code>person?city?name
</code></pre>
<p>That reads pretty well to me.</p>
<p>[Update]</p>
<p>I ended doing this, e.g. <code>(person.city || %{name: ""}).name</code>. Which is okay for one level, but still rather ugly for more, e.g. <code>((person || %{city: nil}).city || %{name: ""}).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="239231" 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/maybe-nil-protection-for-nested-structs/468/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-239231" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="239231"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="241789" data-post-id="241789">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I really wish this were the case.  Kotlin provides this out of the box, and it’s super convenient.</p>
<p><code>person?.city?.name</code></p>
<p>Kotlin uses this <code>?</code> syntax for a lot of other things concerning nulls, which don’t necessarily apply to Elixir, but I think if it worked for structs, it would be a really nice convenience.</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://kotlinlang.org/docs/null-safety.html#safe-calls">
  <header class="source">
      <img src="https://kotlinlang.org/assets/images/favicon.svg?v2" class="site-icon" alt="" width="64" height="64">

      <a href="https://kotlinlang.org/docs/null-safety.html#safe-calls" target="_blank" rel="noopener nofollow ugc">Kotlin Help</a>
  </header>

  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/345;"><img src="https://kotlinlang.org/assets/images/open-graph/docs.png" class="thumbnail" alt="" width="690" height="345"></div>

<h3><a href="https://kotlinlang.org/docs/null-safety.html#safe-calls" target="_blank" rel="noopener nofollow ugc">Null safety | Kotlin</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="241789" 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/maybe-nil-protection-for-nested-structs/468/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-241789" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="241789"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="241843" data-post-id="241843">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am not sure <code>?</code> operator exactly fits the current feature set.<br>
There is multiple semantics at play here:</p>
<p>For maps when the key is missing we get a runtime error KeyError.</p>
<p>For structs when the key is missing we get a compile-time error (great for preventing typos)</p>
<p>Elixir can track even nested structs but we need the information about them in the source code. That means it is impossible to create a macro that allows accessing nested struct and preventing typos at the same time. E.g. nothing stops you from populating <code>person.city</code> with a string instead of city struct.</p>
<p>We could resign from “typo safety” and do the checks at runtime but then we have next choice:</p>
<ul>
<li>do we throw KeyError when key is missing?</li>
<li>or do we return <code>nil</code>?</li>
</ul>
<p>I’d say KeyError is better because we are talking about structs and they populate all keys by default with nils.</p>
<p>Accessing nested values is very much Maybe monad. So if we want to have an  infix operator for nested access I’d use <code>&gt;&gt;&gt;</code> that stands for bind in <a href="https://github.com/witchcrafters/witchcraft" class="inline-onebox" rel="noopener nofollow ugc">GitHub - witchcrafters/witchcraft: Monads and other dark magic for Elixir · GitHub</a></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def nil &gt;&gt;&gt; _, do: nil
  def struct &gt;&gt;&gt; atom when is_struct(struct) and is_atom(atom), do: Map.fetch!(struct, atom)
</code></pre>
<p>and a full example of all the things I talked about:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Outer do
  defstruct [:inner]
end

defmodule Inner do
  defstruct [:a]
end

defmodule NestedAccess do
  def nil &gt;&gt;&gt; _, do: nil
  def struct &gt;&gt;&gt; atom when is_struct(struct) and is_atom(atom), do: Map.fetch!(struct, atom)
end

defmodule SafeStructs do
  def test do
    empty = %Outer{
      inner: nil
    }

    full = %Outer{
      inner: %Inner{
        a: "a"
      }
    }

    # dot nation protects from typos
    IO.inspect empty.inner
    # nil

    #IO.inspect empty.lol
    # does not compile

    IO.inspect full.inner.a
    # "a"

    # pattern matching without structs does not protect from typos
    case empty do
      %{inner: %{a: a}} -&gt; a
      %{} -&gt; nil
    end
    |&gt; IO.inspect
    # nil

    case empty do
      # note the non existent foo key
      %{foo: %{a: a}} -&gt; a
      %{} -&gt; nil
    end
    |&gt; IO.inspect
    # nil

    # pattern matching with structs protects from typos
    # because it gives compiler enough information
    case empty do
      %Outer{inner: %Inner{a: a}} -&gt; a
      %Outer{} -&gt; nil
    end
    |&gt; IO.inspect
    # nil

    #case empty do
    #  %Outer{foo: %{a: a}} -&gt; a
    #  %Outer{} -&gt; nil
    #end
    #|&gt; IO.inspect
    # does not compile

    import NestedAccess
    empty &gt;&gt;&gt; :inner
    full &gt;&gt;&gt; :inner &gt;&gt;&gt; :a
  end
end
</code></pre>
<p>To sum up: you can solve the problem with a two-line function defining an infix operator. Just be careful to think about the semantics of missing keys. For structs missing a key is definitely a typo. For maps, you could add  a case like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def map &gt;&gt;&gt; atom when is_map(map) and is_atom(atom), do: Map.get(map, atom)
</code></pre>
<p>because missing keys might be a legitimate thing.</p>
<p>And yet another question is: what if the city is suddenly a string instead of a struct? Do you return that string or throw an error? I think it is best to leave that decision to people implementing actual business logic and leave it out of the language <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="241843" 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/maybe-nil-protection-for-nested-structs/468/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-241843" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="241843"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>