← Back to context

Comment by antithesis-nl

1 day ago

Nice as a thought experiment, but you actually do get this in real life as well, when maintaining a public API with a large user base (where even the details of the internal workings need to be frozen over time.)

Gives you lovely stuff like the Win32 API (introduced in 1993 and still very much a thing!). CreateWindow, CreateWindowEx, CreateWindowExEx (OK, I made that up...), structs with a load-bearing length field, etc. etc. And read some Raymond Chen on the abuse that customers inflict on the more 'private' stuff...

But you do get perfect backward compatibility. If you want to opt-in to the bug fix, you use a newer version of the function.

I recall there being a blog post, maybe by Joe Armstrong in which he advocated for having version numbers in functions. CreateWindow_v1 CreateWindow_v2, or you could use the commit hash.

  • I do think version numbers in function names is the least bad version of this. I seem to recall a demonstration of a content-addressable function calling system which could effectively garbage-collect no-longer-called function implementations, but that's only useful if you have the library and all its callers in the same execution context.

    • I was playing around with GPIO some time ago. The Linux kernel seems to adopt this approach. The first rule of Linux ABI is that thou shalt not break ABI.The second rule of Linux ABI is THOU SHALT NOT BREAK ABI.

      So they had something like GPIOHANDLE_GET_LINE_VALUES_IOCTL, decided to change things around a little, so introduced GPIO_V2_LINE_GET_VALUES_IOCTL.

      Although, as the saying goes, the problem with backwards compatibility is that anything that starts backwards stays backwards.

      1 reply →

    • This is how microservices should work and in practice do work, but the deployment teams have to coordinate running n+k versions simultaneously so make sure that no inflight requests and clients are broken, this is can take months making k very large.