www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - repeat

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
std.range has a function repeat that repeats one value forever. For 
example, repeat(42) is an infinite range containing 42, 42, 42,...

The same module also has a function replicate that repeats one value a 
specific number of times. In fact, replicate can be expressed as an 
overload of repeat, so that's what I just did (not committed yet): 
repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42 
forever. I'll put replicate on the deprecation chute.

So far so good. Now, string has its own repeat. repeat("abc", 2) returns 
the string "abcabc".

I want to generalize the functionality in string's repeat and move it 
outside std.string. There is an obvious semantic clash here. If you say 
repeat("abc", 3) did you mean one string "abcabcabc" or three strings 
"abc", "abc", and "abc"?

So we need distinct names for the functions. One repeats one value, the 
other repeats a range. Moreover, I'm thinking sometimes you want to 
repeat a range lazily, i.e. instead of producing "abcabc" just return a 
range that looks like it.

Ideas for a good naming scheme are welcome.


Andrei
Jan 17 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
How about..:

repeat("abc", 3) -> "abcabcabc"
reproduce("abc", 3) -> ["abc", "abc", "abc"]
Jan 17 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/11 12:25 PM, Andrej Mitrovic wrote:
 How about..:

 repeat("abc", 3) ->  "abcabcabc"
 reproduce("abc", 3) ->  ["abc", "abc", "abc"]

If I only told you the library has repeat and reproduce, could you be able to tell without looking at the documentation? Andrei
Jan 17 2011
parent "Manfred_Nowak" <svv1999 hotmail.com> writes:
Andrej Mitrovic wrote:

 I see your point

For native english speakers that point might be in existence; for most of the others every sequence of characters is a pure amalgamation without any semantical connotation. -manfred
Jan 17 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 01/17/2011 07:10 PM, Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.

Aha! For this reason precisely, the one producing "abcabcabc" was first called 'multiply' in Text. But then, I implemented it as '*' and '*='; seemed rather intuitive --what do you think? (various other operations are implemented as operator overloads) Could you do something similar for some algos where it makes sense (and does not feel forced)? Denis _________________ vita es estrany spir.wikidot.com
Jan 17 2011
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 17.01.2011 19:45, schrieb spir:
 On 01/17/2011 07:10 PM, Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.

Aha! For this reason precisely, the one producing "abcabcabc" was first called 'multiply' in Text. But then, I implemented it as '*' and '*='; seemed rather intuitive --what do you think? (various other operations are implemented as operator overloads) Could you do something similar for some algos where it makes sense (and does not feel forced)? Denis _________________ vita es estrany spir.wikidot.com

IMHO * (multiply) is not good because in theoretical computer science multiply is used to concatenate two words and thus concatenating a word with itself n times is word^n (pow(word, n) in mathematical terms). Cheers, - Daniel
Jan 17 2011
next sibling parent Simon Buerger <krox gmx.net> writes:
On 18.01.2011 01:24, spir wrote:
 On 01/17/2011 07:57 PM, Daniel Gibson wrote:
 IMHO * (multiply) is not good because in theoretical computer science
 multiply is used to concatenate two words and thus concatenating a word
 with itself n times is word^n (pow(word, n) in mathematical terms).

Weird. Excuse my ignorance, but how can multiply even mean concat? How is this written concretely (example welcome)? Do theoretical computer science people find this syntax a Good Thing? Denis

It is that way for formal languages. {a,b}^2 = {aa,ab,ba,bb}, so only used for sets of strings. It is logical there because * means something like cartesian product which is a concatenation of all combinations of both sets. The notation is not that logical for single strings though. Furthermore, + should mean addition, * should mean multiplication. None of them should stand for concatenation. Similar argument led to the introduction of the ~ operator in D (which is not present in C++/Java) just my point of view, Krox
Jan 17 2011
prev sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 18.01.2011 01:24, schrieb spir:
 On 01/17/2011 07:57 PM, Daniel Gibson wrote:
 IMHO * (multiply) is not good because in theoretical computer science
 multiply is used to concatenate two words and thus concatenating a word
 with itself n times is word^n (pow(word, n) in mathematical terms).

Weird. Excuse my ignorance, but how can multiply even mean concat? How is this written concretely (example welcome)? Do theoretical computer science people find this syntax a Good Thing? Denis _________________ vita es estrany spir.wikidot.com

Dunno, I'm not a theoretical computer science person, but everyone who has studied computer science and hasn't completely forgotten the theoretical classes may be confused if multiply is used for repetition :) Cheers, - Daniel
Jan 18 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 01/17/2011 07:57 PM, Daniel Gibson wrote:
 IMHO * (multiply) is not good because in theoretical computer science
 multiply is used to concatenate two words and thus concatenating a word
 with itself n times is word^n (pow(word, n) in mathematical terms).

Weird. Excuse my ignorance, but how can multiply even mean concat? How is this written concretely (example welcome)? Do theoretical computer science people find this syntax a Good Thing? Denis _________________ vita es estrany spir.wikidot.com
Jan 17 2011
prev sibling next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
It seems to me that you actually want two separate functions:

repeat("abc", 3) => ["abc", "abc", "abc"]

join(repeat("abc", 3)) => "abcabcabc"


A join function already exists in std.string and does this, although
it expects a second argument for word separator. I'd be ok with adding
a default arg to it, the empty string, so this works.


Indeed, we could do lazy this same way... have both return the
lazy ranges, and if your want the array, just call array() on it.
Though I could see that being annoying with strings - the array
probably is the common case, but this would be more conceptually pure.
Jan 17 2011
next sibling parent spir <denis.spir gmail.com> writes:
On 01/17/2011 07:53 PM, Adam Ruppe wrote:
 It seems to me that you actually want two separate functions:

 repeat("abc", 3) =>  ["abc", "abc", "abc"]

 join(repeat("abc", 3)) =>  "abcabcabc"

Would rather see: repeat("abc", 3) => ["abc", "abc", "abc"] "abc" * 3 => "abcabcabc" Denis _________________ vita es estrany spir.wikidot.com
Jan 17 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 17, 2011 10:59:16 spir wrote:
 On 01/17/2011 07:53 PM, Adam Ruppe wrote:
 It seems to me that you actually want two separate functions:
 
 repeat("abc", 3) =>  ["abc", "abc", "abc"]
 
 join(repeat("abc", 3)) =>  "abcabcabc"

Would rather see: repeat("abc", 3) => ["abc", "abc", "abc"] "abc" * 3 => "abcabcabc"

Considering that D add the ~ operator for concatenation because + was too ambiguous (e.g. what should "2" + "3" do?), there's no way that overloading * for a function in std.algorithm is going to fly. And since we're dealing with arbitrary range types - not just strings - it definitely isn't going to work. Not to mention, using an operator like that implies that it'sa basic and important operation. However, I'm not sure that I've ever had to use such an operation in my entire life. It needs a normal function, not an overloaded operator. - Jonathan M Davis
Jan 17 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Considering that D add the ~ operator for concatenation because + was too 
 ambiguous (e.g. what should "2" + "3" do?), there's no way that overloading * 
 for a function in std.algorithm is going to fly.

I think D has used the ~ operator to do that, despite the + is much more common for this operation and the ~ character is not present on some keyboards, because the + is normally meant to be a commutative op, while the array/string concatenation is not commutative (3+5==5+3 but "ab"~"cd"!="cd"~"ab"). In the case of * for string/array multiplication it's associative, commutative, distributive and it has both identity and zero elements, so I don't think there are the same problems.
 However, I'm not sure that I've ever had to use such an operation in 
 my entire life.

This little Python2 program shows a normal usage of the string multiplication: n = 6 s = "+---" * n + "+" print s for i in xrange(5): print "| " * n + "|" print s It prints: +---+---+---+---+---+---+ | | | | | | | +---+---+---+---+---+---+ | | | | | | | +---+---+---+---+---+---+ | | | | | | | +---+---+---+---+---+---+ | | | | | | | +---+---+---+---+---+---+ | | | | | | | +---+---+---+---+---+---+ Bye, bearophile
Jan 17 2011
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
bearophile Wrote:

 n = 6
 s = "+---" * n + "+"
 print s
 for i in xrange(5):
     print "|   " * n + "|"
     print s

Are you saying that (sorry not testing, but since this is fictional at this time anyway): auto n = 6; auto s = join(repeat("+---", n), "+"); print s; foreach(i; 0..5) { writeln(join(repeat("| ", n), "|")); writeln(s); } isn't good enough? Maybe there is a performance benefit to not needing join?
Jan 17 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Jesse Phillips:

 Are you saying that (sorry not testing, but since this is fictional at this
time anyway):

I have printed similar ASCII tables some times, it was an almost real example.
 isn't good enough?

I am saying that repeat() is worse than a multiplication sign. I am aware you are usually able to replace operators with functions. Operators are functions, written using another syntax. Even if people around here keep showing me equivalent ways to do things, I find some Python syntax sugar better than D equivalents. List comprehensions, tuple unpacking syntax, tuple destructuring in function signatures, "in" for presence in a linear collection, etc, and sometimes even string multiplications (among those tuple unpacking syntax is probably the most useful and I still hope to see it in future D. I am losing hope to see array/lazy comprehensions in D).
 Maybe there is a performance benefit to not needing join?

In D I write that with no join (untested): auto s = "+---".repeat(n) ~ "+"; When you want to write an ASCII grid performance is usually not so important. It's more about the amount of cognitive friction, that's here in D is a bit higher. Bye, bearophile
Jan 17 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/11 2:15 PM, Jonathan M Davis wrote:
 On Monday, January 17, 2011 10:59:16 spir wrote:
 On 01/17/2011 07:53 PM, Adam Ruppe wrote:
 It seems to me that you actually want two separate functions:

 repeat("abc", 3) =>   ["abc", "abc", "abc"]

 join(repeat("abc", 3)) =>   "abcabcabc"

Would rather see: repeat("abc", 3) => ["abc", "abc", "abc"] "abc" * 3 => "abcabcabc"

Considering that D add the ~ operator for concatenation because + was too ambiguous (e.g. what should "2" + "3" do?), there's no way that overloading * for a function in std.algorithm is going to fly. And since we're dealing with arbitrary range types - not just strings - it definitely isn't going to work. Not to mention, using an operator like that implies that it'sa basic and important operation. However, I'm not sure that I've ever had to use such an operation in my entire life. It needs a normal function, not an overloaded operator.

I just moved join from string to array, defined multiply to copy a range multiple times into an array, and changed replicate to repeat: http://www.dsource.org/projects/phobos/changeset/2343 http://d-programming-language.org/cutting-edge/phobos/std_array.html http://d-programming-language.org/cutting-edge/phobos/std_string.html Andrei
Jan 17 2011
prev sibling parent so <so so.do> writes:
On Mon, 17 Jan 2011 20:53:33 +0200, Adam Ruppe <destructionator gmail.com>  
wrote:

 It seems to me that you actually want two separate functions:

 repeat("abc", 3) => ["abc", "abc", "abc"]

 join(repeat("abc", 3)) => "abcabcabc"


 A join function already exists in std.string and does this, although
 it expects a second argument for word separator. I'd be ok with adding
 a default arg to it, the empty string, so this works.


 Indeed, we could do lazy this same way... have both return the
 lazy ranges, and if your want the array, just call array() on it.
 Though I could see that being annoying with strings - the array
 probably is the common case, but this would be more conceptually pure.

As always, Adam has the solution! Or maybe overload it like: join("abc", 3)
Jan 18 2011
prev sibling next sibling parent Caligo <iteronvexor gmail.com> writes:
--000e0cd2df0a5201fb049a0f616c
Content-Type: text/plain; charset=ISO-8859-1

How is this:

repeat("abc", 3) -> ["abc", "abc", "abc"]

repeated("abc", 3) -> "abcabcabc"

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

How is this:<div><br><span class=3D"Apple-style-span" style=3D"font-family:=
 arial, sans-serif; font-size: 13px; border-collapse: collapse; ">repeat(&q=
uot;abc&quot;, 3) -&gt; [&quot;abc&quot;, &quot;abc&quot;, &quot;abc&quot;]=
</span></div>
<div><span class=3D"Apple-style-span" style=3D"font-family: arial, sans-ser=
if; font-size: 13px; border-collapse: collapse; "><br></span></div><div><sp=
an class=3D"Apple-style-span" style=3D"font-family: arial, sans-serif; font=
-size: 13px; border-collapse: collapse; ">repeated(&quot;abc&quot;, 3) -&gt=
; &quot;abcabcabc&quot;</span></div>

--000e0cd2df0a5201fb049a0f616c--
Jan 17 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/17/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 1/17/11 12:25 PM, Andrej Mitrovic wrote:
 How about..:

 repeat("abc", 3) ->  "abcabcabc"
 reproduce("abc", 3) ->  ["abc", "abc", "abc"]

If I only told you the library has repeat and reproduce, could you be able to tell without looking at the documentation? Andrei

Yeah, I see your point. Other names that come to mind are duplicate, replicate, clone, repeatRange..
Jan 17 2011
prev sibling next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 17.01.2011 19:10, schrieb Andrei Alexandrescu:
 std.range has a function repeat that repeats one value forever. For example,
 repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value a specific
 number of times. In fact, replicate can be expressed as an overload of repeat,
 so that's what I just did (not committed yet): repeat(42, 100) repeats 42 one
 hundred times, repeat(42) repeats 42 forever. I'll put replicate on the
 deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) returns the
 string "abcabc".

 I want to generalize the functionality in string's repeat and move it outside
 std.string. There is an obvious semantic clash here. If you say repeat("abc",
3)
 did you mean one string "abcabcabc" or three strings "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the other
 repeats a range. Moreover, I'm thinking sometimes you want to repeat a range
 lazily, i.e. instead of producing "abcabc" just return a range that looks like
it.

 Ideas for a good naming scheme are welcome.


 Andrei

You could only supply repeat, returning ["abc","abc",..] And also concat (is there really no concat in std.algorithm? Maybe bringToFront.. but a concat that gets a range of ranges may be useful) so people can do something like concat(repeat("abc", 42)) (functional style) Cheers, - Daniel
Jan 17 2011
prev sibling next sibling parent reply Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Andrei Alexandrescu napisa=B3:

 std.range has a function repeat that repeats one value forever. For=20
 example, repeat(42) is an infinite range containing 42, 42, 42,...
=20
 The same module also has a function replicate that repeats one value a=20
 specific number of times. In fact, replicate can be expressed as an=20
 overload of repeat, so that's what I just did (not committed yet):=20
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42=20
 forever. I'll put replicate on the deprecation chute.
=20
 So far so good. Now, string has its own repeat. repeat("abc", 2) returns=

 the string "abcabc".
=20
 I want to generalize the functionality in string's repeat and move it=20
 outside std.string. There is an obvious semantic clash here. If you say=20
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings=20
 "abc", "abc", and "abc"?
=20
 So we need distinct names for the functions. One repeats one value, the=20
 other repeats a range. Moreover, I'm thinking sometimes you want to=20
 repeat a range lazily, i.e. instead of producing "abcabc" just return a=20
 range that looks like it.
=20
 Ideas for a good naming scheme are welcome.

Overload cycle and call it a day? --=20 Tomek
Jan 17 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/11 1:53 PM, Tomek Sowiński wrote:
 Andrei Alexandrescu napisał:

 std.range has a function repeat that repeats one value forever. For
 example, repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value a
 specific number of times. In fact, replicate can be expressed as an
 overload of repeat, so that's what I just did (not committed yet):
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42
 forever. I'll put replicate on the deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) returns
 the string "abcabc".

 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.

Overload cycle and call it a day?

cycle(r, n) already has a meaning: cycle r for a maximum total of n elements. Andrei
Jan 17 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/11 2:14 PM, Tomek Sowiński wrote:
 Andrei Alexandrescu napisał:

 On 1/17/11 1:53 PM, Tomek Sowiński wrote:
 Andrei Alexandrescu napisał:

 std.range has a function repeat that repeats one value forever. For
 example, repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value a
 specific number of times. In fact, replicate can be expressed as an
 overload of repeat, so that's what I just did (not committed yet):
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42
 forever. I'll put replicate on the deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) returns
 the string "abcabc".

 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.

Overload cycle and call it a day?

cycle(r, n) already has a meaning: cycle r for a maximum total of n elements.

Now I'm confused. The docs say it's an initial index...

Sorry, my bad. You're right. Still, cycle(r, n) has a meaning distinct from what we might need. Essentially I'm looking for a name for the function array(take(cycle(range), n * range.length)). That's what std.string.repeat does currently. Andrei
Jan 17 2011
prev sibling next sibling parent Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Andrei Alexandrescu napisa=B3:

 On 1/17/11 1:53 PM, Tomek Sowi=F1ski wrote:
 Andrei Alexandrescu napisa=B3:

 std.range has a function repeat that repeats one value forever. For
 example, repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value a
 specific number of times. In fact, replicate can be expressed as an
 overload of repeat, so that's what I just did (not committed yet):
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42
 forever. I'll put replicate on the deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) retur=



 the string "abcabc".

 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.

Overload cycle and call it a day?

cycle(r, n) already has a meaning: cycle r for a maximum total of n=20 elements.

Now I'm confused. The docs say it's an initial index... --=20 Tomek
Jan 17 2011
prev sibling next sibling parent Tomek =?ISO-8859-2?Q?Sowi=F1ski?= <just ask.me> writes:
Andrei Alexandrescu napisa=B3:

 On 1/17/11 2:14 PM, Tomek Sowi=F1ski wrote:
 Andrei Alexandrescu napisa=B3:

 On 1/17/11 1:53 PM, Tomek Sowi=F1ski wrote:
 Andrei Alexandrescu napisa=B3:

 std.range has a function repeat that repeats one value forever. For
 example, repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value=





 specific number of times. In fact, replicate can be expressed as an
 overload of repeat, so that's what I just did (not committed yet):
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42
 forever. I'll put replicate on the deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) ret=





 the string "abcabc".

 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you =





 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, =





 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just retur=





 range that looks like it.

 Ideas for a good naming scheme are welcome.

Overload cycle and call it a day?

cycle(r, n) already has a meaning: cycle r for a maximum total of n elements.

Now I'm confused. The docs say it's an initial index...

Sorry, my bad. You're right. Still, cycle(r, n) has a meaning distinct=20 from what we might need.

I don't think the initial index really useful (even the authors confirm by = not bothering to unittest it:-)) My idea is to dump it in favor of popFront= N (provide a method on Cycle, let the stand-alone popFrontN statically reco= gnize that). Bounding an infinite range is much more frequent. Or, if you're really not keen on the idea, introduce cycleN.
 Essentially I'm looking for a name for the=20
 function array(take(cycle(range), n * range.length)). That's what=20
 std.string.repeat does currently.

With the above cycleN(range, n * range.length).array() doesn't look that ba= d. What are the use-cases that you want a separate name? --=20 Tomek
Jan 17 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 01/17/2011 09:15 PM, Jonathan M Davis wrote:
 On Monday, January 17, 2011 10:59:16 spir wrote:
 On 01/17/2011 07:53 PM, Adam Ruppe wrote:
 It seems to me that you actually want two separate functions:

 repeat("abc", 3) =>   ["abc", "abc", "abc"]

 join(repeat("abc", 3)) =>   "abcabcabc"

Would rather see: repeat("abc", 3) => ["abc", "abc", "abc"] "abc" * 3 => "abcabcabc"

Considering that D add the ~ operator for concatenation because + was too ambiguous (e.g. what should "2" + "3" do?), there's no way that overloading * for a function in std.algorithm is going to fly. And since we're dealing with arbitrary range types - not just strings - it definitely isn't going to work. Not to mention, using an operator like that implies that it'sa basic and important operation. However, I'm not sure that I've ever had to use such an operation in my entire life. It needs a normal function, not an overloaded operator.

Right, I understand your point and agree (will change Text's method accordingly when a good name is agreed upon). What about "times"? I had to use this function rather often (else, wouldn't had bothered with it in Text); string types I know from other languages have it builtin as well, so it certainly is a common need (and as you see Andrei provides it as builtin algo as well). About arbitrary ranges, is repeat([1,2,3], 3) supposed to produce [ [1,2,3] , [1,2,3] , [1,2,3] ] ? Denis _________________ vita es estrany spir.wikidot.com
Jan 17 2011
prev sibling next sibling parent Gareth Charnock <gareth.charnock gmail.com> writes:
On 17/01/11 18:10, Andrei Alexandrescu wrote:
 std.range has a function repeat that repeats one value forever. For
 example, repeat(42) is an infinite range containing 42, 42, 42,...

 The same module also has a function replicate that repeats one value a
 specific number of times. In fact, replicate can be expressed as an
 overload of repeat, so that's what I just did (not committed yet):
 repeat(42, 100) repeats 42 one hundred times, repeat(42) repeats 42
 forever. I'll put replicate on the deprecation chute.

 So far so good. Now, string has its own repeat. repeat("abc", 2) returns
 the string "abcabc".

 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you say
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings
 "abc", "abc", and "abc"?

 So we need distinct names for the functions. One repeats one value, the
 other repeats a range. Moreover, I'm thinking sometimes you want to
 repeat a range lazily, i.e. instead of producing "abcabc" just return a
 range that looks like it.

 Ideas for a good naming scheme are welcome.


 Andrei

Perhaps... repeat("abc",3) -> ["abc","abc","abc"] repeatFlatten("abc",3) -> "abcabcabc" or perhaps repeatFlat("abc",3) ?
Jan 17 2011
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it 
 outside std.string. There is an obvious semantic clash here. If you say 
 repeat("abc", 3) did you mean one string "abcabcabc" or three strings 
 "abc", "abc", and "abc"?

Just a thought: concat(repeat("abc",3)) yields "abcabcabc" ?
Jan 18 2011
next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 18.01.2011 10:07, schrieb Walter Bright:
 Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it outside
 std.string. There is an obvious semantic clash here. If you say repeat("abc",
 3) did you mean one string "abcabcabc" or three strings "abc", "abc", and
"abc"?

Just a thought: concat(repeat("abc",3)) yields "abcabcabc" ?

:-)
Jan 18 2011
prev sibling next sibling parent reply Christopher Nicholson-Sauls <ibisbasenji gmail.com> writes:
On 01/18/11 03:07, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you
 say repeat("abc", 3) did you mean one string "abcabcabc" or three
 strings "abc", "abc", and "abc"?

Just a thought: concat(repeat("abc",3)) yields "abcabcabc" ?

Nah. Too obvious. On a more serious note, I have no issue with join(repeat("abc",3)). -- Chris N-S
Jan 18 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
Christopher Nicholson-Sauls wrote:
 On 01/18/11 03:07, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you
 say repeat("abc", 3) did you mean one string "abcabcabc" or three
 strings "abc", "abc", and "abc"?

concat(repeat("abc",3)) yields "abcabcabc" ?

Nah. Too obvious. On a more serious note, I have no issue with join(repeat("abc",3)).

Eh, I forgot about join!
Jan 18 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/11 3:24 PM, Walter Bright wrote:
 Christopher Nicholson-Sauls wrote:
 On 01/18/11 03:07, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you
 say repeat("abc", 3) did you mean one string "abcabcabc" or three
 strings "abc", "abc", and "abc"?

concat(repeat("abc",3)) yields "abcabcabc" ?

Nah. Too obvious. On a more serious note, I have no issue with join(repeat("abc",3)).

Eh, I forgot about join!

It's Porsche-uh (and join-er). Andrei
Jan 18 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/11 3:07 AM, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 I want to generalize the functionality in string's repeat and move it
 outside std.string. There is an obvious semantic clash here. If you
 say repeat("abc", 3) did you mean one string "abcabcabc" or three
 strings "abc", "abc", and "abc"?

Just a thought: concat(repeat("abc",3)) yields "abcabcabc" ?

Actually we already have join. Fortunately repeat in std.range is lazy, which avoid multiple memory allocations. I only need to make join accept general ranges. Question is, do we deprecate std.string.repeat? Andrei
Jan 18 2011
prev sibling parent reply "Aziz K." <aziz.koeksal gmail.com> writes:
I would prefer it to work like this:

repeat("abc", 3) -> "abcabcabc"
repeat(["abc"], 3) -> ["abc","abc","abc"]
repeat([1,2,3], 3) -> [1,2,3,1,2,3,1,2,3]


-- 
Dil D compiler: http://code.google.com/p/dil/
Jan 18 2011
next sibling parent spir <denis.spir gmail.com> writes:
On 01/18/2011 01:10 PM, Aziz K. wrote:
 I would prefer it to work like this:

 repeat("abc", 3) -> "abcabcabc"
 repeat(["abc"], 3) -> ["abc","abc","abc"]
 repeat([1,2,3], 3) -> [1,2,3,1,2,3,1,2,3]

I find this consistent in that the operation keeps the nesting level constant. But then we need a good name for an operation that nests into a higher-level array ;-) What about arrayOf (T) (T something, uint count=1) ? arrayOf("abc", 3) -> ["abc","abc","abc"] arrayOf(["abc"], 3) -> [["abc"],["abc"],["abc"]] arrayOf([1,2,3], 3) -> [[1,2,3],[1,2,3],[1,2,3]] Denis _________________ vita es estrany spir.wikidot.com
Jan 18 2011
prev sibling parent "Aziz K." <aziz.koeksal gmail.com> writes:
Okay, so your arrayOf() function could be written as:

   auto arrayOf(T x, uint n){ return repeat([x], n); }

Only needs to wrap the argument inside another array literal.
Jan 18 2011