4 ms·
The (public) name of the implementation is the unique identifier of the contract in most systems, so I think your "Right Answer" is roughly the status quo?
by ucarion 5y ago
The (public) name of the implementation is the unique identifier of the contract in most systems, so I think your "Right Answer" is roughly the status quo?
- lisper 5y agoNo. The name of a function in current languages has no connection at all to what the function does. (What would be the contract for a function named ‘foo’?)
- gbhn 5y agoThat's kind of the thing that makes APIs possible, right? It sounds to me like "what if programming were done in a completely flat global namespace in which abstractions, encapsulation, and structure were impossible."
- lisper 5y agoNo. An API specifies more than the name of the function. It will specify the arguments, their types, the type of the return value, and at least informally, what the function does. You can change the underlying implementation without changing the API. That's the whole point of an API. The problem with current API technology is that the informality of the spec of what the function does. That allows some aspects of the behavior of the function to change without triggering any warnings. By having the linker work on hashes of implementations you eliminate that problem but create a new problem. You can no longer change the behavior of the function because you can't change the function. That means you can't suddenly change behavior that some caller is counting on, but it also means you can't fix bugs without changes in the caller.
- tgbugs 5y agoReading this now, I'm imagining all the horrors of static linking but applied to every function instead of whole modules. Maybe the simplest solution is to allow the function to change to the new version, but make it easy to revert in the event that something breaks. This of course means that you can't make the names of the functions their hash (without lying, preventing the runtime from checking that hashes ways match, or modifying emitted bytecode or native code to do what you want), it has to be an orthogonal layer on top of them like types (as I mentioned elsewhere in the thread).
- ajuc 5y agoNope, according to https://twitter.com/unisonweb/status/1173942969726054401 https://twitter.com/unisonweb/status/1173942969726054401 when you change a function implementation the system has to walk the callers graph backwards starting from all the places where the function was called updating all the implementations with the new hash, then callers of these with the new implementation and so on up to main (or whatever it's called). I had a chance to implement something like this in a system that used jbpm 3 graph language (basically process X version 1 called process Y version 1 and I updated process Y to version 2). It's nontrivial especially with recursion, I'm wondering how they are dealing with that.
- lamontcg 5y agoA git-like datastore for your AST+callgraph.
- ajuc 5y agoLet's say you have definitions like that: f: Nat -> Nat g: Nat -> Nat h: Nat -> Nat h x = g (x * 2) g x = f (x * 3) f x = x < 0 ? 1 : h (x / 4) And now you change f to be f x = x < 1 ? 1 : h (x / 4) How do you do that? There's a cycle in the callgraph. In fact - how do you calculate a hash of a function that calls itself if you need its hash to calculate its hash :) EDIT: nevermind, recursion is a special case handled differently.