top | item 17597446

(no title)

ShaneWilton | 7 years ago

I'd imagine it isn't, at least depending on how you define API compatibility, and whether you're only looking at the API interfaces. Imagine two versions of a library that implement the function "add".

  Version 1:
  add Int -> Int -> Int
  add x y = x + y

  Version 2:
  add Int -> Int -> Int
  add x y = x * y
Both versions expose the same API interface, but the functions that conform to that interface are semantically different. A stronger type system could probably differentiate between the two functions, but I doubt you could generally compute whether both functions implement the same behavior.

Perhaps with some sort of functional extensionality you'd be able to compute compatibility perfectly, but I can't imagine that ever being feasible in practice.

That being said, what Elm does offer is still a huge improvement over humans trying to guess whether they made any breaking changes :)

discuss

order

codebje|7 years ago

You certainly cannot determine that two programs do or do not have the same behaviour in the general case.

In specific cases, the proofs can be pretty trivial:

https://tinyurl.com/ycx2245q - proof your two programs are different

https://tinyurl.com/y7lcv3re - proof 'y + x' is the same as Version 1.

These proofs weren't automatically discovered, though for such simple programs I'd expect an SMT solver to be able to find the proof or a counterexample easily enough.

But even proving they're the same value for all inputs isn't all that helpful, because of lazy Haskell code like:

    version 1:
    fib :: Int -> Int
    fib n = if n < 3 then 1 else fib (n - 2) + fib (n - 1)

    version 2:
    fib :: Int -> Int
    fib n = let fs = 1:1:zipWith (+) fs (tail fs) in fs !! n
They're (provably) the same for all (positive) input values, but if you call version 1 with n greater than, say, 35, you'll be waiting quite a while for an answer, while version 2 will be very snappy for the first few hundred thousand values of n, at least, after which the size of the answer will be a bottleneck.

If a library switched from the latter to the former, it'd have a good chance of breaking code.

While obviously exponential code is obviously exponential, this sort of behavioural change can show up in less obvious ways - a change in memory usage might blow your heap after a supposedly minor version change, eg.

In the end I don't think the value judgement of 'breaking' or even 'significant' is computable, and you'd need to rely on a human doing something that approximates to 'right' for your world view with their version numbering.

toast0|7 years ago

I don't think 'does it work exactly the same' isn't necessarily the right question, given there are expected to be bug fixes which may change the behavior in some functions.

marcosdumay|7 years ago

The right question is "what's the difference between a bug-fix and a breaking change?"