For example, if I have function A that calls function B, in today's languages updating function B would just work (A will call updated function). My understanding is that updated function B (we can call it B'), would not be used.
For example, if I have function A that calls function B, in today's languages updating function B would just work (A will call updated function). My understanding is that updated function B (we can call it B'), would not be used.
B = "Hello "
and it hashes to #a3yx. Lets say you also have funcion:
A = B ++ "world" which hashes to #c7c1
when we store the A function, we actually store it as:
#c6c7 = #a3yx ++ "world"
Then later if you update the definition of B:
B = "Hello, "
and that function hashes to, #5e2b, when you tell unison to update B from #a3yx => #5e2b, it will look for all of the places that used to reference #a3yx, like your A function, and will see if those functions still typecheck with the replacement. If so, they are automatically updated. If not, we pretty print the definitions that didn't to a file for you to manually fix.
A = "Hello "
B = "Hello "
C = A ++ "world"
D = B ++ "world"
and then you update the definition of A but not B?In fact if you had the function:
double x = x + x
and you were to rewrite it to be:
double addend = addend + addend
Unison would say "this is the same function, no update needed" as it produces the same AST
serviceA.requiredHeaders key = Dictionary.of "X-API-KEY" key
serviceB.apiKeyHeader apiKey = Dictionary.of "X-API-KEY" apiKey
If they hash to the same thing and I update `serviceA.requiredHeaders` (because the vendor changed from `X-API-KEY` to `X-VENDOR-API-KEY`) do I have to know that these are two different services in order to review the change and untangle these two methods or is there a way to mark these as "structurally equivalent but semantically distinct"?type UserName = UserName Text type Password = Password Text
since the entire point in introducing types here is to actually declare them as different from one another.
But for other it might actually be beneficial to recognize that they are the same type, for example:
type Optional a = None | Some a type Maybe a = Nothing | Just a
To allow for both, you can prefix type with either "structural" or "unique" depending on what behavior you want (unique is the default). We have tossed around the idea of also introducing unique terms which would let you terms like yours as unique terms that should be salted, and let the current behavior of "structural"? terms be the default. The reality is that this hasn't been such a big problem that it has made it to the top of our list yet ;)
Without knowing whether the following cases would actually be useful/relevant, I'm curious if these things apply to Unison:
- Is there a way to "pin" a symbol to a specific hash/version so it won't automatically update when the referred function gets a change? I.e. I could write: A = B@ ++ "world" and when I store and retrieve it, it becomes (example syntax): A = B@a3yx ++ "world"
- Is there a way to refer to a function/symbol by name rather than by hash? I.e. a call site which uses B by looking up which hash is currently associated with the name "B", such that if I do two simultaneous renames, B->D and C->B, the code would now refer to the function previously known as C?
- Are there ways in which the way function updates "bubble up" through the codebase (I assume updating a function means updating every function that calls it, recursively) could become a problem? It would seem that changing one little function could have a knock-on effect that requires re-hashing most of the codebase.
The process for upgrading Unison code is that if you have a function A that calls B, and you update B in some way, as long as the change is type-preserving it will automatically be propagated to all the sites in your project where B is called. If the change is not type-preserving (for example, if you added a parameter) the tooling itself will direct you to resolve all the places where B is applied. So as you change code locally, you're continually keeping your codebase in sync; A will always be calling the updated function.
Here's an example from our docs: https://www.unison-lang.org/docs/usage-topics/workflow-how-t...