## digitalmars.D - "Consume", "Skip", "Eat", "Munch", "Bite", or...?

Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```To focus the discussion about naming conventions, let's discuss one
particular aspect. Right now we have in std.algorithm:

=======================
/**
If the range \$(D doesThisStart) starts with \$(I any) of the \$(D
withOneOfThese) ranges or elements, returns 1 if it starts with \$(D
withOneOfThese[0]), 2 if it starts with \$(D withOneOfThese[1]), and so
on. If no match, returns 0.

Example:
----
assert(startsWith("abc", ""));
assert(startsWith("abc", "a"));
assert(!startsWith("abc", "b"));
assert(startsWith("abc", 'a', "b") == 1);
assert(startsWith("abc", "b", "a") == 2);
assert(startsWith("abc", "a", "a") == 1);
assert(startsWith("abc", "x", "a", "b") == 2);
assert(startsWith("abc", "x", "aa", "ab") == 3);
assert(startsWith("abc", "x", "aaa", "sab") == 0);
assert(startsWith("abc", "x", "aaa", 'a', "sab") == 3);
----
*/
uint startsWith(alias pred = "a == b", Range, Ranges...)
(Range doesThisStart, Ranges withOneOfThese);
=======================

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Andrei
```
Feb 20 2010
div0 <div0 users.sourceforge.net> writes:
```-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andrei Alexandrescu wrote:
There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Andrei

chomp?
consume is probably best; it's very clear.

- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFLgFubT9LetA9XoXwRArf2AKDHBXyi7hHoxZFLN0yS8HZiOPiFKwCeIbpK
qNmv5S4We3wdkuRDVLAXmsg=
=01Ac
-----END PGP SIGNATURE-----
```
Feb 20 2010
Michel Fortin <michel.fortin michelf.com> writes:
```On 2010-02-20 15:48:10 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> said:

To focus the discussion about naming conventions, let's discuss one
particular aspect. Right now we have in std.algorithm:

=======================
/**
If the range \$(D doesThisStart) starts with \$(I any) of the \$(D
withOneOfThese) ranges or elements, returns 1 if it starts with \$(D
withOneOfThese[0]), 2 if it starts with \$(D withOneOfThese[1]), and so
on. If no match, returns 0.

Example:
----
assert(startsWith("abc", ""));
assert(startsWith("abc", "a"));
assert(!startsWith("abc", "b"));
assert(startsWith("abc", 'a', "b") == 1);
assert(startsWith("abc", "b", "a") == 2);
assert(startsWith("abc", "a", "a") == 1);
assert(startsWith("abc", "x", "a", "b") == 2);
assert(startsWith("abc", "x", "aa", "ab") == 3);
assert(startsWith("abc", "x", "aaa", "sab") == 0);
assert(startsWith("abc", "x", "aaa", 'a', "sab") == 3);
----
*/
uint startsWith(alias pred = "a == b", Range, Ranges...)
(Range doesThisStart, Ranges withOneOfThese);
=======================

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Instead of "startsWithConsume" you could use "consumePrefix" which
sounds better. You could change "startsWith" to "hasPrefix" too to keep
things consistent, even though "startsWith" isn't a bad name in itself.

The small string parsing module I made has "consumeUntil" that consumes
until a predicate tells it to stop.

In fact, all my consuming primitives advancing over the string and
returning a boolean starts with "consume", this makes their role very
clear. I also have a "read" family of function that uses consumers as
predicate to extract consumed strings return them. So I can write fun
things like this:

alias isChar!(' ') isSpace;
alias isNotChar!(' ') isNotSpace;
alias consumeOneWhile!(isNotSpace) consumeWord;
alias consumeOneWhile!(isSpace) consumeSpaces;

string a = "hello world  of fear  ! ";
assert(result == ["hello", "world", "of", "fear", "!"]);

--
Michel Fortin
michel.fortin michelf.com
http://michelf.com/
```
Feb 20 2010
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```Michel Fortin wrote:
On 2010-02-20 15:48:10 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> said:

To focus the discussion about naming conventions, let's discuss one
particular aspect. Right now we have in std.algorithm:

=======================
/**
If the range \$(D doesThisStart) starts with \$(I any) of the \$(D
withOneOfThese) ranges or elements, returns 1 if it starts with \$(D
withOneOfThese[0]), 2 if it starts with \$(D withOneOfThese[1]), and so
on. If no match, returns 0.

Example:
----
assert(startsWith("abc", ""));
assert(startsWith("abc", "a"));
assert(!startsWith("abc", "b"));
assert(startsWith("abc", 'a', "b") == 1);
assert(startsWith("abc", "b", "a") == 2);
assert(startsWith("abc", "a", "a") == 1);
assert(startsWith("abc", "x", "a", "b") == 2);
assert(startsWith("abc", "x", "aa", "ab") == 3);
assert(startsWith("abc", "x", "aaa", "sab") == 0);
assert(startsWith("abc", "x", "aaa", 'a', "sab") == 3);
----
*/
uint startsWith(alias pred = "a == b", Range, Ranges...)
(Range doesThisStart, Ranges withOneOfThese);
=======================

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range
by value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Instead of "startsWithConsume" you could use "consumePrefix" which
sounds better. You could change "startsWith" to "hasPrefix" too to keep
things consistent, even though "startsWith" isn't a bad name in itself.

But how about others? What is the overall convention? Also don't forget
that many other languages have startsWith. I don't find hasPrefix
terribly informative. a.hasAsPrefix(b) would be more like it, but then
again Yigal's fantastic consistent naming scheme remains elusive.

Andrei
```
Feb 20 2010
Michel Fortin <michel.fortin michelf.com> writes:
```On 2010-02-20 19:12:21 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> said:

But how about others? What is the overall convention?

In my module the convention was to always start the name with
"consume". I had "consumeOneChar" with a predicate checking one
character, "consumeOneString" for matching specific strings (same as
your "startWith"), "consumeWhile" and "consumeUntil" taking a character
predicate,  "consumeCount" for repeating consuming something, etc.
Through the module, "consume" is implying I am reading from the front
of the string and consuming from there.

Also don't forget that many other languages have startsWith. I don't
find hasPrefix terribly informative. a.hasAsPrefix(b) would be more
like it, but then again Yigal's fantastic consistent naming scheme
remains elusive.

Cocoa's NSString use hasPrefix (that's where I got the idea). To me
both sound right. assert("exoplanet".hasPrefix("exo")). :-)

I don't really have a problem with startWith, it just doesn't fit very
well with "consume". But if like me you assume "from the front" to be
implicitly part of the meaning of "consume", then you don't need the
"startWith" part. :-) You could use "consumeFront" to make things
absolutely clear.

--
Michel Fortin
michel.fortin michelf.com
http://michelf.com/
```
Feb 20 2010
Jonathan M Davis <jmdavisProg gmail.com> writes:
```Andrei Alexandrescu wrote:

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Andrei

I thought that that was basically what chompPrefix did, and chompPrefix
seems like a great name to me, but I guess that that's not entirely
generalizable: chompFind or findChomp would be a bit weird. Consume seems
like the best of the ones that you suggested. It is explicitly what you're
doing. It's a bit long, but the others aren't as clear. Other suggestions
might be erase or remove, since you appear to be erasing/removing elements
from the range. Consume is probably better though.

- Jonathan M Davis

P.S. You could also go for startsWithFineDiningWithAFourCourseMeal. People
would absolutely love _that_ function name. ;)
```
Feb 20 2010
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```Jonathan M Davis wrote:
Andrei Alexandrescu wrote:

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Andrei

I thought that that was basically what chompPrefix did, and chompPrefix
seems like a great name to me, but I guess that that's not entirely
generalizable: chompFind or findChomp would be a bit weird. Consume seems
like the best of the ones that you suggested. It is explicitly what you're
doing. It's a bit long, but the others aren't as clear. Other suggestions
might be erase or remove, since you appear to be erasing/removing elements
from the range. Consume is probably better though.

- Jonathan M Davis

P.S. You could also go for startsWithFineDiningWithAFourCourseMeal. People
would absolutely love _that_ function name. ;)

Heh.

Overall the problem of choosing names by consensus is that the
intersection is withering real fast. I agree 80% with Kenny's and
Michel's choices. Others also seem to agree about the same percentage.
The problem is that nobody agrees on the _same_ 80%. The net
intersection of several people's "obviously good" naming schemes and
conventions quickly falls to zero as the size of the group increases.

Andrei
```
Feb 20 2010
Jonathan M Davis <jmdavisProg gmail.com> writes:
``` Heh.

Overall the problem of choosing names by consensus is that the
intersection is withering real fast. I agree 80% with Kenny's and
Michel's choices. Others also seem to agree about the same percentage.
The problem is that nobody agrees on the _same_ 80%. The net
intersection of several people's "obviously good" naming schemes and
conventions quickly falls to zero as the size of the group increases.

Andrei

Well, then it's probably a case where you should find a naming scheme that
you're happy with and is relatively clear to most people. There are always
going to be people who don't like a particular name or think that one name
is clearer than another. So, it seems like it would be a good idea to get
some suggestions for names (like you're doing), pick what you like, verify
that there not considered horrifically bad by the group (though that doesn't
mean that the group agrees with them), and then just use them. As long as
the names are fairly clear, I don't think that it matters all that much. I
know that even if I were picking all of the names myself, there would be
bound to be a few that I didn't like because they were too long or following
a particular naming convention made some of the functions have poorer names
than I'd like, so I certainly don't expect you to come up with names that
I'd like perfectly if I can't. And, as you say, a naming scheme that I like
perfectly would undoubtedly be disliked by others, even if you could find
it.

Find a naming scheme you like and go with it. I'd say that the most
important things for the names are that they are relatively clear and
consistent. When it comes down to it, it's what the functions actually do
which matters most. Beyond that, we just need the names to clearly indicate
that function. So, names are important, but don't kill yourself over them.

- Jonathan M Davis
```
Feb 20 2010
Jonathan M Davis <jmdavisProg gmail.com> writes:
```Oh, and while some names seem odd at first, they can definitely grow on you.
For instance, I thought that retro was quite odd at first, but I'm
definitely starting to like it. I would have suggested reverse (which I
guess was out due to arrays), or maybe rev, but retro is shorter than
reverse and I think ultimately clearer than rev. retro is quite memorable,
is short, isn't an abbreviation, and fits fairly well once you get past the
initial bizarreness of it.

While there may be complaints about some weird function names now, people
will get used to them and may even prefer them. Like many things in Computer
"Science," picking functions names is definitely an art - and a very
imprecise one at that.

- Jonathan M Davis
```
Feb 20 2010
Lutger <lutger.blijdestijn gmail.com> writes:
```Andrei Alexandrescu wrote:

Jonathan M Davis wrote:
Andrei Alexandrescu wrote:

I also defined recently:

=======================
/**
If \$(D startsWith(r1, r2)), consume the corresponding elements off \$(D
r1) and return \$(D true). Otherwise, leave \$(D r1) unchanged and
return \$(D false).
*/
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);
=======================

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind.

Andrei

I thought that that was basically what chompPrefix did, and chompPrefix
seems like a great name to me, but I guess that that's not entirely
generalizable: chompFind or findChomp would be a bit weird. Consume seems
like the best of the ones that you suggested. It is explicitly what
you're doing. It's a bit long, but the others aren't as clear. Other
suggestions might be erase or remove, since you appear to be
erasing/removing elements from the range. Consume is probably better
though.

- Jonathan M Davis

P.S. You could also go for startsWithFineDiningWithAFourCourseMeal.
People would absolutely love _that_ function name. ;)

Heh.

Overall the problem of choosing names by consensus is that the
intersection is withering real fast. I agree 80% with Kenny's and
Michel's choices. Others also seem to agree about the same percentage.
The problem is that nobody agrees on the _same_ 80%. The net
intersection of several people's "obviously good" naming schemes and
conventions quickly falls to zero as the size of the group increases.

Andrei

Yeah, but everybody does agree that consistency is the overriding concern.
There is still consistency to be gained between std.file / std.string /
std.algorithm etc. (more so than in std.algorithm itself).

Consistency is hard though, because you have to make up rules for something
that is connected to natural language, and a messy one too. Luckily english
has a freaking huge vocabulary :)

On a related note, thanks for reordering take's parameters.
```
Feb 22 2010
"Adam D. Ruppe" <destructionator gmail.com> writes:
```On Sat, Feb 20, 2010 at 02:48:10PM -0600, Andrei Alexandrescu wrote:
bool startsWithConsume(R1, R2)(ref R1 r1, R2 r2);

I rather like that. I didn't at first, but I tried think of alternatives
and everything came up short.

xxxxConsume() it a nice, short way of saying "if xxxx, consume xxxx". It
rather reminds me of the convenience functions in ncurses - looks weird
at first, but it is a very simple rule to learn.

Another nice thing about putting it at the end, is my editor's autocomplete
would kick right in. I type "startsWith", hit tab and see the various
modifiers. Minor thing, but I'd like it. They start exactly the same.

The more I think about it, the more I like it.

--
http://arsdnet.net
```
Feb 20 2010
Philippe Sigaud <philippe.sigaud gmail.com> writes:
```--0015174c35aa670def04801c2321
Content-Type: text/plain; charset=ISO-8859-1

On Sat, Feb 20, 2010 at 21:48, Andrei Alexandrescu <
SeeWebsiteForEmail erdani.org> wrote:

To focus the discussion about naming conventions, let's discuss one
particular aspect. Right now we have in std.algorithm:

There are a few other functions like that: one version takes a range by
value, the other takes it by reference and alters it.

The question is, what is a good naming convention for expressing that?
Other examples: findConsume, consumeFind

Would using policies be a solution?

enum ModificationPolicy { doesNotModify, Modifies};

That way, you can keep the same name throughout the module.

And the same for eager or lazy versions of some algorithms. Map/Filter could
be eager rather than lazy (though I like them lazy) and return an array.

Would that be possible, with well-thought defaults?

Philippe

--0015174c35aa670def04801c2321
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Sat, Feb 20, 2010 at 21:48, Andrei Alexandrescu <span dir=3D"ltr">&lt;<a=
href=3D"mailto:SeeWebsiteForEmail erdani.org">SeeWebsiteForEmail erdani.or=
g</a>&gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"=
gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb=
To focus the discussion about naming conventions, let&#39;s discuss one par=
ticular aspect. Right now we have in std.algorithm:<br></blockquote><div>(s=
nip) <br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0=
pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

There are a few other functions like that: one version takes a range by val=
ue, the other takes it by reference and alters it.<br>
<br>
The question is, what is a good naming convention for expressing that? Othe=
r examples: findConsume, consumeFind</blockquote><div><br>Would using polic=
ies be a solution?<br><br>enum ModificationPolicy { doesNotModify, Modifies=
};<br>
<br>That way, you can keep the same name throughout the module.<br><br>And =
the same for eager or lazy versions of some algorithms. Map/Filter could be=
eager rather than lazy (though I like them lazy) and return an array.<br>
<br>Would that be possible, with well-thought defaults?<br><br><br>=A0 Phil=
ippe<br><br><br>=A0</div></div>

--0015174c35aa670def04801c2321--
```
Feb 21 2010