This is definitely an issue that is real, and is currently a problem, and that we will fix; probably by giving the function author an option to salt the hash of new definitions that have some semantic meaning beyond their implementations (appropriate for most application/business logic). No salt for definitions whose meanings are defined by their implementations (appropriate for most generic "library" functions like `List.map`).
We already make this distinction for data types, but not yet for value/function definitions.
Not only do they have to provide a salt themselves but on top of that, they need to make a judgment call of when something has "more semantic meaning beyond their implementation" (to use your words) rather than being some more "fundamental" code.
I'm also surprised that you haven't solved this problem yet: at least once a day, IDEA warns me that some portion of my code is duplicated exactly in some other area of my code, so this kind of duplicated logic is already quite common.
It's similar to how DNS can have two domains point to the same IP, but then you can change one of those domains point to a new IP.
But how do you know which name was called where if the callers referenced the content hash not the name?
If I understand Unison right, the names are used only on the developer's layer(to write code), but when you save code, it's all hash-based.
Still, Unison got my attention.
One challenge I foresee is unintentional coupling. Say you have two functions:
func serialize(MyRecord) ...
func debugToString(MyRecord) ...
Now if you ever make the mistake of having giving those the same implemention, then in Unison they'd be the same hash reference, right?
Then if you want to update, say the debug print later it would update all callsites for that hash including the ones that originally called serialize(). The two are no longer distinguishable.