Jump to page: 1 2 3
Thread overview
Naming of new lazy versions of existing Phobos functions
Jul 17, 2014
Brad Anderson
Jul 17, 2014
H. S. Teoh
Jul 18, 2014
Walter Bright
Jul 18, 2014
Brad Anderson
Jul 18, 2014
Brad Anderson
Jul 18, 2014
Ali Çehreli
Jul 18, 2014
H. S. Teoh
Jul 18, 2014
Brad Anderson
Jul 19, 2014
Brad Anderson
Jul 19, 2014
Gary Willoughby
Jul 19, 2014
Dicebot
Jul 19, 2014
Dmitry Olshansky
Jul 20, 2014
Jonathan M Davis
Jul 20, 2014
Dicebot
Jul 20, 2014
Tobias Pankrath
Jul 18, 2014
Walter Bright
Jul 18, 2014
Brad Anderson
Jul 18, 2014
Meta
Jul 19, 2014
Timon Gehr
Jul 18, 2014
Tourist
Jul 18, 2014
Walter Bright
Jul 18, 2014
Brad Anderson
Jul 18, 2014
H. S. Teoh
Jul 18, 2014
Walter Bright
Jul 18, 2014
Brad Anderson
Jul 21, 2014
Yota
July 17, 2014
Walter's prototype[1] for removing allocations from a phobos function (std.path.setExtension) got hung up on the naming of the function. It couldn't keep the same name because it differed only by return type.

Walter doesn't like explicitly naming them as lazy because existing lazy functions like most of std.algorithm don't have names that state they are lazy. On the other hand, setExt is controversial because it's an arbitrary abbreviation done just to avoid the naming conflict. Not every function we'd like to see adopt the same approach would be amenable to a simple abbreviation to dodge the naming issue.

I think it's probably a good time to come up with a naming scheme for these lazy versions of existing functions so things are consistent throughout Phobos.

David Nadlinger offered a few ideas in the thread: setExtensionLazy, extensionSetter, or withExtension.

I find the "with" prefix particularly attractive. It implies the lazy behavior, is short, and reads well when chained with other calls. Hypothetical example I gave in the Pull Request comments:

  auto contents =
      "  FILE".withStrip()
              .withLowercase()
              .withExtension(".txt")
              .readText();

At the risk of bikeshedding, I thought it would be useful to solicit the wider forum audience for ideas and opinions. Thoughts?

1. https://github.com/D-Programming-Language/phobos/pull/2149
July 17, 2014
On Thu, Jul 17, 2014 at 10:59:26PM +0000, Brad Anderson via Digitalmars-d wrote: [...]
> I find the "with" prefix particularly attractive. It implies the lazy behavior, is short, and reads well when chained with other calls. Hypothetical example I gave in the Pull Request comments:
> 
>   auto contents =
>       "  FILE".withStrip()
>               .withLowercase()
>               .withExtension(".txt")
>               .readText();
> 
> At the risk of bikeshedding, I thought it would be useful to solicit the wider forum audience for ideas and opinions. Thoughts?
> 
> 1. https://github.com/D-Programming-Language/phobos/pull/2149

I like "with".


T

-- 
Once the bikeshed is up for painting, the rainbow won't suffice. -- Andrei Alexandrescu
July 18, 2014
On 7/17/2014 3:59 PM, Brad Anderson wrote:
> Walter's prototype[1] for removing allocations from a phobos function
> (std.path.setExtension) got hung up on the naming of the function. It couldn't
> keep the same name because it differed only by return type.
>
> Walter doesn't like explicitly naming them as lazy because existing lazy
> functions like most of std.algorithm don't have names that state they are lazy.
> On the other hand, setExt is controversial because it's an arbitrary
> abbreviation done just to avoid the naming conflict. Not every function we'd
> like to see adopt the same approach would be amenable to a simple abbreviation
> to dodge the naming issue.

A good summary.


> I think it's probably a good time to come up with a naming scheme for these lazy
> versions of existing functions so things are consistent throughout Phobos.
>
> David Nadlinger offered a few ideas in the thread: setExtensionLazy,
> extensionSetter, or withExtension.
>
> I find the "with" prefix particularly attractive. It implies the lazy behavior,
> is short, and reads well when chained with other calls. Hypothetical example I
> gave in the Pull Request comments:
>
>    auto contents =
>        "  FILE".withStrip()
>                .withLowercase()
>                .withExtension(".txt")
>                .readText();
>
> At the risk of bikeshedding, I thought it would be useful to solicit the wider
> forum audience for ideas and opinions. Thoughts?
>
> 1. https://github.com/D-Programming-Language/phobos/pull/2149

Since there are a lot of existing lazy algorithms in Phobos that do not follow this naming convention, either the convention is pointless or we go through yet another round of changing Phobos names and breaking everyone's code.

I haven't completely sold Andrei on the idea, but I feel that all algorithms should be lazy unless they have a very strong reason not to be. Being the default suggests a naming convention for them would be unnecessary even if it were practical.

I also suggest that ext is not an arbitrary abbreviation for extension, it is commonplace. In a module named std.path, there's little doubt about what it means. And besides, "extension" itself is an abbreviation for "file name extension". I don't really want to go the Java approach of reallyLongSentencesAsIdentifierNames either, as those are not very practical unless one has an autocompleting IDE.
July 18, 2014
On Friday, 18 July 2014 at 08:48:08 UTC, Walter Bright wrote:
> [...]
> Since there are a lot of existing lazy algorithms in Phobos that do not follow this naming convention, either the convention is pointless or we go through yet another round of changing Phobos names and breaking everyone's code.

I'm not suggesting we rename anything. The convention would be just for when there is an existing eager function we'd like to add a lazy version of but which we can't use the original name because an overload isn't possible. It's out of necessity, not desire. I wish we didn't need new names.

> I haven't completely sold Andrei on the idea, but I feel that all algorithms should be lazy unless they have a very strong reason not to be. Being the default suggests a naming convention for them would be unnecessary even if it were practical.

Yeah, I agree. I'd hate having a "with" prefix on everything. I'm just trying to think of a consistent way to approach this issue since all of these new lazy functions in Phobos will need new names in order for us to move forward with Operation Couchpotato.

Looking over std.string at all the functions we should probably add lazy versions of the only option I can think of apart from "with" is maybe use the past participle on the ones with verbs.

So here are both options side by side for comparison:

- abbrev         : abbreviated    : withAbbrev
- capitalize     : capitalized    : withCapitalize
- center         : centered       : withCenter
- detab          : detabbed       : withDetab
- entab          : entabbed       : withEntab
- format         : formatted      : withFormat
- leftJustify    : leftJustified  : withLeftJustify
- munch          : munched        : withMunch
- outdent        : outdented      : withOutdent
- removechars    : removedChars   : withRemoveChars
- rightJustify   : rightJustified : withRightJustify
- splitLines     : splittedLines  : withSplitLines
- squeeze        : squeezed*      : withSqueeze
- strip          : stripped       : withStrip
- stripLeft      : strippedLeft   : withStripLeft
- stripRight     : strippedRight  : withStripRight
- succ           : ?              : withSucc
- toLower        : lowered        : withLower
- toStringz      : ?              : withStringz
- toUpper        : uppered        : withUpper
- tr             : ?              : withTr
- translate      : translated     : withTranslate
- wrap           : wrapped        : withWrap

* or squoze, heh

That actually works surprisingly well for the most part. succ() has a bad name anyway so I'd think we'd take the opportunity to just come up with a better one for the lazy version. Not sure what to do about tr and toStringz.

I left out soundex() and maketrans() because they are kind of different beasts (and technically return fixed sizes so a static array is probably a better option for these two anyway). I also am leaving out to[Lower,Upper]InPlace() because they should probably just take an allocator or something (maybe rename them finally while we are at it; toLowerOftenInPlaceButNotAlwaysBecauseOfVariableWidthEncoding() perhaps).

setExtension doesn't work with this approach though. I'd argue using "set" in the name was bad in the first place because it's not setting anything, it's making something new.

Maybe "with" could be for functions with no verb or a verb with an identical past and present participle, otherwise just use the paste tense of the verb.

Let's try using this rule with std.path:

- absolutePath        : withAbsolutePath
- buildNormalizedPath : builtNormalizedPath (maybe normalizedPath)
- buildPath           : builtPath           (maybe path)
- defaultExtension    : defaultedExtension  (maybe ensureExtension)
- dirName             : withDirName         (maybe dirNameOnly)
- driveName           : withDriveName       (maybe driveNameOnly)
- expandTilde         : expandedTilde
- relativePath        : withRelativePath
- setExtension        : withExtension
- stripDrive          : strippedDrive
- stripExtension      : strippedExtension

baseName() and extension() just slice (or should just slice, didn't look at the implementations) so they were left out. dirName could probably be made to not allocate.

The rule seems to work ok. Not nearly as clean and nice as it applies to std.string though.

What do you think?
July 18, 2014
On Friday, 18 July 2014 at 17:59:05 UTC, Brad Anderson wrote:
> - abbrev         : abbreviated    : withAbbrev

abbrev actually doesn't belong in this list. I probably included a few others mistakenly too.
July 18, 2014
On 07/18/2014 10:59 AM, Brad Anderson wrote:

> maybe use the past participle on the ones with verbs.

I vote 100% for past participle, 20% for "with".

> - abbrev         : abbreviated    : withAbbrev

Haha! We can't keep it abbreviated anymore though. Wait, what? :p

> - removechars    : removedChars   : withRemoveChars

It is better when the verb is at the end: charsRemoved, leftStripped (of course not to mean "has been left in a stripped state" :p), rightStripped, etc.

Ali

July 18, 2014
On Fri, Jul 18, 2014 at 05:59:03PM +0000, Brad Anderson via Digitalmars-d wrote: [...]
> Yeah, I agree. I'd hate having a "with" prefix on everything.

Yeah, "with" doesn't fit everywhere, only in some places. I think "withExtension" (or "withExt") is a very good choice of name. It may apply to a few other noun-based names, but with verb-based names it's really ugly ("withCapitalize"? Please, no!).


> I'm just trying to think of a consistent way to approach this issue since all of these new lazy functions in Phobos will need new names in order for us to move forward with Operation Couchpotato.
> 
> Looking over std.string at all the functions we should probably add lazy versions of the only option I can think of apart from "with" is maybe use the past participle on the ones with verbs.

I think this is actually a good idea. It did occur to me too.


> So here are both options side by side for comparison:
> 
> - abbrev         : abbreviated    : withAbbrev
> - capitalize     : capitalized    : withCapitalize
> - center         : centered       : withCenter

I think this shows clearly that the past participle form is much better when a verb is involved in the original name.


> - detab          : detabbed       : withDetab
> - entab          : entabbed       : withEntab

"withDetab"? Ugh! Clearly, "detabbed" is far better!


> - format         : formatted      : withFormat

ditto


[...]
> - succ           : ?              : withSucc

Ugh. "succ" is a bad name to begin with, but "withSucc"?! Wow. I don't know if we could live with the shame! :-P Maybe the lazy version should be "successor" -- since after all this *is* our chance to replace bad names. :-)


> - toLower        : lowered        : withLower

Ugh. What about "lowercased"?


> - toStringz      : ?              : withStringz

"nullTerminated"?


> - toUpper        : uppered        : withUpper

Please, "uppercased". "uppered" is just horrible in so many ways.


> - tr             : ?              : withTr

Is there any reason at all to introduce a lazy version of this, rather than merging it with "translate"? In fact, if it weren't for the danger of breaking existing code, I'd say get rid of this altogether.


> - translate      : translated     : withTranslate
> - wrap           : wrapped        : withWrap
> 
> * or squoze, heh
> 
> That actually works surprisingly well for the most part. succ() has a bad name anyway so I'd think we'd take the opportunity to just come up with a better one for the lazy version.

I'd say take over the original good name: successor. :-)


> Not sure what to do about tr and toStringz.

I vote to *not* do a lazy version of tr, since translate subsumes its functionality in a much better interface.

toStringz -> nullTerminated


> I left out soundex() and maketrans() because they are kind of
> different beasts (and technically return fixed sizes so a static array
> is probably a better option for these two anyway).

Agreed.


> I also am leaving out to[Lower,Upper]InPlace() because they should
> probably just take an allocator or something (maybe rename them
> finally while we are at it;
> toLowerOftenInPlaceButNotAlwaysBecauseOfVariableWidthEncoding()
> perhaps).

And while we're at it, replace the logo on dlang.org with a coffee cup and rename the domain to java.org. :-P


> setExtension doesn't work with this approach though. I'd argue using "set" in the name was bad in the first place because it's not setting anything, it's making something new.

Yeah perhaps it should've been named "replaceExt" or something along those lines. But anyway, "withExt" sounds like the best lazy name in this case.


> Maybe "with" could be for functions with no verb or a verb with an identical past and present participle, otherwise just use the paste tense of the verb.

Yes.


> Let's try using this rule with std.path:
> 
> - absolutePath        : withAbsolutePath

I don't like "with" in this case. How about "absolutePathOf"? Not ideal, but a notch better than "withAbsolutePath" IMO.


> - buildNormalizedPath : builtNormalizedPath (maybe normalizedPath)

I vote for "normalizedPath".


> - buildPath           : builtPath           (maybe path)

I don't like "path" 'cos it doesn't really describe what it's doing very well:

	auto components = ["path", "to", "filename"];
	auto pathname = components.path; // huh?

Makes it sound like you're finding the path to the components, rather than putting them together to make a path. What about "assemblePath"? (Not that good either, makes it confusing with "buildPath". :-/)

Or maybe "asPath"?


> - defaultExtension    : defaultedExtension  (maybe ensureExtension)

"withDefaultExtension" is better IMO.


> - dirName             : withDirName         (maybe dirNameOnly)

Eeek, no. What about "dirNameOf"?


> - driveName           : withDriveName       (maybe driveNameOnly)

"driveNameOf".


> - expandTilde         : expandedTilde

tildeExpanded.


> - relativePath        : withRelativePath

No, that sounds backwards. I propose "relativePathOf".


> - setExtension        : withExtension

OK.


> - stripDrive          : strippedDrive
> - stripExtension      : strippedExtension

Sounds OK.


> baseName() and extension() just slice (or should just slice, didn't
> look at the implementations) so they were left out. dirName could
> probably be made to not allocate.

If we ever need to, "baseNameOf" and "extensionOf" would work, I think. "dirName" could be "directoryOf" or "dirOf", perhaps.


> The rule seems to work ok. Not nearly as clean and nice as it applies to std.string though.
> 
> What do you think?

I think it's a fool's errand to try to invent a single system of naming that's blindly applied across the board. We should have some guiding principles for common cases (like "withXxx", "xxxOf", "verbed", etc.) for the sake of overall consistency, but we should consider each name on a case-to-case basis and make appropriate exceptions where it makes more sense ("tildeExpanded" sounds much better than "withExpandTilde" or "expandTildeOf" or "expandedTilde", for example).


T

-- 
"The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous
July 18, 2014
On 7/18/2014 10:59 AM, Brad Anderson wrote:
> What do you think?

I'd leaven that proposal with the observation that functions are likely to be lexically sorted by name. Hence, like functions should lexicographically be adjacent to each other.

"setExtension" and "withExtension" will be widely separated, and a user looking for such a function will likely see only one of them and not be aware of the other, which may be a better fit for him.

Note that Microsoft often adds the suffix "Ex" when creating a new version of an API function. It works well because the new and old will be sorted right next to each other. I'm not suggesting that these ranges add that particular suffix, just pointing out what others do.
July 18, 2014
On Friday, 18 July 2014 at 17:59:05 UTC, Brad Anderson wrote:
> On Friday, 18 July 2014 at 08:48:08 UTC, Walter Bright wrote:
>> [...]
>> Since there are a lot of existing lazy algorithms in Phobos that do not follow this naming convention, either the convention is pointless or we go through yet another round of changing Phobos names and breaking everyone's code.
>
> ...

What user is going to think that's intuitive? It's not a bad idea, but it's terribly complicated and it doesn't even indicate the critical property of the function: that it's lazy. Let's just prepend -Lazy to the name and call it a day. Why prepend instead of append? Because the names will be sorted in lexical order and we want abbrevLazy to show up right below abbrev.

- abbrev         : abbrevLazy
- capitalize     : capitalizeLazy
- center         : centerLazy
- detab          : detabLazy
- entab          : entabLazy
- format         : formatLazy
- leftJustify    : leftJustifyLazy
- munch          : munchLazy
- outdent        : outdentLazy
- removechars    : removedCharsLazy

...etc.
July 18, 2014
On Thursday, 17 July 2014 at 22:59:27 UTC, Brad Anderson wrote:
> Walter's prototype[1] for removing allocations from a phobos function (std.path.setExtension) got hung up on the naming of the function. It couldn't keep the same name because it differed only by return type.
>
> Walter doesn't like explicitly naming them as lazy because existing lazy functions like most of std.algorithm don't have names that state they are lazy. On the other hand, setExt is controversial because it's an arbitrary abbreviation done just to avoid the naming conflict. Not every function we'd like to see adopt the same approach would be amenable to a simple abbreviation to dodge the naming issue.
>
> I think it's probably a good time to come up with a naming scheme for these lazy versions of existing functions so things are consistent throughout Phobos.
>
> David Nadlinger offered a few ideas in the thread: setExtensionLazy, extensionSetter, or withExtension.
>
> I find the "with" prefix particularly attractive. It implies the lazy behavior, is short, and reads well when chained with other calls. Hypothetical example I gave in the Pull Request comments:
>
>   auto contents =
>       "  FILE".withStrip()
>               .withLowercase()
>               .withExtension(".txt")
>               .readText();
>
> At the risk of bikeshedding, I thought it would be useful to solicit the wider forum audience for ideas and opinions. Thoughts?
>
> 1. https://github.com/D-Programming-Language/phobos/pull/2149

Are you planning to deprecate the non-lazy functions at some (maybe very distant) point? If yes, I agree that it's a good opportunity for a cleanup, and there's no point to add prefixes/suffixes.
« First   ‹ Prev
1 2 3