digitalmars.D - Dynamic array creation with default
- bearophile (29/29) Aug 22 2011 To create a nD dynamic array and initialize it to a constant value (diff...
- foobar (21/50) Aug 23 2011 then initializes it all again with true. You sometimes forget to use the...
- bearophile (13/26) Aug 23 2011 Keep in mind that currently this is correct and it generates a 1D dynami...
- foobar (13/39) Aug 23 2011 Isn't this an inconsistency in the language?
- Timon Gehr (2/41) Aug 23 2011
- foobar (4/23) Aug 23 2011 "int" and "new int" are both an integer, the only difference is the memo...
- Andrei Alexandrescu (6/20) Aug 23 2011 I hate that, too. Walter hates it, too, but we both reckon it's too late...
- foobar (7/30) Aug 23 2011 Is it possible to deprecate/disallow "new T[size]" since we have an alte...
- Timon Gehr (5/35) Aug 23 2011 Dynamic arrays should stay fully built-in imo. What would be the benefit...
- Andrei Alexandrescu (3/33) Aug 23 2011 I'm afraid too much paste is out of the tube at this point.
- Don (7/37) Aug 23 2011 Please note that moving AAs from built-in to library was little short of...
- Adam D. Ruppe (3/5) Aug 23 2011 Amen. The library AAs *still* give me trouble from time to time -
- Andrei Alexandrescu (5/48) Aug 23 2011 We're not seeing benefits because they haven't materialized yet; the
- bearophile (4/6) Aug 23 2011 With a soft deprecation path I think you will be able to deprecate and r...
- Lars T. Kyllingstad (4/25) Aug 23 2011 I, for one, would welcome this change. It's a horrible inconsistency in...
- Steven Schveighoffer (9/32) Aug 24 2011 It's actually possible, but ugly:
- Michel Fortin (10/18) Aug 24 2011 A problem with this approach is that it won't work in safe mode because
- Steven Schveighoffer (10/22) Aug 24 2011 =
- Timon Gehr (2/20) Aug 24 2011 int[N]*
To create a nD dynamic array and initialize it to a constant value (different from the init) you currently do something like this: auto mat = new bool[][](10, 20); foreach (ref row; mat) row[] = true; Currently this D code initializes the matrix items to bool.init (false), and then initializes it all again with true. You sometimes forget to use the "ref", and they are three lines of code for a single operation. Time ago I have seen this as a way to simplify the code, similar to the syntax for fixed-sized arrays (but Andrei says this is not good): auto mat = new bool[][](10, 20) = true; to do the same thing): let mat = Array2D.create 10 20 true This has suggested me to add one optional initialization value in D too: auto mat = new bool[][](10, 20, true); It's a bit more bug-prone, because you sometimes forget a [] and you write: auto mat = new int[](10, 20); Instead of: auto mat = new int[][](10, 20); And instead of a matrix you get a 1D array initialized to some integer value. But I think it's not a big problem. A bigger problem is that currently this code is accepted, so you can't use an optional initialization value: auto a = new int[][](5); A solution is to always require as many sizes as dimensions, so you have to write: auto a = new int[][](5, 0); // OK, no default auto a = new int[][](5, 0, 30); // 30 is the default Another solution is to introduce named arguments and always require the argument name for the default value, when you add a default value: auto mat = new bool[][](10, 20, default=true); Using both solutions at the same time is possible. In theory this syntax is also useful to initialize the array to something not constant, using a delegate (in this universe when uniform has a single input, it acts like iota(n)), this is a typical use case: auto mat10 = new int[][](10, 20, default={ return uniform(9); }); This replaces a function table() that I have suggested for Phobos. Bye, bearophile
Aug 22 2011
== Quote from bearophile (bearophileHUGS lycos.com)'s articleTo create a nD dynamic array and initialize it to a constant value (differentfrom the init) you currently do something like this:auto mat = new bool[][](10, 20); foreach (ref row; mat) row[] = true; Currently this D code initializes the matrix items to bool.init (false), andthen initializes it all again with true. You sometimes forget to use the "ref", and they are three lines of code for a single operation.Time ago I have seen this as a way to simplify the code, similar to the syntaxfor fixed-sized arrays (but Andrei says this is not good):auto mat = new bool[][](10, 20) = true; todo the same thing):let mat = Array2D.create 10 20 true This has suggested me to add one optional initialization value in D too: auto mat = new bool[][](10, 20, true); It's a bit more bug-prone, because you sometimes forget a [] and you write: auto mat = new int[](10, 20); Instead of: auto mat = new int[][](10, 20); And instead of a matrix you get a 1D array initialized to some integer value.But I think it's not a big problem.A bigger problem is that currently this code is accepted, so you can't use anoptional initialization value:auto a = new int[][](5); A solution is to always require as many sizes as dimensions, so you have to write: auto a = new int[][](5, 0); // OK, no default auto a = new int[][](5, 0, 30); // 30 is the default Another solution is to introduce named arguments and always require the argumentname for the default value, when you add a default value:auto mat = new bool[][](10, 20, default=true); Using both solutions at the same time is possible. In theory this syntax is also useful to initialize the array to something notconstant, using a delegate (in this universe when uniform has a single input, it acts like iota(n)), this is a typical use case:auto mat10 = new int[][](10, 20, default={ return uniform(9); }); This replaces a function table() that I have suggested for Phobos. Bye, bearophileyou raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation error // 2) function of the array dimension auto bar = new int[][](10, 20, (int x, int y) { return x*y; } ); // if you want a default value just use: auto bar1 = new int[][](10, 20, { return 3; } ); For fixed-sized arrays the function would be CTFE-able.
Aug 23 2011
foobar:you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];// 2) function of the array dimension auto bar = new int[][](10, 20, (int x, int y) { return x*y; } ); // if you want a default value just use: auto bar1 = new int[][](10, 20, { return 3; } ); For fixed-sized arrays the function would be CTFE-able.This is more complex than my suggestions :-) The most common case is the initialization with a constant value. I'd like this case to be as efficient as possible, so I don't like the { return 3; }. The case with a more complex delegate is interesting to initialize constant arrays: immutable m = new int[][](10, 20, (int x, int y){ return x*y; }); But in my opinion this is not a so common operation. And it's not able to replace Python-style array comps: foo = [x ** x for x in lazyIterable] So I don't like your proposals. Maybe dsimcha will give a Phobos function to allocate & initialize a nD array with a given const value. Bye, bearophile
Aug 23 2011
== Quote from bearophile (bearophileHUGS lycos.com)'s articlefoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];case to be as efficient as possible, so I don't like the { return 3; }. This syntax could be simplified if we drop "return" as suggested in another thread. Also, couldn't we employ "lazy" for this? I don't remember how it works, does it accept a value on the call-site? On the other hand, I dislike the named-parameter suggestion. Named parameters indicate in my eyes a design bug.// 2) function of the array dimension auto bar = new int[][](10, 20, (int x, int y) { return x*y; } ); // if you want a default value just use: auto bar1 = new int[][](10, 20, { return 3; } ); For fixed-sized arrays the function would be CTFE-able.This is more complex than my suggestions :-) The most common case is the initialization with a constant value. I'd like thisThe case with a more complex delegate is interesting to initialize constant arrays: immutable m = new int[][](10, 20, (int x, int y){ return x*y; }); But in my opinion this is not a so common operation. And it's not able toreplace Python-style array comps:foo = [x ** x for x in lazyIterable] So I don't like your proposals. Maybe dsimcha will give a Phobos function to allocate & initialize a nD arraywith a given const value.Bye, bearophile
Aug 23 2011
On 08/23/2011 03:15 PM, foobar wrote:== Quote from bearophile (bearophileHUGS lycos.com)'s articleint and typeof(new int) are different types too.foobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];case to be as efficient as possible, so I don't like the { return 3; }. This syntax could be simplified if we drop "return" as suggested in another thread. Also, couldn't we employ "lazy" for this? I don't remember how it works, does it accept a value on the call-site? On the other hand, I dislike the named-parameter suggestion. Named parameters indicate in my eyes a design bug.// 2) function of the array dimension auto bar = new int[][](10, 20, (int x, int y) { return x*y; } ); // if you want a default value just use: auto bar1 = new int[][](10, 20, { return 3; } ); For fixed-sized arrays the function would be CTFE-able.This is more complex than my suggestions :-) The most common case is the initialization with a constant value. I'd like thisThe case with a more complex delegate is interesting to initialize constant arrays: immutable m = new int[][](10, 20, (int x, int y){ return x*y; }); But in my opinion this is not a so common operation. And it's not able toreplace Python-style array comps:foo = [x ** x for x in lazyIterable] So I don't like your proposals. Maybe dsimcha will give a Phobos function to allocate& initialize a nD arraywith a given const value.Bye, bearophile
Aug 23 2011
== Quote from Timon Gehr (timon.gehr gmx.ch)'s articleOn 08/23/2011 03:15 PM, foobar wrote:"int" and "new int" are both an integer, the only difference is the memory location. "int[10]" is a fixed-size array vs. "new int[10]" which is a dynamic array with a completely different interface.== Quote from bearophile (bearophileHUGS lycos.com)'s articleint and typeof(new int) are different types too.foobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
On 8/23/11 6:15 AM, foobar wrote:== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleOn 8/23/11 6:15 AM, foobar wrote:Is it possible to deprecate/disallow "new T[size]" since we have an alternate syntax for it? At least until D3 comes along when we could change this. This also aligns with your goal of moving built-in types from the compiler/runtime to the library (AAs..) which I think is an important goal. I'd like to see dynamic arrays as well as AAs as plain templates in phobos and D itself only provides a thin layer of syntax sugar for literals and such.== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
On 08/23/2011 05:11 PM, foobar wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleDynamic arrays should stay fully built-in imo. What would be the benefit of having them in the library? To generate decent machine code and optimize away some boundary checks from safe code, compilers would still have to treat them specially.On 8/23/11 6:15 AM, foobar wrote:Is it possible to deprecate/disallow "new T[size]" since we have an alternate syntax for it? At least until D3 comes along when we could change this. This also aligns with your goal of moving built-in types from the compiler/runtime to the library (AAs..) which I think is an important goal. I'd like to see dynamic arrays as well as AAs as plain templates in phobos and D itself only provides a thin layer of syntax sugar for literals and such.== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
On 8/23/11 8:11 AM, foobar wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleI'm afraid too much paste is out of the tube at this point. AndreiOn 8/23/11 6:15 AM, foobar wrote:Is it possible to deprecate/disallow "new T[size]" since we have an alternate syntax for it? At least until D3 comes along when we could change this. This also aligns with your goal of moving built-in types from the compiler/runtime to the library (AAs..) which I think is an important goal. I'd like to see dynamic arrays as well as AAs as plain templates in phobos and D itself only provides a thin layer of syntax sugar for literals and such.== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
foobar wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articlePlease note that moving AAs from built-in to library was little short of a disaster, as far as the compiler is concerned. It created a horrific number of regression bugs (more than 20% of all serious regressions have been caused by it), it's occupied months of time, the job is still only half done, and as far as I can see, there's actually been ZERO benefit from it.On 8/23/11 6:15 AM, foobar wrote:Is it possible to deprecate/disallow "new T[size]" since we have an alternate syntax for it? At least until D3 comes along when we could change this. This also aligns with your goal of moving built-in types from the compiler/runtime to the library (AAs..) which I think is an important goal. I'd like to see dynamic arrays as well as AAs as plain templates in phobos and D itself only provides a thin layer of syntax sugar for literals and such.== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
Don wrote:Please note that moving AAs from built-in to library was little short of a disaster, as far as the compiler is concerned.Amen. The library AAs *still* give me trouble from time to time - been the most buggy thing I've used in D.
Aug 23 2011
On 8/23/11 12:32 PM, Don wrote:foobar wrote:We're not seeing benefits because they haven't materialized yet; the benefit so far is that it paves the way toward finalizing the transition. But point taken about the difficulties. Andrei== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articlePlease note that moving AAs from built-in to library was little short of a disaster, as far as the compiler is concerned. It created a horrific number of regression bugs (more than 20% of all serious regressions have been caused by it), it's occupied months of time, the job is still only half done, and as far as I can see, there's actually been ZERO benefit from it.On 8/23/11 6:15 AM, foobar wrote:Is it possible to deprecate/disallow "new T[size]" since we have an alternate syntax for it? At least until D3 comes along when we could change this. This also aligns with your goal of moving built-in types from the compiler/runtime to the library (AAs..) which I think is an important goal. I'd like to see dynamic arrays as well as AAs as plain templates in phobos and D itself only provides a thin layer of syntax sugar for literals and such.== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error. Andreifoobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
Andrei Alexandrescu:I hate that, too. Walter hates it, too, but we both reckon it's too late now to change things.With a soft deprecation path I think you will be able to deprecate and remove it in a year. Bye, bearophile
Aug 23 2011
On Tue, 23 Aug 2011 07:45:33 -0700, Andrei Alexandrescu wrote:On 8/23/11 6:15 AM, foobar wrote:I, for one, would welcome this change. It's a horrible inconsistency in the language. -Lars== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things.foobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 23 2011
On Tue, 23 Aug 2011 10:45:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 8/23/11 6:15 AM, foobar wrote:It's actually possible, but ugly: auto ptr = (new int[10][](1)).ptr; One really interesting thing to note -- the compiler actually turns struct allocations into array-of-one allocations in the runtime. So this is likely what the compiler would do if it supported direct heap allocation of fixed-sized arrays. -Steve== Quote from bearophile (bearophileHUGS lycos.com)'s articleI hate that, too. Walter hates it, too, but we both reckon it's too late now to change things. It makes it impossible to create an instance of the type "int[10]" dynamically because of an gratuitous syntactic special case. It comes from C++, where it was an unforced error.foobar:Isn't this an inconsistency in the language? // Generally speaking, allocates an instance of T on the heap auto foo = new T; However, "int[10]" and "new int[10]" are different types.you raise a valid concern but this looks too complicated. I'd suggest to simplify into only two cases. // 1) T.INIT - as you suggested the dimension should be checked auto foo = new int[][](10, 20); // correct auto foo1 = new int[][](10); // compilation errorKeep in mind that currently this is correct and it generates a 1D dynamic array: auto v = new int[10];
Aug 24 2011
On 2011-08-24 11:17:08 +0000, "Steven Schveighoffer" <schveiguy yahoo.com> said:It's actually possible, but ugly: auto ptr = (new int[10][](1)).ptr; One really interesting thing to note -- the compiler actually turns struct allocations into array-of-one allocations in the runtime. So this is likely what the compiler would do if it supported direct heap allocation of fixed-sized arrays.A problem with this approach is that it won't work in safe mode because accessing the .ptr property of an array is unsafe in general. But it is perfectly safe to allocate a static array on the GC heap, so it should be allowed… -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 24 2011
On Wed, 24 Aug 2011 15:15:54 -0400, Michel Fortin = <michel.fortin michelf.com> wrote:On 2011-08-24 11:17:08 +0000, "Steven Schveighoffer" =<schveiguy yahoo.com> said:=It's actually possible, but ugly: auto ptr =3D (new int[10][](1)).ptr; One really interesting thing to note -- the compiler actually turns ==struct allocations into array-of-one allocations in the runtime. So=p =this is likely what the compiler would do if it supported direct hea=e =allocation of fixed-sized arrays.A problem with this approach is that it won't work in safe mode becaus=accessing the .ptr property of an array is unsafe in general. But it i=s =perfectly safe to allocate a static array on the GC heap, so it should==be allowed=E2=80=A6And what would be the type returned by such a function? ;) -Steve
Aug 24 2011
On 08/24/2011 11:19 PM, Steven Schveighoffer wrote:On Wed, 24 Aug 2011 15:15:54 -0400, Michel Fortin <michel.fortin michelf.com> wrote:int[N]*On 2011-08-24 11:17:08 +0000, "Steven Schveighoffer" <schveiguy yahoo.com> said:And what would be the type returned by such a function? ;) -SteveIt's actually possible, but ugly: auto ptr = (new int[10][](1)).ptr; One really interesting thing to note -- the compiler actually turns struct allocations into array-of-one allocations in the runtime. So this is likely what the compiler would do if it supported direct heap allocation of fixed-sized arrays.A problem with this approach is that it won't work in safe mode because accessing the .ptr property of an array is unsafe in general. But it is perfectly safe to allocate a static array on the GC heap, so it should be allowed…
Aug 24 2011