This is an attempt on summing up the arguments for code compatibility. If it’s not very evenly balanced, it might be due to my convictions of code compatibility being the better alternative.
Definition of code compatibility
We say that A
is code compatible with B
if valid use of code generated from B
also is valid use of code generated from A
with the same sound compiler.
Restrictions
Restrictions on DSDL
For a DSDL definition:
- All variable names that exists in
B
must also exist inA
. They must also have the same type. - All const names that exists in
B
must also exist inA
. They must also have the same type.
Restrictions on DSDL compilers
For a compiler implementation to be sound, it must generate compatible code if:
- All variable names that exists in
B
also exist inA
with the same type. - All const names that exists in
B
alsos exist inA
with the same type.
The argument for code compatibility
Automatic update to the newest version of a definition is nice.
With code compatibility, no work is required when updating to new definitions with the same major version number. This is the non-surprising behavior and allows developers using new fields without extra maintenance burden.
Not having code compatibility doesn’t give us much
The benefits of not having code compatibility are mainly the ability to fix misspelled words and doing small ergonomic changes as unrolling arrays and the like. The problem of doing ergonomic changes is that breaking the code to get the corrected spelling is more unergonomic than living with the misspelled word until the next major version release.
Having minor version updates solves all other problems.
Most (all?) of the examples where code compatibility would be useful for solving the problem. Incrementing minor version and populating void field would be a better solution. This will require some caution when stabilizing types, but should be achievable.
The changes that break code compatibility often make dangerous assumptions
One example that was brought up was removing the sub_mode
field from NodeStatus
. The problem is that removing a field from a definitions is a very dangerous thing to do. If someone has started using it and it gets repopulated everything can quickly becomes quite messy.
To avoid breaking fielded nodes we should avoid doing potentially dangerous changes that breaks code compatibility.
The argument against code compatibility
Adding new features to DSDL
If we add new features/types to DSDL at a later point we will not be able to use them in a backward compatible way if requiring code compatibility. An example is that if we create a type Q16_8
:
uint16 integer_bits
uint8 fractional_bits
We will not be able to substitute it for a native q16.8
type later on
For the full (incredible long) discussion of code compatibility check out this github issue: https://github.com/UAVCAN/specification/issues/9