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.