New Issue: version-based annotations for deprecation and stability?

20911, "mppf", "version-based annotations for deprecation and stability?", "2022-10-25T18:14:52Z"

A Python Precedent

For a long time, I have been envious of what Python shows in their docs in terms of the versions of Python in which a standard library function become available or changed significantly. Here is an example from os — Miscellaneous operating system interfaces — Python 3.14.0 documentation :

os.fsencode(filename)

Encode path-like filename to the filesystem encoding and error handler; return bytes unchanged.
fsdecode() is the reverse function.
New in version 3.2.
Changed in version 3.6: Support added to accept objects implementing the os.PathLike interface.

These "New in version" and "Changed in version" elements are attached to the individual functions and that can be very useful when developing Python code that needs to run with several versions of Python.

Imagine a World Where...

What if the Chapel programming language supported attributes/annotations for this purpose?

Here is a straw example just to convey the idea.

getFileSize was added in 1.12, so it could indicate that:

@versions 1.12..
proc getFileSize(name: string) { }

Then we would get a warning if we compile in a way indicating that we want to be able to run in 1.11:

$ chpl --min-version 1.11 --max-version 1.29
warning: FileSystem.getFileSize was not available in version 1.11 -- it was new in 1.12

So that's nice and helps to catch easy mistakes. (It would not catch all problems with compiling with many versions of Chapel -- you would test for that -- but it can catch the errors that are now obvious to the compiler).

But, the idea can help more. Let's take a tricky example where a function's return type changed. Let's say we had this in 1.26:

proc foo() : int { ... }

and then in 1.29 we wanted to change the return type to void:

proc foo() : void { ... }

We could express that with where clauses and the new annotations:

@versions 1.26..1..27
@deprecated "this 'foo' is deprecated -- the newer version returns void -- please specify --min-version 1.29 or newer to accept the new behavior and avoid this warning"
proc foo() : int where minVersion < 1.29 { ... }
@versions 1.26..
proc foo() : void where minVersion > 1.29 { ... }

(in the above, I am supposing that the minVersion symbol is a config param connected to --min-version).

Now if you compile it with a --min-version that is older than 1.29, you would get the deprecation error:

$ chpl --min-version 1.26 --max-version 1.29
warning: this 'foo' is deprecated -- the newer version returns void -- please specify --min-version 1.29 or newer to accept the new behavior and avoid this warning

But, if you indicate that you want compatibility only with version 1.29, the deprecation error goes away:

$ chpl --min-version 1.29 --max-version 1.29
<no deprecation warning for 'foo'>

This seems like it might be an interesting alternative as compared to creating config params for each individual such change in behavior.