Re: Using inout in delegates

2012-10-09 Thread Jacob Carlborg

On 2012-10-08 21:40, Timon Gehr wrote:


The original behaviour is to be expected and the workaround exploits a
compiler bug.

The correct way to get rid of the compile error is:

void foo(inout(int)[] arr){
 auto a = { const b = arr[0]; } // or int b = arr[0];
}


Why can't auto work there? BTW, this doesn't work:

void foo (inout(int)[] arr)
{
auto a = {
foreach (int e ; arr) {}
};
}

--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-08 Thread Timon Gehr

On 10/05/2012 04:09 PM, Ali Çehreli wrote:

...

This workaround makes the compiler happy:

void foo (inout(int)[] arr)
{
 auto a = (inout int) { auto b = arr[0]; };
}

But probably not what you want. :/

IIRC, inout has bugs and incomplete implementation. I think this should
be in the bug database.

Ali


The original behaviour is to be expected and the workaround exploits a 
compiler bug.


The correct way to get rid of the compile error is:

void foo(inout(int)[] arr){
auto a = { const b = arr[0]; } // or int b = arr[0];
}


Re: Using inout in delegates

2012-10-07 Thread Jacob Carlborg

On 2012-10-05 16:09, Ali Çehreli wrote:


This workaround makes the compiler happy:

void foo (inout(int)[] arr)
{
 auto a = (inout int) { auto b = arr[0]; };
}

But probably not what you want. :/

IIRC, inout has bugs and incomplete implementation. I think this should
be in the bug database.


Using the above workaround did make it compile. But using typeid it now 
contains inout instead. It turns out I didn't need neither const or 
inout, don't know why I added it in the first place. Thanks anyway.


--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-06 Thread Jacob Carlborg

On 2012-10-05 16:09, Ali Çehreli wrote:



This workaround makes the compiler happy:

void foo (inout(int)[] arr)
{
 auto a = (inout int) { auto b = arr[0]; };
}

But probably not what you want. :/

IIRC, inout has bugs and incomplete implementation. I think this should
be in the bug database.


Hmm, I'll see if I can use that, thanks.

--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-05 Thread Jacob Carlborg

On 2012-10-04 16:09, Jesse Phillips wrote:


IIRC, inout must be applied to the return type too, and it only works in
templates.


What? The whole point of inout is to NOT have to use templates since 
the compiler will generate the same code anyway.


http://dlang.org/function.html#inout-functions

I also tried to make it a template but I get the same result. Actually 
in my original code it's a template.


--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-05 Thread Jacob Carlborg

On 2012-10-04 16:18, Ali Çehreli wrote:


inout is like a template on 'mutable', const, and immutable; but it need
not be applied to templates. Here is a simple example that transfers the
mutability to the return type:


I do think I understand how inout works, or at least I thought. I 
don't understand how the delegate affects anything. If I remove the 
delegate to this code it compiles:


void foo (inout int[] arr)
{
auto a = arr[0];
}

My actual problem is that I want to be able to pass both mutable, const 
and immutable to a function. In that function I want the mutability to 
persist.


I first used const for my function and that works, kind of. The problem 
if I do like this:


void foo (const int[] arr)
{
auto s = typeid(typeof(arr)).toString;
// here s will be something like const(const(int)[])
}

I doesn't matter if I pass immutable or mutable, s will always be 
const(const(int)[]. So I thought, hey, that's what inout is for, I 
use that, then everything blows up.


I'm using typeid(typeof(arr)) in my serialization library to get a 
string representation of a type. I would prefer that the mutability was 
correct.


--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-05 Thread Ali Çehreli

On 10/04/2012 11:30 PM, Jacob Carlborg wrote:

On 2012-10-04 16:18, Ali Çehreli wrote:


inout is like a template on 'mutable', const, and immutable; but it need
not be applied to templates. Here is a simple example that transfers the
mutability to the return type:


I do think I understand how inout works, or at least I thought. I
don't understand how the delegate affects anything. If I remove the
delegate to this code it compiles:

void foo (inout int[] arr)
{
auto a = arr[0];
}

My actual problem is that I want to be able to pass both mutable, const
and immutable to a function. In that function I want the mutability to
persist.

I first used const for my function and that works, kind of. The problem
if I do like this:

void foo (const int[] arr)
{
auto s = typeid(typeof(arr)).toString;
// here s will be something like const(const(int)[])
}

I doesn't matter if I pass immutable or mutable, s will always be
const(const(int)[]. So I thought, hey, that's what inout is for, I
use that, then everything blows up.

I'm using typeid(typeof(arr)) in my serialization library to get a
string representation of a type. I would prefer that the mutability was
correct.



This workaround makes the compiler happy:

void foo (inout(int)[] arr)
{
auto a = (inout int) { auto b = arr[0]; };
}

But probably not what you want. :/

IIRC, inout has bugs and incomplete implementation. I think this should 
be in the bug database.


Ali


Re: Using inout in delegates

2012-10-05 Thread Steven Schveighoffer

On Thu, 04 Oct 2012 09:49:48 -0400, Jacob Carlborg d...@me.com wrote:


void foo (inout int[] arr)
{
 auto a = { auto b = arr[0]; };
}

void main ()
{
 auto a = [3, 4, 5];
 foo(a);
}

Compiling the above code with DMD 2.060 results in the following error  
message:


Error: variable main.foo.__lambda1.b inout variables can only be  
declared inside inout functions
Failed: /Users/jacob/.dvm/bin/dvm-current-dc  -v -o-  
'/Users/jacob/development/d/main.d' -I'/Users/jacob/development/d'  
 /Users/jacob/development/d/main.d.deps


Is this a bug, a limitation of inout/delegate or am I doing something  
else wrong?


It is a quirk of how inout is implemented.  There are definitely some very  
tricky situations that inout has uncovered, and I think not all of them  
are handled gracefully.


In my first vision for inout, I posited that inout variables should only  
be valid within inout functions.  No point in declaring inout variables if  
you don't have inout parameters or return values, right?  I mean the point  
of in out means what you get in is what you put out.  So if you aren't  
using a wildcard on an input or output, there is no point of having an  
inout variable that can't be transferred anywhere.


But logically, inout is simply another form of const.  One that acts like  
immutable, but could refer to mutable data.  Declaring something inout  
inside a non-inout function is useless, but not harmful.  I think now, it  
should be allowed, because it's more useful to use auto in these  
situations, and IFTI goes into fits if you don't allow it.


However, your case is interesting.  A delegate is a function, and  
functions which are inout have the special feature of transferring const.   
In this case, you are pulling the data from the context pointer, not from  
a parameter.  But the inout for your delegate may be a *different* inout  
than the one in your parameter.


Here is a more demonstratable case:

void foo(inout int* a)
{
   int x;
   inout(int) * foosub(inout(int) * b)
   {
  inout(int) *result = a  b ? a : b;
  return result;
   }

   int *n = foosub(x);
}

Note that n could end up being equal to a!  Which means we have  
effectively removed the inout qualifier from it (very bad).  I don't even  
know if the above compiles, but I suspect it does.


There is a very confusing aspect of inout.  When inout is inside a  
function, it's actual type is based solely on the function call itself.   
It actually should be that a and b above have *different* unassignable  
types.  But it is very difficult and confusing thing to understand and  
implement, much less explain.


I think at some point, inout needs another overhaul before it is truly a  
complete feature.


-Steve


Using inout in delegates

2012-10-04 Thread Jacob Carlborg

void foo (inout int[] arr)
{
auto a = { auto b = arr[0]; };
}

void main ()
{
auto a = [3, 4, 5];
foo(a);
}

Compiling the above code with DMD 2.060 results in the following error 
message:


Error: variable main.foo.__lambda1.b inout variables can only be 
declared inside inout functions
Failed: /Users/jacob/.dvm/bin/dvm-current-dc  -v -o- 
'/Users/jacob/development/d/main.d' -I'/Users/jacob/development/d' 
/Users/jacob/development/d/main.d.deps


Is this a bug, a limitation of inout/delegate or am I doing something 
else wrong?


--
/Jacob Carlborg


Re: Using inout in delegates

2012-10-04 Thread Jesse Phillips

On Thursday, 4 October 2012 at 13:55:39 UTC, Jacob Carlborg wrote:

void foo (inout int[] arr)
{
auto a = { auto b = arr[0]; };
}

void main ()
{
auto a = [3, 4, 5];
foo(a);
}

Compiling the above code with DMD 2.060 results in the 
following error message:


Error: variable main.foo.__lambda1.b inout variables can only 
be declared inside inout functions
Failed: /Users/jacob/.dvm/bin/dvm-current-dc  -v -o- 
'/Users/jacob/development/d/main.d' 
-I'/Users/jacob/development/d'

/Users/jacob/development/d/main.d.deps

Is this a bug, a limitation of inout/delegate or am I doing 
something else wrong?


IIRC, inout must be applied to the return type too, and it only 
works in templates.


Re: Using inout in delegates

2012-10-04 Thread Ali Çehreli

On 10/04/2012 07:09 AM, Jesse Phillips wrote:

On Thursday, 4 October 2012 at 13:55:39 UTC, Jacob Carlborg wrote:

void foo (inout int[] arr)
{
auto a = { auto b = arr[0]; };
}

void main ()
{
auto a = [3, 4, 5];
foo(a);
}

Compiling the above code with DMD 2.060 results in the following error
message:

Error: variable main.foo.__lambda1.b inout variables can only be
declared inside inout functions
Failed: /Users/jacob/.dvm/bin/dvm-current-dc -v -o-
'/Users/jacob/development/d/main.d' -I'/Users/jacob/development/d'
/Users/jacob/development/d/main.d.deps

Is this a bug, a limitation of inout/delegate or am I doing something
else wrong?


IIRC, inout must be applied to the return type too, and it only works in
templates.


inout is like a template on 'mutable', const, and immutable; but it need 
not be applied to templates. Here is a simple example that transfers the 
mutability to the return type:


  http://ddili.org/ders/d.en/function_parameters.html

inout(int)[] trimmed(inout(int)[] slice)
{
if (slice.length) {
--slice.length;   // trim from the end

if (slice.length) {
slice = slice[1 .. $];// trim from the beginning
}
}

return slice;
}

All three blocks below compile:

{
int[] numbers = [ 5, 6, 7, 8, 9 ];
// The return type is slice of mutable elements
int[] middle = trimmed(numbers);
middle[] *= 10;
writeln(middle);
}

{
immutable int[] numbers = [ 10, 11, 12 ];
// The return type is slice of immutable elements
immutable int[] middle = trimmed(numbers);
writeln(middle);
}

{
const int[] numbers = [ 13, 14, 15, 16 ];
// The return type is slice of const elements
const int[] middle = trimmed(numbers);
writeln(middle);
}

inout can also be applied to member functions where the 'this' reference 
takes the mutability of a parameter and all of the member accesses 
becomes mutable, const, or immutable.


Ali