digitalmars.D.learn - string initialization question.
- dcoder (9/9) Jul 30 2010 Hello.
- Steven Schveighoffer (8/19) Jul 30 2010 It's most likely complaining about rowstr.length not being a constant, n...
- Justin Spahr-Summers (5/38) Jul 30 2010 Something like this will work on the heap:
- Steven Schveighoffer (5/16) Jul 30 2010 That assigns 0xff to all divider chars, and then assigns '-'. I think
- bearophile (8/13) Jul 30 2010 In past there was some way to do that:
- Steven Schveighoffer (8/22) Jul 30 2010 I was wrong, I looked through the runtime and did not find such a functi...
- Jonathan M Davis (22/23) Jul 30 2010 Well, creating a function for producing an array literal and returning i...
- Steven Schveighoffer (9/28) Jul 30 2010 The function would call gc_malloc directly, which does not initialize th...
- Jonathan M Davis (13/48) Jul 30 2010 Well, if there's a function other than new to allocate GC memory, then
- Steven Schveighoffer (10/26) Jul 30 2010 To be clear, the compiler could do the optimization if it had another
- bearophile (4/7) Jul 30 2010 Doesn't the D2 GC give you a lower level function to GC-allocate uniniti...
- dcoder (8/18) Jul 30 2010 If I'm writing a program that pretty prints tree data, or output of sql,...
- Philippe Sigaud (4/11) Jul 30 2010 There is fill() in std.algorithm, but it needs an already present range....
- Jonathan M Davis (16/24) Jul 30 2010 Well, I certainly have no problem with a function like makeArray() exist...
- Justin Spahr-Summers (13/26) Jul 30 2010 I agree with this sentiment. I think the feature is pretty niche to
- Steven Schveighoffer (21/53) Aug 02 2010 That's because it's not a trivial function to write :) One has to have ...
- Jason Spencer (10/11) Jul 31 2010 function.
- Steven Schveighoffer (5/15) Aug 02 2010 It doesn't do the right thing. It allocates, then initializes, resultin...
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (19/21) Jul 30 2010 If you need to only print, you can:
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (4/5) Jul 30 2010 Oh, and if repeat had slicing (as it should)... '-'.repeat[0..5]
Hello. Is there anyway in D to convenient fill a string variable with a char say X times? So, I'd like to do something like: string divider( size, '-'); // C++ notation. $divider = '-' x $size; // perl notation. I thought I could do the following: const char divider[rowstr.length] = '-'; but the compiler complains about not having a constant integer expression. thanks.
Jul 30 2010
On Fri, 30 Jul 2010 11:24:41 -0400, dcoder <dcoder devnull.com> wrote:Hello. Is there anyway in D to convenient fill a string variable with a char say X times? So, I'd like to do something like: string divider( size, '-'); // C++ notation. $divider = '-' x $size; // perl notation. I thought I could do the following: const char divider[rowstr.length] = '-'; but the compiler complains about not having a constant integer expression. thanks.It's most likely complaining about rowstr.length not being a constant, not the '-'. This works: const char divider[5] = '-'; If you want to allocate a new array on the heap with '-' in it, I think there is a way, but I'm not sure how to do it. I'm pretty sure there's a runtime function to do it. -Steve
Jul 30 2010
On Fri, 30 Jul 2010 11:35:15 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Fri, 30 Jul 2010 11:24:41 -0400, dcoder <dcoder devnull.com> wrote:Something like this will work on the heap: char[] divider = new char[5]; divider[] = '-';Hello. Is there anyway in D to convenient fill a string variable with a char say X times? So, I'd like to do something like: string divider( size, '-'); // C++ notation. $divider = '-' x $size; // perl notation. I thought I could do the following: const char divider[rowstr.length] = '-'; but the compiler complains about not having a constant integer expression. thanks.It's most likely complaining about rowstr.length not being a constant, not the '-'. This works: const char divider[5] = '-'; If you want to allocate a new array on the heap with '-' in it, I think there is a way, but I'm not sure how to do it. I'm pretty sure there's a runtime function to do it. -Steve
Jul 30 2010
On Fri, 30 Jul 2010 11:46:32 -0400, Justin Spahr-Summers <Justin.SpahrSummers gmail.com> wrote:On Fri, 30 Jul 2010 11:35:15 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:That assigns 0xff to all divider chars, and then assigns '-'. I think there's a way to do it without the initial assignment. -SteveIf you want to allocate a new array on the heap with '-' in it, I think there is a way, but I'm not sure how to do it. I'm pretty sure there's a runtime function to do it.Something like this will work on the heap: char[] divider = new char[5]; divider[] = '-';
Jul 30 2010
Steven Schveighoffer:In past there was some way to do that: typedef char mchar = '-'; mchar[] divider = new mchar[5]; Now you have to initialize the dynamic array two times (using a char struct with alias this is probably not a good idea). I have shown this problem, but I think Walter was not interested. Maybe LDC will able to optimize away the first initialization, I have an enhancement request for LLVM. Bye, bearophilechar[] divider = new char[5]; divider[] = '-';That assigns 0xff to all divider chars, and then assigns '-'. I think there's a way to do it without the initial assignment.
Jul 30 2010
On Fri, 30 Jul 2010 12:46:20 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:I was wrong, I looked through the runtime and did not find such a function. I think I may have read it in my copy of TDPL that I reviewed. In any case, I think D deserves a way to do that.char[] divider = new char[5]; divider[] = '-';That assigns 0xff to all divider chars, and then assigns '-'. I think there's a way to do it without the initial assignment.In past there was some way to do that: typedef char mchar = '-'; mchar[] divider = new mchar[5];As a way to initialize an array, this is horrible :)Now you have to initialize the dynamic array two times (using a char struct with alias this is probably not a good idea). I have shown this problem, but I think Walter was not interested. Maybe LDC will able to optimize away the first initialization, I have an enhancement request for LLVM.I think a function to do it is fine, like makeArray('-', 5); -Steve
Jul 30 2010
On Friday, July 30, 2010 10:14:45 Steven Schveighoffer wrote:I think a function to do it is fine, like makeArray('-', 5);Well, creating a function for producing an array literal and returning it using templates and string mixins wouldn't be all that hard, but if you want to create a dynamic array of arbitrary size at runtime, that's not going to work, and a makeArray() function would have exactly the same tools that you have to create an array of all the same value. So, it's not going to be any more efficient that what you can do. int[] a = new int[](x); a[] = val; _should_ be fairly easily optimized by the compiler and thus really should be optimized down to an initialization rather than an initialization and an assignment. A makeArray() function wouldn't hurt any, but I don't think that it would really buy us much. Of course, truth be told, I've always thought that the ability to construct a string or vector in C++ all of a single value was pretty useless. Obviously, some people find it useful at least once in a while, but I've never had much use for it. A makeArray() function would probably still be a good thing to have, but what we really need here is either a syntactic way to do it or for the compiler to optimize out the useless initialization (as well as inline makeArray()) so that you don't have to deal with the extra cost of setting everything twice. - Jonathan M Davis
Jul 30 2010
On Fri, 30 Jul 2010 15:56:36 -0400, Jonathan M Davis <jmdavisprog gmail.com> wrote:On Friday, July 30, 2010 10:14:45 Steven Schveighoffer wrote:The function would call gc_malloc directly, which does not initialize the requested memory. Actually, it would call a new run time function that I will write, which would initialize the array length also.I think a function to do it is fine, like makeArray('-', 5);Well, creating a function for producing an array literal and returning it using templates and string mixins wouldn't be all that hard, but if you want to create a dynamic array of arbitrary size at runtime, that's not going to work, and a makeArray() function would have exactly the same tools that you have to create an array of all the same value.So, it's not going to be any more efficient that what you can do. int[] a = new int[](x); a[] = val; _should_ be fairly easily optimized by the compiler and thus really should be optimized down to an initialization rather than an initialization and an assignment.It's not. The only runtime functions available to the compiler look like this: _d_newarrayT(TypeInfo ti, size_t length); -Steve
Jul 30 2010
On Friday, July 30, 2010 13:10:46 Steven Schveighoffer wrote:On Fri, 30 Jul 2010 15:56:36 -0400, Jonathan M Davis <jmdavisprog gmail.com> wrote:Well, if there's a function other than new to allocate GC memory, then makeArray() is quite doable. I've never dealt with anything but new. As far as I've been aware, you either use new for GC memory or malloc for non-GC memory. If there's a gc_malloc, then that would solve the problem and it would make good sense to do that with makeArray().On Friday, July 30, 2010 10:14:45 Steven Schveighoffer wrote:The function would call gc_malloc directly, which does not initialize the requested memory. Actually, it would call a new run time function that I will write, which would initialize the array length also.I think a function to do it is fine, like makeArray('-', 5);Well, creating a function for producing an array literal and returning it using templates and string mixins wouldn't be all that hard, but if you want to create a dynamic array of arbitrary size at runtime, that's not going to work, and a makeArray() function would have exactly the same tools that you have to create an array of all the same value.I guess that's one thing that comes of not really implementing it as a primitive. If there are enough such functions that would be properly optimizable had they actually been implemented as primitives, I would think that there would be some merit in finding a way to get the compiler to understand that it can do such optimizations. But I really don't know how all that works in dmd, so I have no idea how feasible that is. - Jonathan M DavisSo, it's not going to be any more efficient that what you can do. int[] a = new int[](x); a[] = val; _should_ be fairly easily optimized by the compiler and thus really should be optimized down to an initialization rather than an initialization and an assignment.It's not. The only runtime functions available to the compiler look like this: _d_newarrayT(TypeInfo ti, size_t length);
Jul 30 2010
On Fri, 30 Jul 2010 16:31:49 -0400, Jonathan M Davis <jmdavisprog gmail.com> wrote:On Friday, July 30, 2010 13:10:46 Steven Schveighoffer wrote:To be clear, the compiler could do the optimization if it had another runtime function to call. But since there is *no* runtime function that allocates a new array and initializes it with a custom initial element, how do you make a primitive? So if the function exists, the compiler can be fixed to make the sequence of "create then assign" a primitive, but I think just a runtime function is good enough, and will work without compiler changes. -SteveIt's not. The only runtime functions available to the compiler look like this: _d_newarrayT(TypeInfo ti, size_t length);I guess that's one thing that comes of not really implementing it as a primitive. If there are enough such functions that would be properly optimizable had they actually been implemented as primitives, I would think that there would be some merit in finding a way to get the compiler to understand that it can do such optimizations. But I really don't know how all that works in dmd, so I have no idea how feasible that is.
Jul 30 2010
Jonathan M Davis:a makeArray() function would have exactly the same tools that you have to create an array of all the same value. So, it's not going to be any more efficient that what you can do.Doesn't the D2 GC give you a lower level function to GC-allocate uninitialized memory? The GC in D1 has such function, so in D1 it's easy to create a makeArray(). Bye, bearophile
Jul 30 2010
== Quote from Jonathan M Davis (jmdavisprog gmail.com)'s articleA makeArray() function wouldn't hurt any, but I don't think that it would really buy us much. Of course, truth be told, I've always thought that the ability to construct a string or vector in C++ all of a single value was pretty useless. Obviously, some people find it useful at least once in a while, but I've never had much use for it. A makeArray() function would probably still be a good thing to have, but what we really need here is either a syntactic way to do it or for the compiler to optimize out the useless initialization (as well as inline makeArray()) so that you don't have to deal with the extra cost of setting everything twice. - Jonathan M DavisIf I'm writing a program that pretty prints tree data, or output of sql, like Oracle's sqlplus, or postgres equivalent, I find having such a utility function/constructor a pretty handy feature. I don't know where such a tool should finally be placed in D, but I having it available as a library or as part of the language would be great. It seems like a lot of other languages have it like python, perl, C++, and Java. So it can't be that useless.
Jul 30 2010
I don't know where such a tool should finally be placed in D, but I having it available as a library or as part of the language would be great. It seems like a lot of other languages have it like python, perl, C++, and Java. So it can't be that useless.There is fill() in std.algorithm, but it needs an already present range... auto s = new int[5]; fill(s, 10); s is now [10,10,10,10,10]
Jul 30 2010
On Friday, July 30, 2010 14:13:15 dcoder wrote:If I'm writing a program that pretty prints tree data, or output of sql, like Oracle's sqlplus, or postgres equivalent, I find having such a utility function/constructor a pretty handy feature. I don't know where such a tool should finally be placed in D, but I having it available as a library or as part of the language would be great. It seems like a lot of other languages have it like python, perl, C++, and Java. So it can't be that useless.Well, I certainly have no problem with a function like makeArray() existing. It's just that it's one of those functions that I've never found useful, and I don't think that I've ever seen anyone use it in code. Now, for strings, I find such a function to be a bit dangerous since it's ignoring the fact that char is a UTF-8 code unit rather than an ASCII value, but for other types of arrays, that wouldn't be a problem. And for strings, you could either use dstrings or just be certain that all of your characters are actually a single code unit. But I certainly wouldn't want the equivalent of having a string constructor that takes a char and a count like C++'s string does. It would be fine in many cases, but string functions that take chars are generally asking for trouble due to unicode issues. But since, string in D is an array rather than a class, that's not really a problem in the same way. makeArray() being for arrays in general rather than specifically strings would not promote bad string code in the same way that C++'s string constructor does. - Jonathan M Davis
Jul 30 2010
On Fri, 30 Jul 2010 16:30:17 -0700, Jonathan M Davis <jmdavisprog gmail.com> wrote:On Friday, July 30, 2010 14:13:15 dcoder wrote:I agree with this sentiment. I think the feature is pretty niche to begin with, and the compiler should be able to optimize out the initialization in the sample I gave previously. D is indeed a systems language, but I (and I'm sure others) would like to use it in a high- level way, where I can write natural, straightforward code and expect the compiler to do the Right Thing. Besides, performance is not an applicable argument for this use case. Even if the array initialization is compiled into the binary, the amount of time it would take is infinitesimal. If someone's trying to initialize a 100,000 element array to some specific value, they're likely going to write their own makeArray() anyways.If I'm writing a program that pretty prints tree data, or output of sql, like Oracle's sqlplus, or postgres equivalent, I find having such a utility function/constructor a pretty handy feature. I don't know where such a tool should finally be placed in D, but I having it available as a library or as part of the language would be great. It seems like a lot of other languages have it like python, perl, C++, and Java. So it can't be that useless.Well, I certainly have no problem with a function like makeArray() existing. It's just that it's one of those functions that I've never found useful, and I don't think that I've ever seen anyone use it in code.
Jul 30 2010
On Fri, 30 Jul 2010 19:41:03 -0400, Justin Spahr-Summers <Justin.SpahrSummers gmail.com> wrote:On Fri, 30 Jul 2010 16:30:17 -0700, Jonathan M Davis <jmdavisprog gmail.com> wrote:That's because it's not a trivial function to write :) One has to have intimate knowledge of the runtime and understand how to properly allocate a block for this purpose. Basically, there have been code instances of the form: T[] x = new T[n]; x[] = initval; Because that's the only way to do it. Offer a function like makeArray, and why *wouldn't* you change to it? I prefer a single line/initialization anyways.On Friday, July 30, 2010 14:13:15 dcoder wrote:If I'm writing a program that pretty prints tree data, or output ofsql,like Oracle's sqlplus, or postgres equivalent, I find having such a utility function/constructor a pretty handy feature. I don't know where such a tool should finally be placed in D, but Ihavingit available as a library or as part of the language would be great.Itseems like a lot of other languages have it like python, perl, C++,andJava. So it can't be that useless.Well, I certainly have no problem with a function like makeArray() existing. It's just that it's one of those functions that I've never found useful, and I don't think that I've ever seen anyone use it in code.I agree with this sentiment. I think the feature is pretty niche to begin with, and the compiler should be able to optimize out the initialization in the sample I gave previously. D is indeed a systems language, but I (and I'm sure others) would like to use it in a high- level way, where I can write natural, straightforward code and expect the compiler to do the Right Thing.I just find the syntax awkward: char[] divider = new char[5]; // hey, compiler I'm initializing divider divider[] = '-'; // OOHHH got you there, I wasn't done yet :) It just seems natural that I should be able to do this in one line. Having the compiler optimize isn't a bad thing, but relying on the optimization because "we can't find a better way" seems crappy to me.Besides, performance is not an applicable argument for this use case. Even if the array initialization is compiled into the binary, the amount of time it would take is infinitesimal. If someone's trying to initialize a 100,000 element array to some specific value, they're likely going to write their own makeArray() anyways.The performance improvement is certainly a smaller argument compared to the syntax. But it is a nice bonus. There are more significant performance bugs in initialization of static arrays using array literals. -Steve
Aug 02 2010
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleI was wrong, I looked through the runtime and did not find such afunction. std.string has a repeat() function. Try: import std.string; void main() { string divider = repeat("-", 5); writeln(divider); } Jason
Jul 31 2010
On Sat, 31 Jul 2010 05:37:41 -0400, Jason Spencer <spencer8 sbcglobal.net> wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleIt doesn't do the right thing. It allocates, then initializes, resulting in a double-initialization. -SteveI was wrong, I looked through the runtime and did not find such afunction. std.string has a repeat() function. Try: import std.string; void main() { string divider = repeat("-", 5); writeln(divider); }
Aug 02 2010
Dnia 30-07-2010 o 17:24:41 dcoder <dcoder devnull.com> napisa=B3(a):Is there anyway in D to convenient fill a string variable with a char ==say X times?If you need to only print, you can: import std.stdio; import std.range; void main() { foreach (c; take(repeat('-'), 5)) write(c); } I know, I know, you said *convenient* ;) I heard write(ln) is to print = arbitrary ranges, so this'd come down to: writeln(take(repeat('-'), 5)); and if universal call syntax worked correctly then even this would be = possible: writeln('-'.repeat.take(5)); much easier to type. BTW, I stumbled on this when crafting the example: http://d.puremagic.com/issues/show_bug.cgi?id=3D4537 Tomek
Jul 30 2010
Dnia 30-07-2010 o 22:15:50 Tomek Sowi=F1ski <just ask.me> napisa=B3(a):writeln('-'.repeat.take(5));Oh, and if repeat had slicing (as it should)... '-'.repeat[0..5] Still, it's far cry from Python's '-' * 5 Tomek
Jul 30 2010