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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m not sure what you mean by “fixed the mistake” WRT Igniter, but I think I was just wrong when explaining our main use case with <code>Spitfire</code>. Sorry about that <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"> Error tolerance is why we use <code>Spitfire.container_cursor_to_quoted/1</code> as opposed to <code>Code.Fragment</code>, but what we actually use <code>Spitfire</code> for is primarily <code>Spitfire.Env.expand</code>.</p>
<p>The way we are using it currently (and we aim to expand this usage) is, for example, when patching in a module name, we want it to respect existing module aliases.</p>
<p>For example, when installing <code>AshPostgres</code>, we make sure that your <code>Repo</code> module exists, is configured correctly, etc., and then we make sure that it is a child of your application (and that you have an application file, we create it if it doesn’t exist).</p>
<p>This patching logic is naive at the moment, but it will get more robust over time. I’ve also removed a bunch of stuff token this example simple</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># in `Igniter.Project.Application`
  def do_add_child(igniter, application, to_supervise) do
    path = Igniter.Code.Module.proper_location(application)

    Igniter.update_elixir_file(igniter, path, fn zipper -&gt;
      with {:ok, zipper} &lt;- Igniter.Code.Module.move_to_module_using(zipper, Application),
           {:ok, zipper} &lt;- Igniter.Code.Function.move_to_def(zipper, :start, 2),
           {:ok, zipper} &lt;-
             Igniter.Code.Function.move_to_function_call_in_current_scope(
               zipper,
               :=,
               [2],
               fn call -&gt;
                 Igniter.Code.Function.argument_matches_pattern?(
                   call,
                   0,
                   {:children, _, context} when is_atom(context)
                 ) &amp;&amp;
                   Igniter.Code.Function.argument_matches_pattern?(call, 1, v when is_list(v))
               end
             ) do
        zipper
        |&gt; Zipper.down()
        |&gt; Zipper.rightmost()
        |&gt; Igniter.Code.List.append_new_to_list(Macro.escape(to_supervise), diff_checker)
      else
        _ -&gt;
          {:warning, "...."}
      end
    end)
  end
</code></pre>
<p>So when using <code>append_new_to_list</code>, that ultimately ends up using code that expands the environment at the place you are bringing in code, and uses that to</p>
<ol>
<li>honor aliases when checking for matches in the list</li>
<li>use aliases when inserting a module into the AST</li>
</ol>
<p>Error tolerance can be useful for us because it is theoretically possible to introduce invalid AST “temporarily” while working with igniter. You compose a bunch of AST modifiers, and I didn’t want to necessarily guarantee that, after every single modification you make, the AST is valid. Only when actually writing the file must it be valid.</p>
<p>If its not valid, though, you won’t get the nice features of being able to determine env at a location.</p>
<p>This is the entirety of our <code>Spitfire</code> usage currently.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  @doc """
  Expands the environment at the current zipper position and returns the
  expanded environment. Currently used for properly working with aliases.
  """
  def current_env(zipper) do
    zipper
    |&gt; do_add_code({:__cursor__, [], []}, :after, false)
    |&gt; Zipper.topmost_root()
    |&gt; Sourceror.to_string()
    |&gt; String.split("__cursor__()", parts: 2)
    |&gt; List.first()
    |&gt; Spitfire.container_cursor_to_quoted()
    |&gt; then(fn {:ok, ast} -&gt;
      ast
    end)
    |&gt; Spitfire.Env.expand("file.ex")
    |&gt; then(fn {_ast, _final_state, _final_env, cursor_env} -&gt;
      {:ok, struct(Macro.Env, cursor_env)}
    end)
  rescue
    e -&gt;
      {:error, e}
  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="336399" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-336399" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336399"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="336406" data-post-id="336406">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zachallaun" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/120/29208_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zachallaun
                    <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>Definitely understand, but:</p>
<aside class="quote group-Ash-Core-Team quote-modified" data-username="zachdaniel" data-post="12" data-topic="65316">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachdaniel/48/31980_2.png" class="avatar"> zachdaniel:</div>
<blockquote>
<p>…but what we actually use <code>Spitfire</code> for is primarily <code>Spitfire.Env.expand</code>.</p>
</blockquote>
</aside>
<p>This means that Igniter requires Elixir 1.17+, which seems like a significant drawback as well. No such thing as a free lunch, and all that. <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>
<p>As José suggested, there are certainly things lib_elixir could do to reduce/eliminate the need for downloading Elixir (though it does only happen once and then is cached). For instance, instead of specifying a ref, libraries could specify a path, and then stick a tarball/zip in priv.</p>
<p>Ultimately, the two main goals of lib_elixir are to:</p>
<ol>
<li>Make it possible to use the latest Elixir stdlib APIs while maintaining wider version compatibility, and</li>
<li>Make it much easier for tools to stay up-to-date with the latest and greatest Elixir features without time consuming manual work (vendoring in stuff yourself and making sure you change everything important and in a way that will work for the version range you want to support).</li>
</ol>
<p>Finally, Spitfire was just the library that came to mind and was a good proof-of-concept usage, but if it’s goals differ from the two above, then there’s no reason for it to use lib_elixir!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="336406" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-336406" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336406"
                     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="336411" data-post-id="336411">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="zachallaun" data-post="13" data-topic="65316">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/48/29208_2.png" class="avatar"> zachallaun:</div>
<blockquote>
<p>This means that Igniter requires Elixir 1.17+, which seems like a significant drawback as well. No such thing as a free lunch, and all that. <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>
</blockquote>
</aside>
<p>We don’t require 1.17+, we just fail to perform smarter alias handling logic unless you’re using 1.17+.</p>
<p>I think requiring a download <em>to compile</em> is a non-option for Ash/igniter, although it could be totally fine for other use cases. I think the idea of downloading the files once and saving them with the library is the best case all around IMO and should be the only/default method. This reduces any potential variability between downloads, prevents network issues from coming into play while end users are compiling tools, etc.</p>
<p>Also, I should have led with this: I think this is awesome <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"> I think that for exactly the reasons we’re just talking about here w/ <code>Igniter</code> not being able to be as smart unless the end-user is on 1.17+, this will provide a very valuable improvement to Igniter users, and ought to have similar impacts for other projects as well. I’m very excited about this idea <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="336411" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-336411" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336411"
                     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="336414" data-post-id="336414">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zachallaun" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/120/29208_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zachallaun
                    <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>So, for this to be “ready to use,” I think lib_elixir should also be using the Bob-compiled Elixirs, which means no additional compilation should be happening (compiling with <code>make</code>, that is). We need the end-user’s version of OTP to know which precompiled Elixir to download, but on the correct version of OTP, the .beam files should be portable across operating systems (right?).</p>
<p>It would even be possible for library authors using lib_elixir to pre-namespace for every version of OTP they wish to support and then save that result in priv. Then the only thing that needs to happen on end-user machines is moving some .beam files around. This seems like the optimal path, I 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="336414" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-336414" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336414"
                     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="337001" data-post-id="337001">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/zachallaun" rel="nofollow">@zachallaun</a> have you considered generating the namespaced code and publishing that code to hex instead of having the consumer of the library inject it?</p>
<p>I think what I expected is to see a library with something like <code>LibElixir_1_17</code>, <code>LibElixir_1_18</code> modules.</p>
<p>(Rationale for the namespaced modules here rather than just releasing the package with the version of Elixir its packaging is so that two libraries could use different versions without problems.)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337001" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-337001" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337001"
                     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="337002" data-post-id="337002">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Zach is using the environment expanding features of spitfire which use the new Macro.Env functions, not the parser itself.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337002" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-337002" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337002"
                     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="337005" data-post-id="337005">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zachallaun" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/120/29208_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zachallaun
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Expert-LSP-Core-Team" data-username="mhanberg" data-post="16" data-topic="65316">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mhanberg/48/17162_2.png" class="avatar"> mhanberg:</div>
<blockquote>
<p><a class="mention" href="/u/zachallaun" rel="nofollow">@zachallaun</a> have you considered generating the namespaced code and publishing that code to hex instead of having the consumer of the library inject it?</p>
</blockquote>
</aside>
<p>I’m not actually sure how that would work. The technique here is to modify the <code>.beam</code> files generated when you compile Elixir, and then stick those in the code path. That compilation needs to have been done with the runtime Erlang/OTP version, so you have to delay picking the correct version until compile-time.</p>
<p>I think the way to publish code to hex would be to parse and namespace the original <code>.ex</code> and <code>.erl</code> files and then publish that. In our experience, that’s a much trickier process with many more edge cases than parsing the BEAM abstract code that is read in from compiled <code>.beam</code> files. But I’m very open to a different/better solution if there’s something I’m missing.</p>
<p>I haven’t been able to work on this in the last week, but I think the current solution could be optimized so that the only thing that happens at compile-time is namespacing. Libraries using lib_elixir could bundle compiled Elixirs from <a href="https://github.com/hexpm/bob" rel="noopener nofollow ugc">Bob</a> in their <code>priv</code> to be distributed with the library (so nothing needs to be downloaded) and nothing would need to be compiled using system tools like <code>make</code> because the Bob artifacts contain the precompiled <code>.beam</code> files.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337005" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-337005" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337005"
                     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="337007" data-post-id="337007">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Oh right, it slipped my mind that it was modifying at that level.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337007" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-337007" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337007"
                     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="337013" data-post-id="337013">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Had another thought</p>
<p>In your gist above, would it be possible to write the modified modified abstract forms to disk as source files in <code>lib_elixir</code> and then include a Mix.Task.Compiler for the consuming code to add to their project? The compiler would be the part that calls <code>:compiler.forms</code> and handles writing the .beam files.</p>
<p>If this is possible, it sounds like you could keep the modified source files in the library, and the consuming application would be able to compile it locally like a normal erlang or elixir file (and therefore not have to worry about min OTP version to compile with ahead of time)</p>
<aside class="quote no-group" data-username="zachallaun" data-post="1" data-topic="65316">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/48/29208_2.png" class="avatar"> zachallaun:</div>
<blockquote>
<ul>
<li>Compile your Elixir and Erlang modules to bytecode: <code>.app</code> and <code>.beam</code> files.</li>
<li>Read them in as <a href="https://www.erlang.org/doc/apps/erts/absform.html" rel="nofollow">Abstract Forms</a> using <code>:beam_lib.chunks(path, [:abstract_code])</code>.</li>
<li>Walk the abstract code, rewriting module names to their namespaced counterparts:</li>
<li><code>Code -&gt; Spitfire.LibElixir.Code</code></li>
<li><code>:elixir_tokenizer -&gt; :spitfire_lib_elixir_tokenizer</code></li>
<li>Recompile the modified abstract forms using <code>:compile.forms(...)</code>, writing the resulting binary out to a new <code>.beam</code>:</li>
<li><code>Elixir.Code.beam -&gt; Elixir.Spitfire.LibElixir.Code.beam</code></li>
<li><code>elixir_tokenizer.beam -&gt; spitfire_lib_elixir_tokenizer.beam</code></li>
</ul>
</blockquote>
</aside> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337013" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-337013" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337013"
                     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="337021" data-post-id="337021">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="zachallaun" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/zachallaun/120/29208_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  zachallaun
                    <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>Hmm, just writing the abstract forms to a file is an interesting option that I hadn’t thought of. I’d like to think through the Pros/Cons compared to namespacing the abstract forms during compilation.</p>
<p>Pros:</p>
<ul>
<li>Faster compilation because namespacing happens ahead of time.</li>
<li>Multiple libraries can depend on and use the same lib_elixir instead of having to re-namespace per library.</li>
<li>Easier setup, just add dependency like <code>:lib_elixir_1_17_2</code> and then use <code>LibElixir_1_17_2.Code</code> (etc.) instead of having to set up custom config, pre-download, and namespace the abstract forms. (Though that would only happen once.)</li>
</ul>
<p>Cons:</p>
<ul>
<li>More difficult maintainership, or at least more complex setup to get automations in place to distribute multiple lib_elixir versions, stay up-to-date with releases, etc.</li>
<li>Possibly misusing the hex package registry by encoding the Elixir version in the package name. <code>:lib_elixir_1_17_2</code> instead of <code>:lib_elixir</code>. (This is necessary for different libraries to depend on different versions.)</li>
<li>Doesn’t support building arbitrary ref, e.g. whatever the latest dev build is.</li>
</ul>
<p>Things I missed?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337021" 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/working-on-lib-elixir-elixir-core-modules-as-a-library/65316/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-337021" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337021"
                     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 #20"></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/65316/load_more?page=3">Load more posts (3 remaining)</a>
</div></template></turbo-stream>