-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API renames must be backported, new {.deprecatedAlias.} syntax #214
Comments
The problem is real but the solution could also be: Let's release 1.4 already and accept that the community must move to 1.4. It's semver, we know it doesn't work, yet we stick to it. |
Or: We backport the |
That would just kick the can down the road and you'd be faced with the exact same problem the next time around for 1.4=>1.6 or any future transition.
there are 2 options:
I prefer the pragmatic approach to the "1.0 stability guarantee".
That could be a compromise, but I think most ppl stuck on 1.0 (or any past release) want to migrate at some point, and migration is easier if gradual (fighting 1 deprecation warning/legacy flag) at a time. Suppressing a warning is so trivial though, I don't see how it's a negative: just add |
With such a small team, I think Nim still needs to maintain a more rapid development mode if it's going to stay competitive. Putting a lot of effort to support older versions is taxing on this. I think the great majority of active Nim users are always eager to use to latest version with the shiny new features and fixes :) |
this could be considered a breaking change because it introduces new symbols in the global namespace - due to modules not really being isolated - it's quite common that adding a symbol to one module breaks another (this is a general problem in nim, as soon as you have more than a pageful of code because of how weak the module boundary is)
this is a self-fulfilling prophesy - being "forced" to upgrade regularly prevents any other kind of users to become active nim users - backwards compat is a killer feature that allows a new category of users to participate
on balance, I'd prefer seeing most renames backported, but it would be nice to do something about the global namespace and module system as well - as-is, it'll be hard to create a library eco-system that doesn't keep breaking |
I have a solution for that but it's "yet another feature" or at least "yet another language change" but maybe I should write the RFC anyway... |
Yeah, too bad. But since API renames always cause friction and in the end the system with the worst names in history wins ("man, cat, grep, cp, kill ...") we simply won't accept API renames anymore in the future. |
nim-lang/Nim#13908 introduced a wide-ranging rename of exceptions to better reflect exception hierarchy, eg AssertionError=> AssertionDefect. While this was a good change, it creates a problem for backward compatibility; the current recommendation in nim-lang/Nim#13908 (comment) was to not backport it.
however this would pretty much guarantee a language drift and a not-so-slow death for 1.0 and 1.2: user code and third party code (or future packages) would face the impossible dilemma of either:
since
(not practical, this would be a huge wasted effort)proposal
FooOld=>FooNew
doesn't need to change all the code usingFooOld
(that's bonus and can happen over time) but it needs to introduce the new aliasFooNew
{.deprecatedAlias.}
syntax (or at least by the nimfix-era syntax:{.deprecated: [FooOld: FooNew].}
), not viatype FooOld* {.deprecated.} = FooNew
was was done in Error -> Defect for defects Nim#13908 see the reason in section below.benefits
{.deprecatedAlias: [FooOld].}
per renamed declaration)bonus1: selective deprecation warning:
--warning:deprecated:bar:off
The only effect on users of 1.0 branch when they upgrade to 1.0.8 is a deprecation warning (
Warning: use FooNew instead; FooOld is deprecated
). While they can use--warning:deprecated:off
to silence it, it's a bit blunt and goes against strategies of "gradual migration"; so we could introduce (and backport) a simple way to target a specific deprecation warning, for example:for the API renaming, we could simply use
--warning:deprecated:FooOld:off
for simplicity but that doesn't take into account cases whereFooOld
would exist in different modules (or even different packages) since--warning:deprecated:FooOld:off
has global scope; so instead we can simply introduce (and backport) this syntax:{. deprecatedAlias(bar): FooOld.}
wherebar
is the name we give to this deprecation warning (in our case, it could be calledpr13908
orerrorVsDefect
)benefits: this allows grouping all related API renames under 1 deprecation name, so that users can use a single flag in their home config.nims:
--warning:deprecated:errorVsDefect:off
bonus2: revive nimfix
{. deprecatedAlias(bar): FooOld.}
{.deprecated(bar): [FooOld: FooNew].}
with minimal (or probably 0) "manual fixups" needed.edge case: partial API renames for overloaded symbols
this is an edge case, and (IIUC) is the reason you get
Warning: the .deprecated pragma is unreliable for routines [User]
when applying{.deprecated: [fooOld: fooNew].}
to routines: when an API rename only renames some overloads offooOld
,{.deprecated: [fooOld: fooNew].}
cannot work (would give: Error: redefinition of 'funOld').That's one of the reasons for the proposed
{.deprecatedAlias.}
, see below.why not use
type FooOld {.deprecated.} = FooNew
as was done in nim-lang/Nim#13908 ?for several reasons:
alias: myecho=echo
to alias any symbol Nim#11822)Warning: FooOld2 is deprecated
instead ofWarning: use Foo instead; FooOld1 is deprecated
){.deprecatedAlias.}
This would be the best approach and we should do it and backport it:
{.deprecated: [FooOld: FooNew].}
and should be feasible to revive it and teach it {.deprecatedAlias.} )The alternative would be to allowing specifying the signature in the rewrite rule, but it's less appealing:
the param names and return type don't need to be specified since you can't overload by these (but you can rename parameters as shown above. The same idea could be applied for selective import, eg:
import foo except bar(int, float)
note
code changes, however minor (whether it's a bug fix or new feature or the proposed
{.deprecated: [FooOld: FooNew].}
) always have the slight potential to break someone's code/workflow, see the classic https://xkcd.com/1172/; because users may implicitly rely on the old behavior (eg here, it could cause conflict if user has introduced a typeAssertionDefect
in his code); this applies to backports (eg nim-lang/Nim@8cf8879).However, this is an acceptable tradeoff compared to the alternative, and those breakages should be unlikely and easy to fix.
links
D20200428T154340
summary:
The text was updated successfully, but these errors were encountered: