I'm in the process of breaking our larger/monolithic app into separate repos so we can bring the pieces in as dependencies on other apps.

However, a key problem we are running into is ultimately around the database models.

We're working on a separate thing around most of that, but at the heart the problem comes in that we are one level too far removed, so a LOT of warnings appear during compile, even though they aren't relevant at runtime — notably stuff like below on the dependency compile.

warning: Core.Repo.transaction/2 is undefined (module Core.Repo is not 
available or is yet to be defined)
  lib/rivet/ecto/collection/general.ex:21: Rivet.Ident.Action.full_table_scan/2

I've looked at how oban handles it, and they setup an inefficient layer of indirection (obfuscation) to hide the warning.

The problem I have is this is what I'd call a developer vanity change. It serves NO purpose other than to hide a compiler warning, but the side-effect is less efficient code during runtime.

The resulting code with a warning includes the atom for the repo module, and everything works fine. The warnings are legitimate in the myopic context of compiling ONLY the dependency, but are not correct when considering the complete application.

I could perhaps add something like `[xref: [exclude: [Core.Repo]]]` to the dependent library's project data/mix.exs, and that might be fine for a closed-world where we don't share the library. But we are considering opening the library to the public, so this isn't a valid solution.

I feel like this same problem is resolved with umbrella applications.

Which makes me wonder, perhaps there could be a way to treat an external dependency like a member of the umbrella, and inject stuff like the xref in at the deps() array level, rather than from within that project?

While I'm not a fan of premature optimization, but I do care about keeping in mind the things that will have a potential of high-frequency calls, and avoiding doing anything obviously dangerous with those, especially over just a vanity thing.

In this case the warning isn't a real problem, it's just something the compiler thinks could be a problem.

Is there some other way to do this short of putting in a less efficient abstraction layer just to make it so the compiler can't detect what's really happening?

I'm just throwing mud on the wall now but something like:

{:included_thing, "~> 1.2.3", xref: [exclude: [Core.Repo]]},

Ultimately, the problem I have with all of the hereto offered solutions is that they effectively boil down to "obfuscate your code enough that the compiler won't throw a warning."

But that's seriously misaligned in my opinion.

The goal of coding should be (a) creating simple but efficient code to execute in production that is (b) readable and maintainable.  These obfuscation/vanity recommendations violate both of these points.

I don't know what the right solution is. I just feel like there should be something better than what's there now.


-Brandon

--
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/4b127f8b-ddcb-b25e-0e7c-12af3af68252%40cold.org.

Reply via email to