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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chemist" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chemist
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yep i read this but dont understand how to use this to solve my current problem. You have any suggestions?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244025" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-244025" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244025"
                     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="244026" data-post-id="244026">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chemist" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chemist
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Vexing.</p>
<p>Yep but why would I need a <code>validates/3</code> when I’m calling only a <code>validates/2</code> ultimately after the evaluation of the inner <code>Map.get</code>.</p>
<p>By right my function call should work as it has an arity of 2. Thoughts?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244026" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-244026" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244026"
                     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="244027" data-post-id="244027">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Can you try this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">validates(:withdrawal, presence: [message: "expected"], 
  by: [function: &amp;Test.test/2, 
  message: "invalid withdrawal."])

  def test(withdrawal, context) do
    # some logic here
    funds_balance = context.funds_balance
  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="244027" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-244027" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244027"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chemist" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chemist
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi kartheek, yes that is what I did as explained in my original post, I still want to find out whether a nested function can be done.</p>
<blockquote>
<p>I am aware that it is possible to move this function to the function, test but will like to learn if it is possible to do it as a nested function as part of an anonymous function</p>
</blockquote> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244028" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-244028" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244028"
                     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="244029" data-post-id="244029">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="kartheek" data-post="11" data-topic="46256">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kartheek/48/19143_2.png" class="avatar"> kartheek:</div>
<blockquote>
<p>Check this issue - <a href="https://github.com/CargoSense/vex/issues/11" rel="noopener nofollow ugc">Compilation error with Vex.Struct validates by · Issue #11 · CargoSense/vex · GitHub</a></p>
</blockquote>
</aside>
<aside class="onebox githubissue" data-onebox-src="https://github.com/CargoSense/vex/issues/11#issuecomment-87475663">
  <header class="source">

      <a href="https://github.com/CargoSense/vex/issues/11#issuecomment-87475663" target="_blank" rel="noopener nofollow ugc">github.com/CargoSense/vex</a>
  </header>

  <article class="onebox-body">
    <div class="github-row">
  <div class="github-icon-container" title="Issue" data-github-private-repo="false">
	  <svg width="60" height="60" class="github-icon" viewBox="0 0 14 16" aria-hidden="true"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg>
  </div>

  <div class="github-info-container">
    <h4>
      <a href="https://github.com/CargoSense/vex/issues/11#issuecomment-87475663" target="_blank" rel="noopener nofollow ugc">Compilation error with Vex.Struct  validates by</a>
    </h4>

    <div class="github-info">
      <div class="date">
        opened <span class="discourse-local-date" data-format="ll" data-date="2015-03-29" data-time="09:24:31" data-timezone="UTC">09:24AM - 29 Mar 15 UTC</span>
      </div>

        <div class="date">
          closed <span class="discourse-local-date" data-format="ll" data-date="2015-03-30" data-time="13:34:55" data-timezone="UTC">01:34PM - 30 Mar 15 UTC</span>
        </div>

      <div class="user">
        <a href="https://github.com/bitchef" target="_blank" rel="noopener nofollow ugc">
          <img alt="" src="https://avatars.githubusercontent.com/u/8940595?v=4" class="onebox-avatar-inline" width="20" height="20">
          bitchef
        </a>
      </div>
    </div>

    <div class="labels">
    </div>
  </div>
</div>

  <div class="github-row">
    <p class="github-body-container">Hi,
I am a new Vex user and I am loving it (^_^)b Recently, I stumbled on the fo<span class="show-more-container"><a href="" rel="noopener nofollow" class="show-more">…</a></span><span class="excerpt hidden">llowing error while trying to vaiidate a structure attribute with a custom function:

Environment: Elixir 1.0.3  -  Erlang/OTP 17 

```
** (ArgumentError) cannot inject attribute @vex_validations into function/macro because cannot escape #Function&lt;1.98856283/1 in :elixir_compiler_5.__MODULE__/1&gt;. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, pids and remote functions in the format &amp;Mod.fun/arity
    (elixir) lib/kernel.ex:2043: Kernel.do_at/4
    (elixir) expanding macro: Kernel.@/1
    test/test_helper.exs:8: UserTest.__vex_validations__/0
    (vex) /tmp/vex/test/test_helper.exs:8: Vex.Struct.__before_compile__/1
```

So, as a test,  I added the following line to Vex's `UserTest` module in `test_helper.exs` and got the same error.

``` elixir
validates :age, by: &amp;(&amp;1 &gt; 18)
```

Any thoughts?
Cheers!</span></p>
  </div>

  </article>

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

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

<p>This says you cannot use anonymous functions when validating structs:</p>
<blockquote>
<p>This is because anonymous functions are closures, which is to say that they capture the environment in which they’re created. In the case of module attributes, this is the compile time environment that is not available at runtime.</p>
</blockquote>
<blockquote>
<p>Long story short, when validating structs you have to use named remote functions IE <code>&amp;OtherModule.function/1</code></p>
</blockquote>
<p>I guess you have no other option ?</p>
<p><a class="mention" href="/u/benwilson512" rel="nofollow">@benwilson512</a> can elaborate more on this.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244029" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-244029" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244029"
                     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="244030" data-post-id="244030">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chemist" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chemist
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I have read the article already. But i dont fully understand <em>how it applies to my question</em></p>
<blockquote>
<p>This is because anonymous functions are closures, which is to say that they capture the environment in which they’re created. In the case of module attributes, this is the compile time environment that is not available at runtime.</p>
<p>Long story short, when validating structs you have to use named remote functions IE <code>&amp;OtherModule.function/1</code></p>
</blockquote>
<p>As you have quoted this article again despite me saying I have read it, maybe you can explain to me how this case applies here.</p>
<p>Do note, you have successfully created an anonymous function in the validator <em>contrary to what the article says</em> and furthermore, this article does not comment on my question - nesting a <em>named function</em> within an anonymous function.</p>
<p>Thanks kartheek.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244030" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-244030" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244030"
                     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="244040" data-post-id="244040">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="chemist" data-post="17" data-topic="46256">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/c/d9b06d/48.png" class="avatar"> chemist:</div>
<blockquote>
<p>you have successfully created an anonymous function in the validator <em>contrary to what the article says</em></p>
</blockquote>
</aside>
<p>I have not created an anonymous function, I captured the function using &amp; operator. Look at the following:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(6)&gt; a = &amp;Test.test/2
&amp;Test.test/2
iex(7)&gt; i a
Term
  &amp;Test.test/2 #&lt;- it is pointing to Test.test func
Data type
  Function
Type
  external
Arity
  2
Implemented protocols
  Enumerable, IEx.Info, Inspect, Jason.Encoder, Phoenix.Param, Plug.Exception, Swoosh.Email.Recipient
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(8)&gt; a = &amp;Test.test(&amp;1, &amp;2.funds_balance)
#Function&lt;43.79398840/2 in :erl_eval.expr/5&gt;
iex(9)&gt; i a
Term
  #Function&lt;43.79398840/2 in :erl_eval.expr/5&gt;
Data type
  Function
Type
  local
Arity
  2
Description
  This is an anonymous function. # &lt;- anonymous function
Implemented protocols
  Enumerable, IEx.Info, Inspect, Jason.Encoder, Phoenix.Param, Plug.Exception, Swoosh.Email.Recipient
</code></pre>
<aside class="quote no-group" data-username="chemist" data-post="17" data-topic="46256">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/c/d9b06d/48.png" class="avatar"> chemist:</div>
<blockquote>
<p>As you have quoted this article again despite me saying I have read it, maybe you can explain to me how this case applies here.</p>
</blockquote>
</aside>
<p>You might have read it - you may have missed few things.</p>
<aside class="quote no-group" data-username="chemist" data-post="17" data-topic="46256">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/c/d9b06d/48.png" class="avatar"> chemist:</div>
<blockquote>
<p>this article does not comment on my question - nesting a <em>named function</em> within an anonymous function</p>
</blockquote>
</aside>
<p>Github issue says you cannot use anonymous functions - as they are closures and their environment does not survive once compilation is finished - in this case of defining as module attribute(<span class="mention">@vex_validations</span>) and using them in a function(<strong>vex_validations</strong>). Closures and anonymous functions are little difficult to explain here - you can read more about them on internet.</p>
<p>Read my comments inline:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Vex.Struct do
  @moduledoc false

  defmacro __using__(_) do
    quote do
      @vex_validations %{}
      @before_compile unquote(__MODULE__)
      import unquote(__MODULE__)
      def valid?(self), do: Vex.valid?(self)
    end
  end
  
  """
  below macro tries to inject a __vex_validations__ function which refers to @vex_validations, 
  which has  anonymous function. anonymous function cannot be injected by elixir compiler.
  """
  defmacro __before_compile__(_) do
    quote do
      def __vex_validations__(), do: @vex_validations

      require Vex.Extract.Struct
      Vex.Extract.Struct.for_struct()
    end
  end

  """
  below macro creates a module attribute @vex_validations on the module. 
  This works fine - no problems till here.
  """
  defmacro validates(name, validations \\ []) do
    quote do
      @vex_validations Map.put(@vex_validations, unquote(name), unquote(validations))
    end
  end
end
</code></pre>
<p>You can try to compile the following code(it will fail), this is similar to what Vex.Struct macros are doing:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Test do
  @test_map %{function: fn -&gt; 1 end}

  def test_map, do: @test_map
end
</code></pre>
<p>TLDR: You are creating an anonymous function and it does not work in case of Vex.Struct due compiler limitations.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244040" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-244040" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244040"
                     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="244189" data-post-id="244189">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chemist" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chemist
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Many thanks kartheek for your kind and comprehensive reply. I took some time to ponder and try out the samples you helpfully supplied.</p>
<p>You make sense. Can kindly see my responses to check my understanding</p>
<ol>
<li><code>&amp;Test.test</code> is NOT an anonymous function. It is NAMED Test.test where <code>Test</code> is the module, <code>test</code> the function. <code>&amp;</code> is a capture operator and ONLY when applied to an unnamed function e.g. <code>fn x -&gt; x + 1 end</code>, that function is treated as an anonymous function USING a capture operator e.g. <code>&amp;(&amp;1 + 1).()</code></li>
</ol>
<p>A question though: My earlier post above had a nested <code>&amp;Map.get(&amp;2, :funds_balance)</code> - is this an anonymous function? Or a named one?</p>
<ol start="2">
<li>My mistake</li>
</ol>
<blockquote>
<p>You might have read it - you may have missed few things.</p>
</blockquote>
<ol start="3">
<li>So in essence, there is NO way to use the <code>validates</code> macro exposed by <code>Vex.struct</code> for an anonymous function so my method of defining a seperate function is correct (which you also suggested)</li>
</ol>
<p>But just a quick question: I dont understand one of your inline comments:</p>
<aside class="quote no-group quote-modified" data-username="kartheek" data-post="18" data-topic="46256" 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/kartheek/48/19143_2.png" class="avatar"> kartheek:</div>
<blockquote>
<p>Read my comments inline:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  """
  below macro creates a module attribute @vex_validations on the module. 
  This works fine - no problems till here.
  """
  defmacro validates(name, validations \\ []) do
    quote do
      @vex_validations Map.put(@vex_validations, unquote(name), unquote(validations))
    end
  end
end
</code></pre>
</blockquote>
</aside>
<p>What does “no problems till here” mean? Do you mean this function should execute without problems?</p>
<p>Many thanks and have a great weekend.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244189" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-244189" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244189"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="244199" data-post-id="244199">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/chemist" rel="nofollow">@chemist</a> You are welcome.</p>
<p>Kernel.SpecialForms.&amp;/1 or capture operator - terminology of capturing or creating anonymous function is little confusing in the docs (speaking for myself) :</p>
<ol>
<li>
<p>&amp; captures a function - <code>&amp;Module.function/arity</code> - same as <code>Function.capture(Module, function, arity)</code> - <code>&amp;Test.test/2</code> is same as <code>Function.capture(Test, :test, 2)</code></p>
</li>
<li>
<p>Another way of capturing function is <code>&amp;Module.function(&amp;1, &amp;2,.. &amp;n)</code> - this should match the number of parameters for a given function. No modification of parameters. <code>&amp;Test.test(&amp;1, &amp;2)</code> captures function and  is same as <code>&amp;Test.test/2</code></p>
</li>
<li>
<p>&amp; can create an anonymous function - <code>&amp;()</code> which is short form for <code>fn -&gt; end</code>. <code>&amp;(&amp;1 + 2)</code> is expanded to <code>fn x -&gt; x + 2 end</code>. {} and <span class="chcklst-box fa fa-square-o"></span> can be used for tuples and lists.</p>
</li>
<li>
<p>&amp; can partially apply a function - <code>&amp;Test.test(&amp;1, &amp;2.funds_balance)</code> (note - here we don’t use arity /n). function call looks similar to 1 and 2 - as we are modifying second param - it creates an anonymous function - <code>fn x, x1 -&gt; Test.test(x, x1.funds_balance) end</code></p>
</li>
</ol>
<p>Lets look at the following example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule TestCapture do
  def capture_1() do
    x = &amp;Test.test/2
    x.(1, 2)
  end

  def capture_2() do
    x = &amp;Test.test(&amp;1, &amp;2)
    # rewritten as
    # x = &amp;Test.test/2
    x.(1, 2)
  end

  def capture_3() do
    x = Function.capture(Test, :test, 2)
    # expanded as
    # x = :erlang.make_fun(Test, :test, 2)
    x.(1, 2)
  end

  def capture_4() do
    x = &amp;Test.test(&amp;1, &amp;2.funds_balance)
    # expanded as 
    # x = fn x1, x2 -&gt; Test.test(x1, x2.funds_balance) end
    x.(1, 2)
  end

  def capture_5() do
    x = &amp;Test.test(&amp;1, Map.get(&amp;2, :funds_balance))
    # expanded as
    # x = fn x1, x2 -&gt; Test.test(x1, Map.get(x2, :funds_balance)) end
    x.(1, 2)
  end

  def capture_6() do
    x = &amp;(&amp;1 + &amp;2 + 1)
    # expanded as
    # x = fn x1, x2 -&gt; :erlang.+(:erlang.+(x1, x2), 1) end
    x.(1, 2)
  end
end
</code></pre>
<p>You can see how - Elixir compiler expands the module using <code>BeamFile.elixir_code!(TestCapture) |&gt; IO.puts()</code> and ast using <code>BeamFile.debug_info(TestCapture)</code>.</p>
<p>All the three function captures - capture_1, capture_2, capture_3 generate same byte code - calling  function directly (no anonymous function).</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{:function, :capture_1, 0, 9,
     [
       {:line, 1},
       {:label, 8},
       {:func_info, {:atom, TestCapture}, {:atom, :capture_1}, 0},
       {:label, 9},
       {:move, {:integer, 2}, {:x, 1}},
       {:move, {:integer, 1}, {:x, 0}},
       {:line, 2},
       {:call_ext_only, 2, {:extfunc, Test, :test, 2}} # &lt;- this one 
     ]},
    {:function, :capture_2, 0, 11,
     [
       {:line, 3},
       {:label, 10},
       {:func_info, {:atom, TestCapture}, {:atom, :capture_2}, 0},
       {:label, 11},
       {:move, {:integer, 2}, {:x, 1}},
       {:move, {:integer, 1}, {:x, 0}},
       {:line, 4},
       {:call_ext_only, 2, {:extfunc, Test, :test, 2}} # &lt;- this one
     ]},
    {:function, :capture_3, 0, 13,
     [
       {:line, 5},
       {:label, 12},
       {:func_info, {:atom, TestCapture}, {:atom, :capture_3}, 0},
       {:label, 13},
       {:move, {:integer, 2}, {:x, 1}},
       {:move, {:integer, 1}, {:x, 0}},
       {:line, 6},
       {:call_ext_only, 2, {:extfunc, Test, :test, 2}} # &lt;- this one
     ]},
</code></pre>
<p><a href="https://hexdocs.pm/elixir/Kernel.SpecialForms.html#&amp;/1" class="inline-onebox" rel="noopener nofollow ugc">Kernel.SpecialForms — Elixir v1.20.2</a> documentation gives an example of Kernel.is_atom and states below:</p>
<blockquote>
<p>Capture operator. Captures or creates an anonymous function.</p>
</blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">fun = &amp;Kernel.is_atom/1
fun.("string")
</code></pre>
<blockquote>
<p>In the example above, we captured Kernel.is_atom/1 as an anonymous function and then invoked it.</p>
</blockquote>
<p>It should be read as below:</p>
<blockquote>
<p>Capture operator. Captures a function or creates an anonymous function.<br>
In the example above, we captured Kernel.is_atom/1 and it can be invoked using the same syntax as anonymous function.</p>
</blockquote>
<p>Essence of capturing a function is storing reference to a function in a variable to be passed around and invoked using the variable. This has nothing to do with anonymous functions or closures except that it uses <code>func_name.</code> syntax for invoking the function.</p>
<p>May be separating concepts like function variables, anonymous functions, captured functions and invoking a function in function variable will remove this confusion.</p>
<hr>
<p>For those who are curious - all the above code from beam file is inspected using <a href="https://github.com/hrzndhrn/beam_file" rel="noopener nofollow ugc">BeamFile</a> - <code>BeamFile.byte_code(TestCapture</code>), <code>BeamFile.elixir_code!(TestCapture) |&gt; IO.puts()</code> and <code>BeamFile.debug_info(TestCapture)</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="244199" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-244199" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244199"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="244203" data-post-id="244203">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am replying to your questions in this post:</p>
<p>Point - 1) Anonymous functions, captured functions, etc - covered in <a href="https://forum.elixirforum.com/t/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/20" rel="nofollow">previous post</a>. &amp; operator creates anonymous functions in cases 3, 4 like expanding short form anonymous functions defined using &amp;() or &amp;{} or &amp;<span class="chcklst-box fa fa-square-o"></span> and partially applying functions - As you are modifying second parameter of the Test.test function using Map.get - it will create an anonymous function (see example capture_5) .</p>
<p>Point - 3) True</p>
<aside class="quote no-group" data-username="chemist" data-post="19" data-topic="46256">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/c/d9b06d/48.png" class="avatar"> chemist:</div>
<blockquote>
<p>What does “no problems till here” mean? Do you mean this function should execute without problems?</p>
</blockquote>
</aside>
<p><code>validates()</code> macro is expanded before <code>__before_compile__</code> , but it appears lexically in the bottom of the file (till here - was in that sense). Anonymous function assignment to a module attribute directly or indirectly does not cause error. Module attributes are available only during compile time - any usage of module attribute with anonymous function in a func/macro will cause compiler error - in this case <code>__before_compile__</code> is causing error.</p>
<p>Have a nice weekend.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="244203" 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/vex-validate-w-anon-function-cannot-inject-attribute-vex-validations-into-function-macro-because-cannot-escape-function/46256/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-244203" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="244203"
                     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>