nathanl

nathanl

Is `mix xref graph --label compile-connected` overzealous?

I’m confronted with a case where mix xref graph --label compile-connected --fail-above 0 would force me to refactor something which seems unnecessary. I’ll give a simplified example, starting with an expected case and then showing my case.

Expected case

Here is a clear transitive compile-time dependency, where A depends on B which depends on C.

(Note: pretend that each of these modules is in its own file.)

  • If C.hello/0 changes, that means B needs to recompile and B.hello/0 changes
  • If B.hello/0 changes, that means A needs to recompile and A.hello/0 changes
defmodule A do
  @hello B.hello()
  def hello, do: @hello
end

defmodule B do
  @hello C.hello()
  def hello, do: @hello
end

defmodule C do
  def hello, do: "hello"
end

We can find this out like this:

$ mix xref graph --label compile-connected --fail-above 0

lib/a.ex
└── lib/b.ex (compile)
** (Mix) Too many references (found: 1, permitted: 0)

If we want to know “why is it bad that A depends on B? What does B depend on?”, we can check:

$ mix xref graph --source lib/b.ex

lib/b.ex
└── lib/c.ex (compile)

(Tangential point: it would be nice if the first command would show this automatically; its output implies “A shouldn’t depend on B” when maybe the truth is that B shouldn’t depend on C.)

A More Confusing Case

Here is a more confusing case, like the one I’m facing:

  • If C.world/0 changes, that means B needs to recompile and B.world/0 changes
  • If B.world/0 changes, I’m pretty sure that A isn’t going to compile any differently, but because the A depends at compile time on B for B.hello/0, it will get (needlessly?) recompiled.
defmodule A do
  @hello B.hello()
  def hello, do: @hello
end

defmodule B do
  @hello "hello"
  def hello, do: @hello

  def world, do: C.world()
end

defmodule C do
  def world, do: "world"
end

The mix xref commands above see these two situations as the same, even though to me they seem quite different. This seems like a shortcoming of mix xref and/or the compile process.

Am I wrong?

Most Liked

nathanl

nathanl

Further conversation in Elixir Slack with Michał Muskała:

Me: So this is a case of “in theory it would be nice if it could be more granular, but that would be hard to implement”? I think in the case that I showed, recompiling A is wasted work

Michał Muskała: Yes, in this case it is. Tracking this however is very complex - the graphs can get pretty big and just maintaining them might be more expensive than just doing some of the extra compilations

al2o3cr

al2o3cr

My interpretation of this situation is that you’re tracking more detail in your mental model of the compiler than the compiler actually uses.

C.world/0 changes” is just “C changes” to the compiler.

Where Next?

Popular in Discussions Top

Jayshua
I recently came across the javascript library htmx. It reminded me a lot of liveview so I thought the community here might be interested....
New
mikl
I wanted to capitalize a string, and tried using String.capitalize(). That generally works well, until you try to capitalize a word like...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
WolfDan
After doing a port from a c++ library to my project in phoenix I’ve seen that I need a faster way to run this algorithm and I found this ...
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43657 311
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement