www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Deprecating Allocating Functions In std.string

reply Jack Stouffer <jack jackstouffer.com> writes:
Looking through the source code of std.string, a lot of the 
functions that allocate have range based non-allocating 
alternatives that accomplish the same task. I'm wondering if 
there is any specific reason to keep the allocating versions 
around? If there are two functions in the same module that 
perform the same task, why not do the cycle of 
deprecation->remove docs->remove on the allocating version, as 
the other function is clearly better. Also, it's more GC handling 
code that would be removed, which is good for PR reasons.
Nov 04 2015
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 4 November 2015 at 16:17:29 UTC, Jack Stouffer 
wrote:
 Looking through the source code of std.string, a lot of the 
 functions that allocate have range based non-allocating 
 alternatives that accomplish the same task. I'm wondering if 
 there is any specific reason to keep the allocating versions 
 around? If there are two functions in the same module that 
 perform the same task, why not do the cycle of 
 deprecation->remove docs->remove on the allocating version, as 
 the other function is clearly better. Also, it's more GC 
 handling code that would be removed, which is good for PR 
 reasons.
And why break the code that uses them? They work just fine, and for many programs, the allocation is a non-issue and simply getting a string back rather than a range is more user-friendly. We probably wouldn't add functions like them at this point (particularly if we already had the range-based ones), but I really don't see any point in removing them. And even if it were good PR to remove GC-allocating functions, it's bad PR to break existing code, so it needs to have a solid reason as to why it's worth it, which I don't think that we have in this case. And it's not like we're ever going to remove all of the GC-allocating stuff from Phobos anyway. Some stuff needs it. We just want to make it so that the GC is not required by the code when it's not actually required to do what the code does. And if we have an eager function that allocates and a lazy one which doesn't, we've provided the nogc option for that functionality already. - Jonathan M Davis
Nov 04 2015
parent reply Jack Stouffer <jack jackstouffer.com> writes:
On Wednesday, 4 November 2015 at 22:42:19 UTC, Jonathan M Davis 
wrote:
 And why break the code that uses them? They work just fine, and 
 for many programs, the allocation is a non-issue and simply 
 getting a string back rather than a range is more user-friendly.
Because there are two functions that do the exact same thing that both need to be maintained. The fix for an existing code base is as simple as a global find and replace for the function name and change the type to auto.
 And it's not like we're ever going to remove all of the 
 GC-allocating stuff from Phobos anyway.
We can remove as much as possible.
 And if we have an eager function that allocates and a lazy one 
 which doesn't, we've provided the  nogc option for that 
 functionality already.
Again, I fail to see why you would ever need to use the allocating versions of these functions when the non-allocating versions perform the exact same tasks but faster.
Nov 04 2015
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, 4 November 2015 at 23:28:09 UTC, Jack Stouffer 
wrote:
 On Wednesday, 4 November 2015 at 22:42:19 UTC, Jonathan M Davis 
 wrote:
 And why break the code that uses them? They work just fine, 
 and for many programs, the allocation is a non-issue and 
 simply getting a string back rather than a range is more 
 user-friendly.
Because there are two functions that do the exact same thing that both need to be maintained. The fix for an existing code base is as simple as a global find and replace for the function name and change the type to auto.
And then slap an array() call on the end anyway. Sure, in some cases, you can replace a call to an eager function with a lazy one, but in many, you can't without first converting to an array, because the lazy function doesn't result in the right type of range. Lazy functions are frequently _not_ drop-in replacements for eager ones. And as far as maintenance goes, if there's no really efficiency advantage to doing eager() over lazy().array(), then the internals of eager() can be changed to simply call lazy().array(), whereas if there _is_ an efficiency advantage to eager(), then we gain something by keeping it around.
 And it's not like we're ever going to remove all of the 
 GC-allocating stuff from Phobos anyway.
We can remove as much as possible.
I really don't see any point in removing them when they work just fine. It's just going to cause code breakage. Those who want to avoid the allocations can just change their code to use the lazy functions, and those that don't care can just leave their code as-is. If we go and remove all of the existing eager functions, I expect that a number of folks will get ticked about the resulting code breakage and the fact that they end up having array() in a bunch of places in their code where they didn't have to before. We're trying to avoid deprecating functions if we don't have to. Mass deprecations reduce our stability and hurt our PR. And a wholesale deprecation of eager functions goes completely contrary to that goal and without adding any real value.
 And if we have an eager function that allocates and a lazy one 
 which doesn't, we've provided the  nogc option for that 
 functionality already.
Again, I fail to see why you would ever need to use the allocating versions of these functions when the non-allocating versions perform the exact same tasks but faster.
Is it faster? If you don't actually need to allocate, then it likely is, but if you do need to allocate, then there's a decent chance that a version that was specifically written with that in mind is going to be be faster. And even if the lazy version _is_ faster, there are plenty of folks who would prefer the eager version simply because it's easier to use, and the efficiency gain doesn't mean anything in their particular use case. We've been adding lazy versions of functions for years now, and we've never removed the eager versions. And I'm pretty sure that Walter and Andrei have generally been opposed to the idea of doing so precisely because of the code breakage that it causes. We have been moving towards using lazy range-based functions as much as possible and avoiding adding new eager functions, but that doesn't mean that removing the eager functions is worth the pain that that causes or even that the eager functions aren't worth having. - Jonathan M Davis
Nov 04 2015
parent reply Rory McGuire via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thu, Nov 5, 2015 at 2:02 AM, Jonathan M Davis via Digitalmars-d <
digitalmars-d puremagic.com> wrote:

 We've been adding lazy versions of functions for years now, and we've
 never removed the eager versions. And I'm pretty sure that Walter and
 Andrei have generally been opposed to the idea of doing so precisely
 because of the code breakage that it causes. We have been moving towards
 using lazy range-based functions as much as possible and avoiding adding
 new eager functions, but that doesn't mean that removing the eager
 functions is worth the pain that that causes or even that the eager
 functions aren't worth having.

 - Jonathan M Davis
Surely the eager functions should at least be using the lazy version internally? "more code, more bugs" is often a true statement (not always, but often).
Nov 13 2015
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, 13 November 2015 at 21:48:58 UTC, Rory McGuire wrote:
 On Thu, Nov 5, 2015 at 2:02 AM, Jonathan M Davis via 
 Digitalmars-d < digitalmars-d puremagic.com> wrote:

 We've been adding lazy versions of functions for years now, 
 and we've never removed the eager versions. And I'm pretty 
 sure that Walter and Andrei have generally been opposed to the 
 idea of doing so precisely because of the code breakage that 
 it causes. We have been moving towards using lazy range-based 
 functions as much as possible and avoiding adding new eager 
 functions, but that doesn't mean that removing the eager 
 functions is worth the pain that that causes or even that the 
 eager functions aren't worth having.
Surely the eager functions should at least be using the lazy version internally? "more code, more bugs" is often a true statement (not always, but often).
If it doesn't harm the efficiency of the function, then yes, changing an eager function to call the lazy one internally makes sense. If it does harm efficiency, then it's a more debatable question. But the big issue here is simply that we don't want to break existing code just for the sake of moving to lazy range-based functions as the norm in Phobos. I understand the sentiment, but I really don't think that it's worth the code breakage, and I recall Walter and Andrei saying the same. - Jonathan M Davis
Nov 13 2015