-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
String: change order of arguments in starts_with and ends_with #10105
Conversation
I'm not enthusiastic about Extlib's choice of order of arguments, but I agree we have a bit of a problem here. Should we revert the addition of |
Just for the proverbial record, this was discussed in the original PR - see #9533 (review) |
@ygrek honestly, unlabeled, you are only going to confuse readers that are not familiar with extlib's idea of reading this function. Almost every From a cost/benefit perspective I don't think it's a good idea to have to explain for the next 20 years that an unlabeled If you want to provide a bugless migration path towards stdlib's signature I suggest either 1) you break the signature in extlib by any means to make users aware of the problem or 2) you deprecate it with a suitable alert that explains the situation. |
extlib as a library is older than my programming career, let alone my ocaml experience, so I am trying to maintain it without breaking backward compatibility. I was thinking that maybe stdlib starts_with being implemented with a labeled argument would make it less sensitive to the order of arguments. |
I tend to agree with @dbuenzli : committing to backward compatibility with all standard library extensions feels hardly sustainable in the long term. And if I am not mistaken, this compatibility issue would only be a concern for users that switch to |
Wasn't there another suggestion for those functions to change the label? I would be in favor of playing it safe and not exposing them in 4.12 so that we can reach a better consensus by 4.13. |
There was here. Do you want to reopen that discussion ? As far as I'm concerned I would be glad if we went for what I proposed there but I'm too tired to argue for it, it seems difficult to make people step back and look a bit further. At a certain point we need to move on. I already changed here and there some APIs to align to the stdlib. I would be glad if we could at least settle on something now (regardless of whether the functions make it to 4.12) so that I can stop the back and forth. |
I agree that we should decide now - 4.12 hasn't yet flipped from alpha to beta (even if it will be soon) and I tend to @Octachron's opinion, too. I don't the extra time gained delaying the decision to 4.13 will add anything! |
I propose to do the following:
I created an open, shared document at https://codimd.math.cnrs.fr/os79Xe-dRU-J5laJf6qoiw to try to condense the arguments in various directions in a single place. |
On argument order:
Some extra data that would be useful:
All this being said, my preference would be to make sure we like the label name, consistently encourage its use, and as a result consider that this unsolvable tension for parameter-declaration order does not matter much, and (as a gift of kindness on this new year) make the choice that is consistent with those standard-library-extensions that use the same function names -- if a unique such choice exists. |
I agree with this, and I'd like to suggest a slightly stronger proposal for resolving this question (and similar questions that might arise in the future): we should add support for attaching the "labels-omitted" warning to a declaration, so that any unlabeled use of the annotated function triggers a warning: val starts_with : prefix:string -> string -> bool
[@@ocaml.warning "+6"] With this change there's no longer a need to make the signature of the standard library function the same as the extlib version, since if unlabeled applications are detected then there's no possibility of silent bugs. |
@ygrek do you have a concrete example of Extlib-using code that gets in trouble because of the new stdlib export, and how a different declaration-side argument order would make things different? (If I remember correctly extlib shadows stdlib module with additional definitions, so I suppose that you now have to change the signature in ExtString to match the stdlib's, to avoid being cursed by users. Do you have a concrete example where this change in problematic?) |
Current signature in extlib:
Example of code using it : https://github.com/search?q=extlib+starts_with+language%3Aocaml&type=Code I agree with @gasche reasoning about order and labels (that's what was my thinking behind this PR).
It is about committing to backward compatibility with existing code. |
Yeah so the problem is with code like:
if you remove My take-away would be that:
|
Removing an For those specific functions using them without labels is probably error-prone enough that it may make sense to stick with the |
I'm not sure what the way to go here is. Given that there have already been some discussions about the argument order and name I think we won't find I conclusion that satisfies everyone. I personally would go with the existing order and wait with the inclusion of the functions until either #10118 is merged or the proposal of @yallop would be implemented, which I personally would prefer more. |
The proposal of @yallop requires some non-obvious design and implementation, so it's very clear that it would not be available until at least 4.13. I'm less sure about #10118 (my proposal to enable the warning by default), I don't know if we could sneak it into the 4.12 release at this point -- this would probably require opam-wide testing. Either of those changes could fix the Extlib issue (if we use the current order) or the other-people issue (if we use Extlib order), and it also makes sense to try to have both. I believe that once one of those changes are applied, it probably does not matter which order we use, so we can as well stick to the current order which seems to be slightly more popular than the Extlib order. I believe that this leaves us with the following choice:
I think that (2) is the safer default choice (it does not assume extra worry for the release-management team). @dbuenzli pointed out (understandably) that he would be unhappy about it, but then he would also be unhappy about (1) so maybe that's life. I will submit a PR to implement (2), and also a PR to change the labels to |
My own reading of the discussion is that the incompatibility with Extlib is minor and no changes are required in the 4.12 release. At any rate, the only two reasonable choices are 1- go ahead, and 2- remove the new functions from 4.12. It is way too late in the 4.12 release cycle to slip in new features like #10118. |
Agreed. I’d add though that we should never be afraid to add or enable warnings - packages in opam which break because we add or turn on a warning are themselves already broken. |
Regarding #10118 and 4.12: noted, there will be no attempt to have it in 4.12. Could you also consider giving your opinion there as to whether the change is actually a good idea? I would be happy to have it in trunk (regardless of the outcome of the String helpers discussion). |
Regarding extlib: I don't think that the compatibility issue is as minor as you are saying. Extlib is used by a lot of packages out there, and I can very well see bugs happening because of the argument-order mismatch. (There is a correlation between "using extlib" and "larger codebase" and "not having migrated to Dune yet", an effective cocktail to make this bug likely.) I think this is a compatibility issue (even if the changes does not silently break existing code) that should be taken seriously. |
I agree with @gasche: we should definitely enable warning 6 for 4.13 and delay the introduction of these functions until then. IMO the problem is not so much backward compatibility but the possibility of introducing hidden bugs in existing code. |
It is true that it is possible to trigger a hidden bug with code that amounts to open Extlib.String
open Stdlib.String
let bug = starts_with "prefix_rest" "prefix" After some pondering, I kind of like the idea of enabling the warning for omitted labels in order to free us from the ghosts of alternative argument orderings. |
Just for the record I'm not unhappy about 2 and would be more unhappy about 1. The only thing I was asking is to have a decision on the actual signatures now as I have some APIs that match them. |
Random fun fact (as I'm preparing PRs to implement my proposals):
looks like Extlib is not the only place where the prefix is passed as a second parameter... |
(Obviously the prefix of |
ftr my way of reading it (ingrained over years) is "starts_with a b" = "string a starts_with b" :) |
I'm closing this PR because we are not going to merge it and because an alternate course of action will be followed. (Namely: remove the new functions from 4.12, and turn warning on by default in 4.13.) |
to match extlib.
ref #9533 (comment)
This change will make life for extlib maintainer (aka me) much easier and will help prevent bugs for people used to extlib String module