-
-
Notifications
You must be signed in to change notification settings - Fork 739
Deprecate public aliases for Regex, StaticRegex, etc #5964
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
Conversation
As per the discussion at dlang#5963, we want the option to swap out the types for Regex, Capture, etc. This is impossible if people are able to refer to Regex by name. Furthermore, according to @wilzbach, aliases are not an option. Therefore, this PR deprecates public uses of the Regex types to allow us to switch out the concrete type later.
Thanks for your pull request, @dhasenan! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Some tips to help speed things up:
Bear in mind that large or tricky changes may require multiple rounds of review and revision. Please see CONTRIBUTING.md for more information. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. |
I think this quickly got out of hand. I think it's fine to keep Regex!Char and in fact I'd drop isRegexFor instead. StaticRegex!X is indeed on its way out. Captures!R is a non-standard concept (unlike e.g. forward range) that we are pretty much stuck with. RegexMatch is indeed just a forward range of Captures so can deprecate that . |
public alias StaticRegex = Regex; | ||
|
||
private alias _Regex(Char) = std.regex.internal.ir.Regex!(Char); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw that's another advantage of using auto
:
We don't have to pay any initialization cost until the function is called once :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean import cost, no? Because "initializers" would be constructors, usually. You never pay for an instance constructor until an instance is created, and you always pay for a static constructor before main()
.
Anyway, that's easily addressed:
template _Regex(Char)
{
private import std.regex.internal.ir : IRRegex = Regex;
alias _Regex = IRRegex!Char;
}
Pretty sure this technique has been discussed on the newsgroup several times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant CTFE "initialization" cost - evaluation would have been a better word.
Pretty sure this technique has been discussed on the newsgroup several times.
Well NG and actual PRs is a huge difference. Here's an overview on the status quo on making Phobos slicker:
- Faster to import std.regex, by lazy eval of wordMatcher #5942
- Dramatically faster to compile Tuple #5931
- Make import of std.internal.unicode_tables lazy. #5945
- Dramatically faster to import std.datetime (and anything under it) #5948
- Add a global convenience package file #5916
- http://forum.dlang.org/post/[email protected] (latest NG thread)
tl;dr: there are still a lot of easy fruits to pick :)
The biggest problem is that we should move docs to package.d so that Regex alias contains DDoc from internal/ir.d |
Thank you! I strive to be efficient.
But then we can't change
Not quite. It's a forward range of Captures with extra convenience methods So we can't switch from RegexMatch to something that's currently more widely used. But we could come up with a type similar to RegexMatch that can be more widely used (eg a more advanced type for searching through random-access ranges). If we did that, I would be able to add an alias for compatibility, but that apparently isn't a universal trait of phobos devs and I can't commit to being available to help out. So that's not an option. |
https://issues.dlang.org/buglist.cgi?component=phobos&list_id=218415&product=D&resolution=--- Any help would be highly appreciated!
Oh I think you have misunderstood me a bit. I was trying to say that we can't use aliases to change the return type of a function if it's not Bar myFancyPhobosFunction()
{
...
} and in a later version do the following:
|
Ah, I see the problem. When I said I strive to be efficient, you thought I said that I strive to do whatever you think is important whenever you want, without compensation. I really have no clue how people keep confusing the two, but since they do it a lot, apparently it's an easy mistake to make. I charge $150 per hour normally, but I offer a 30% open source discount.
Some discussion of why this is the case would be salient. Removing one type in favor of another and adding a compatibility alias seems like the obvious way to make a change with a reasonable deprecation cycle. |
Since it's apparently better to document the entire interface of your return types than to use static typing to direct people to the type's own documentation, this ensures that that documentation is complete.
FYI, here is a PR that fixes just the immediate issue for
This is not correct IMO. Only Voldemort returns make this guaranteed. And even there, it doesn't give you liberty to change the API of the return type. For instance, if you have: auto foo(T)(T t)
{
static if(is(T == int)) return cast(long)t * 2;
else return t * 2;
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are to go forward with this:
- tune down the destruction
- remove 3 documented comments
- move whatever documentation there is from internal subpackage
Lastly - for contructual work, negotiate with D Language foundation if they can accomodate such.
@@ -557,57 +562,49 @@ public: | |||
} | |||
} | |||
} | |||
///Slice of input prior to the match. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an important part of API actually.
@property R pre() | ||
{ | ||
return _nMatch == 0 ? _input[] : _input[0 .. matches[0].begin]; | ||
} | ||
|
||
///Slice of input immediately after the match. | ||
@property R post() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
assert(!matchFirst("nothing", "something")); | ||
--- | ||
+/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super useful part of API
Number of pattern matched counting, where 1 - the first pattern. | ||
Returns 0 on no match. | ||
+/ | ||
|
||
@safe @property int whichPattern() const nothrow { return _nMatch; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remarkably important part of API that allows you to match many things at once
@safe @property int whichPattern() const nothrow { return _nMatch; } | ||
|
||
/// | ||
@system unittest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is plain sabotage - deleting code that shows how to use the above powerful primitive
@property bool empty() const { return _captures._nMatch == 0; } | ||
|
||
///Same as !(x.empty), provided for its convenience in conditional statements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful short-cut to be documented.
Effectively it's a forward range of Captures!R, produced | ||
by lazily searching for matches in a given input. | ||
+/ | ||
@trusted public struct RegexMatch(R) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically of this PR,
only this can be kept
@property R post() | ||
{ | ||
return _captures.post; | ||
} | ||
|
||
///ditto | ||
@property R hit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 2-nd thing to keep from this PR
$(LI captures: compatibility alias for previous versions of std.regex.) | ||
) | ||
|
||
Each capture struct offers the following methods: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead just document the Captures struct. This description is at best a skeleton
T opCast(T:bool)(){ return !empty; } | ||
|
||
/// Same as .front, provided for compatibility with original std.regex. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 3-rd thing to keep from this PR
We can't use real return types because we need to be able to change out the types returned without a deprecation cycle. But in other places where that's done, we either use a private type or a Voldemort type to make it actually work. Nobody can actually refer to That's not the case with However, once (Or we could just be honest about our inclination to change return types and stop using Anyway, I don't have the patience to deal with open source anymore, so you all can decide what you want. I'm out. |
As per the discussion at #5963, we want the option to swap out the types for Regex, Capture, etc. This is impossible if people are able to refer to Regex by name. Furthermore, according to @wilzbach, aliases are not an option. Therefore, this PR deprecates public uses of regex types (Regex, StaticRegex, Captures, and RegexMatch) to ensure we can later swap out the implementation types..