[Issue 5348] Variable Length Arrays

2013-03-29 Thread d-bugmail
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

2013-03-28 Thread d-bugmail
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

2013-03-28 Thread d-bugmail
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

2013-03-28 Thread d-bugmail
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

2013-03-28 Thread d-bugmail
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

2011-11-15 Thread d-bugmail
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

2011-11-15 Thread d-bugmail
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

2011-02-13 Thread d-bugmail
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

2011-01-03 Thread d-bugmail
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

2011-01-03 Thread d-bugmail
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: ---