[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #11 from bearophile_h...@eml.cc 2013-03-29 16:05:41 PDT --- (In reply to comment #10) but I think this is complex enough that it should be done as a DIP, not a simple enhancement request. I agree. But at the moment I am not good enough to write a DIP, so for now I have opened just Issue 9832 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #7 from bearophile_h...@eml.cc 2013-03-28 12:03:43 PDT --- See also for an alternative design: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3532.html -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 Walter Bright bugzi...@digitalmars.com changed: What|Removed |Added Status|NEW |RESOLVED CC||bugzi...@digitalmars.com Platform|Other |All Resolution||WONTFIX OS/Version|Windows |All --- Comment #8 from Walter Bright bugzi...@digitalmars.com 2013-03-28 13:02:08 PDT --- 1. VLAs are a failure in C99. 2. I'd prefer to deal with stack allocated arrays by optimization rather than new syntax semantics, i.e.: int[] array = new int[5]; and determining that array[] can never leave its scope, and so can be allocated on the stack. 3. Consider that static arrays are passed by value to functions, rather than by reference. VLAs for static arrays mess this up. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #9 from bearophile_h...@eml.cc 2013-03-28 15:55:17 PDT --- Thank you for your comments. 1. VLAs are a failure in C99. I agree, let's invent something better. My ideas have changed, and now I think it's better to define DSSAA in library code that is recognized and managed in a special way by the compiler, as here for C++: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3532.html Ada2012 has added stack-allocated collections. Rust allows any thing you want to be allocated on the stack, if you want. They know that sometimes heap allocations are bad for performance. Dynamic-size stack-allocated arrays (abbreviated to DSSAA) will be a base to create several other stack-allocated collections for D, as in Ada (and in future Rust). 2. I'd prefer to deal with stack allocated arrays by optimization rather than new syntax semantics, i.e.: int[] array = new int[5]; and determining that array[] can never leave its scope, and so can be allocated on the stack. Your idea has problems: 1) Since some time Java has added escape analysis to stack-allocate some objects and reduce a little the pressure on the GC. This feature is useful in Java, but also it shows its limits, in many cases it fails, so it doesn't bring a large improvement in Java. 2) I'd like DSSAA to be able to leave the scope (the simplest way to do this is to dup on them, copying them on the heap. Below I show another way to do it). A solution is to invent library-defined arrays that have a semantics different from the regular dynamic arrays. See below. 3. Consider that static arrays are passed by value to functions, rather than by reference. VLAs for static arrays mess this up. A solution is to add a special value array to Phobos, as in that n3532, and then let the D compiler manage it in a special way, allocating it on the stack where possible (if you use it inside a struct its storage goes on the heap, like a dynamic array). In the following case foo creates a DSSAA and returns it. A DSSAA keeps its lenght beside the data, in the stack frame. At the return point inside bar() bar allocates another DSSAA on the stack (increasing the size of the stack frame of bar) and copies the received data: import std.collections: ValArray; ValArray!int foo(int n) { auto a = ValArray!int(n); // on the stack. return a; } void bar() { ValArray!int b = foo(5); // copied on the stack. } In this case foo() creates the DSSAA and calls bar with it. D just returns pointer to the data on the stack frame plus length (so it's a kind of slice) and then under the cover the data is also copied inside the stack frame of bar: import std.collections: ValArray; void foo(int n) { auto a = ValArray!int(n); bar(a); } void bar(ValArray!int b) { } Probably I have to open an enhancement request on this. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #10 from Walter Bright bugzi...@digitalmars.com 2013-03-28 17:02:19 PDT --- Probably I have to open an enhancement request on this. Since it's different, yes, but I think this is complex enough that it should be done as a DIP, not a simple enhancement request. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #5 from bearophile_h...@eml.cc 2011-11-15 14:45:02 PST --- Currently this works, and ct_function() is run at compile-time because fixed array length definitions is a compile-time context, so in D it forces CTFE: int ct_function(int x) { return x * 2; } void main() { int[ct_function(5)] a; } If VLA come in D, and if their definition syntax is the same as the current fixed array definition syntax, then that length definition stops being a compile-time context, and the compiler is not forced (but free any way) to run ct_function() at compile-time. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 timon.g...@gmx.ch changed: What|Removed |Added CC||timon.g...@gmx.ch --- Comment #6 from timon.g...@gmx.ch 2011-11-15 15:07:25 PST --- (In reply to comment #5) Currently this works, and ct_function() is run at compile-time because fixed array length definitions is a compile-time context, so in D it forces CTFE: int ct_function(int x) { return x * 2; } void main() { int[ct_function(5)] a; } If VLA come in D, and if their definition syntax is the same as the current fixed array definition syntax, then that length definition stops being a compile-time context, and the compiler is not forced (but free any way) to run ct_function() at compile-time. It is not necessarily able to solve the particular halting problem instance. The best that could be done without breaking backwards compatibility would be to define the semantics of int[foo()] a; as either: if foo() can be executed at compile time, take the result as the array length, else either don't terminate compilation or introduce a VLA. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #3 from bearophile_h...@eml.cc 2011-02-13 12:58:28 PST --- Ada language too supports stack-allocation of 2D arrays with run-time sizes, an example: with Ada.Text_Io; use Ada.Text_Io; with Ada.Float_Text_Io; use Ada.Float_Text_Io; with Ada.Integer_Text_Io; use Ada.Integer_Text_Io; procedure Two_Dimensional_Arrays is type Matrix_Type is array(Positive range , Positive range ) of Float; Dim_1 : Positive; Dim_2 : Positive; begin Get(Item = Dim_1); Get(Item = Dim_2); -- Create an inner block with the correctly sized array declare Matrix : Matrix_Type(1..Dim_1, 1..Dim_2); begin Matrix(1, Dim_2) := 3.14159; Put(Item = Matrix(1, Dim_2), Fore = 1, Aft = 5, Exp = 0); New_Line; end; -- The variable Matrix is popped off the stack automatically end Two_Dimensional_Arrays; -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 --- Comment #1 from bearophile_h...@eml.cc 2011-01-03 04:22:18 PST --- Some comments by Dmitry Olshansky: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=125942 As stated in this proposal they are quite useless, e.g. they are easily implemented via mixin with alloca. Plus, what's the benefit in throwing exception on alloca failure, how you suppose the user to handle this stackoverflow exception? I would have expected a better design to provide an optional parameter to fallback to GC or something ( like malloc(...) + scope(exit) free(...); ) and that's indicates a library solution, of course. Some answers to Dmitry Olshansky: As stated in this proposal they are quite useless, e.g. they are easily implemented via mixin with alloca. This is false, a mixin solution can't replace a VLA because: - The compiler knows what a VLA is, so it may copy it automatically (as it does with fixed-sized arrays) if you return a VLA from a function. - vla_array.sizeof gives the correct answer - alloca() is not pure, while a function that uses VLA can be pure. - The VLA syntax is nicer, it doesn't look like hack, this encourages their usage, and it doesn't require imports. And if you need a 2D variable length matrix, you don't need a different mixin, the VLA syntax supports multi dimensional arrays. Plus, what's the benefit in throwing exception on alloca failure, how you suppose the user to handle this stackoverflow exception? The proposal says that an error too is OK: When a VLA array is allocated the D compiler tests that there is enough free stack left, and otherwise throws a runtime exception/error (like stack overflow). I would have expected a better design to provide an optional parameter to fallback to GC or something ( like malloc(...) + scope(exit) free(...); ) and that's indicates a library solution, of course. This is a possibility to keep in mind. But it makes the VLA implementation a bit more complex: - in the current proposal the VLA is represented by just a length. If you add a fall-back mechanism then you need to keep a pointer too on the stack. - If you return a VLA the code has to copy the data contents only if the VLA is allocated on the stack. - This semantics is different from the C99 one. So people that know C99 need to read about this difference and understand it, and C99 code ported to D probably needs to keep in account the difference. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5348] Variable Length Arrays
http://d.puremagic.com/issues/show_bug.cgi?id=5348 Dmitry Olshansky dmitry.o...@gmail.com changed: What|Removed |Added CC||dmitry.o...@gmail.com --- Comment #2 from Dmitry Olshansky dmitry.o...@gmail.com 2011-01-03 05:18:26 PST --- As stated in this proposal they are quite useless, e.g. they are easily implemented via mixin with alloca. This is false, a mixin solution can't replace a VLA because: - The compiler knows what a VLA is, so it may copy it automatically (as it does with fixed-sized arrays) if you return a VLA from a function. Introducing more magic then it's worth - one thing I really dislike about this proposal. It doesn't solve anything at all, yet uglifies language. How would function signature look like for function returning VLA? How it then interacts with other array types? Is supposed to be a slice of stack? I guess, no. But with alloca that's all : Foo* ptr = cast(Foo*)alloca(len * Foo.sizeof); Foo[] arr = ptr[0 .. len];//that's all, last time I asked Steven, I got the answer that you can even append to it (which would reallocate on first append) Making it mixin is little extra cost for an *unsafe* feature as it is. - vla_array.sizeof gives the correct answer Small benefit since you now beforehand the size you passed to it, and can create slice out of of it. Plus, what semnatics do you propouse for VLA's on return - value type? How it fits the rest of language? - alloca() is not pure, while a function that uses VLA can be pure. ..but as defined VLAs subtly destroing nothrow property, and in general are leaky abstraction. - The VLA syntax is nicer, it doesn't look like hack, this encourages their usage, and it doesn't require imports. And if you need a 2D variable length matrix, you don't need a different mixin, the VLA syntax supports multi dimensional arrays. I might be wrong but matrices are usaully either small and fixed sized, or big arbitrarily sized and require allocation anyways. IMO every special case language feature should do something importantly useful to prove worthy. Plus, what's the benefit in throwing exception on alloca failure, how you suppose the user to handle this stackoverflow exception? The proposal says that an error too is OK: When a VLA array is allocated the D compiler tests that there is enough free stack left, and otherwise throws a runtime exception/error (like stack overflow). I don't care what proposal *stated* is OK, I care for the user of this feature, would he/she like exception he/she can't *handle* in any sensible way or some other default mechanism? I'm not seeing VLA as much safer/better then alloca in this regard (in the latter you at least have options if you are the author of this piece of code). I would have expected a better design to provide an optional parameter to fallback to GC or something ( like malloc(...) + scope(exit) free(...); ) and that's indicates a library solution, of course. This is a possibility to keep in mind. But it makes the VLA implementation a bit more complex: Again, this just shows how VLAs as stated are not getting anything good. Library solution can be complex and have options, built-in on the contrary should be clear and lightweight. Slicing the result of alloca + some fallback on failure path is OK (at least it has clear semantics, and explicit). - in the current proposal the VLA is represented by just a length. If you add a fall-back mechanism then you need to keep a pointer too on the stack. It's not _too_ but _instead_ of reserving stack space :) - If you return a VLA the code has to copy the data contents only if the VLA is allocated on the stack. And I yet have to see how function's return type would be defined as VLA. What's makes me sad is there is not a single thing about actually defining anything e.g. semantics of copying, interaction with the rest of language. It's all more about kind cool to have that, something like that, you know... - This semantics is different from the C99 one. So people that know C99 need to read about this difference and understand it, and C99 code ported to D probably needs to keep in account the difference. We should ask C99 folks if there are lots of VLAs used at all. Sorry for being too critical, but at very least the proposal needs a lot of refinement on actual implementation. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---