Oh, one additional point. As we add more static verification to Elixir,
this verification will be done based on runtime dependencies. For example,
if A depends on B at runtime, and B changes, we need to verify the types of
A in relation to B are still valid. Elixir v1.15 already moved behaviours
from compile time deps to runtime deps, which is a win. Therefore, hiding
runtime dependencies is bound to have more and more downsides.



On Tue, Sep 20, 2022 at 9:24 AM José Valim <jose.va...@dashbit.co> wrote:

>
> I guess what I'm ultimately confused about is what *absolutely
>> necessitates* a runtime dependency becoming a transitive compile time
>> dependency.
>>
>
> defmodule A do
>   def const, do: 13
> end
>
> defmodule B do
>   def const, do: A.const()
> end
>
> defmodule C do
>   @const B.const()
> end
>
> C depends on B at compile-time. B depends on A at runtime. Still, if A
> changes, C must be recompiled.
>
> There is zero chance we will allow developers to bypass this behaviour
> because, if you get this wrong (now or in the future when the project
> evolves), then your users will increasingly run into situations where an
> interactive build emits different results than a full build. And those will
> be impossible to understand why in large projects. In turn this will
> ultimately harm developers confidence on projects, who will then proceed to
> perform full builds, "just to be sure", and harm productivity.
>
> Once again, the runtime dependency is not the root cause. *You must
> remove the compile-time dependencies OR isolate runtime deps from
> compile-time deps*. I understand users are familiar with how Ash works
> today but, in my opinion, this discussion is indicative of design issues. I
> also understand change is frustrating, but sometimes it is necessary,
> especially as we recognize patterns that can be harmful once projects grow.
> Elixir changed how configuration works because it was unproductive for
> large projects. Phoenix moved helpers from from imports to aliases, due to
> similar runtime-compile issues in large projects. Etc.
>
>
>> In the case of Ash resources, they are introspectable configurations.
>> Some modules that you get back when inspecting that configuration make
>> sense to "do something with" at compile time. Others absolutely don't. In
>> Ash these things are modeled as behaviours because that is the way that I
>> can define a functional contract. Not being able to refer to modules in
>> this way essentially forces us to bypass the compiler.
>>
>
> As mentioned before, the fact a dependency can be compile-time or runtime
> can be problematic. You should have distinct entry-points for those.
> Ideally, remove most compile-time configuration OR encapsulate it in a
> single place instead of throughout the system.
>
> I will bow out of the discussion for now because I believe I have given
> all insight I have on the topic. Once again, I want to say bypassing the
> compiler can be really harmful and I do not encourage this pattern. We make
> the compiler smarter, whenever we can, but sometimes we have to make our
> abstractions simpler too.
>
> ---
>
> Marlus, feel free to start a separate thread if you need help with moving
> to the @after_verify callback. That's what we are using for declarative
> assigns in LiveView and I assume it is similar in capabilities to Surface.
> If the assumption is not true, please let me know.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BqUcvP%2BgE5GPF-kxJHF5G46tCvFJyDJR6yNZeTOMDHgg%40mail.gmail.com.

Reply via email to