September 07, 2010
On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
> Yes, a valid return. Your function should be:
>
> void foo(void delegate(const(C) f) const
>
> It helps to understand that inout/const/immutable has NOTHING to do with
> code generation, it only has to do with limiting what compiles. For this
> reason, an inout function is compiled once, and works on all three
> constancies (4 if you have a nested inout function). For the entire
> function any inout variable is treated as a non-changeable value, just
> like const. Then when you return, it's converted at the call site back
> to the constancy with which it was called. If the return value is void,
> then there's nothing to convert, and no reason to use inout over const.
>
> I'll repeat -- there is no benefit to inout if you are not returning
> anything.
>
> -Steve

That's not an equivalent function signature. Or maybe it is, but look at this (sorry it's so long):

class C {
    int x;
    this(int y) { x = y; }

    inout(int*) foo() inout {
        return &x;
    }
    void bar(void delegate(int*) f) {
        f(&x);
    }
    void bar(void delegate(const(int*)) f) const {
        f(&x);
    }
    void bar(void delegate(immutable(int*)) f) immutable {
        f(&x);
    }
}

void main() {

    immutable(int)* wah;
    void wahwah(immutable(int*) x) {
        wah = x;
    }
    auto c = new immutable(C)(10);
    wahwah(c.foo);  // why is this privilegied with inout
    c.bar(&wahwah); // and this not?

    writeln(*wah);

}

Can't use void delegate(const(int*)) there.
September 07, 2010
On Tue, 07 Sep 2010 11:37:20 -0400, Pelle <pelle.mansson@gmail.com> wrote:

> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>> Yes, a valid return. Your function should be:
>>
>> void foo(void delegate(const(C) f) const
>>
>> It helps to understand that inout/const/immutable has NOTHING to do with
>> code generation, it only has to do with limiting what compiles. For this
>> reason, an inout function is compiled once, and works on all three
>> constancies (4 if you have a nested inout function). For the entire
>> function any inout variable is treated as a non-changeable value, just
>> like const. Then when you return, it's converted at the call site back
>> to the constancy with which it was called. If the return value is void,
>> then there's nothing to convert, and no reason to use inout over const.
>>
>> I'll repeat -- there is no benefit to inout if you are not returning
>> anything.
>>
>> -Steve
>
> That's not an equivalent function signature. Or maybe it is, but look at this (sorry it's so long):
>
> class C {
>      int x;
>      this(int y) { x = y; }
>
>      inout(int*) foo() inout {
>          return &x;
>      }
>      void bar(void delegate(int*) f) {
>          f(&x);
>      }
>      void bar(void delegate(const(int*)) f) const {
>          f(&x);
>      }
>      void bar(void delegate(immutable(int*)) f) immutable {
>          f(&x);
>      }
> }
>
> void main() {
>
>      immutable(int)* wah;
>      void wahwah(immutable(int*) x) {
>          wah = x;
>      }
>      auto c = new immutable(C)(10);
>      wahwah(c.foo);  // why is this privilegied with inout
>      c.bar(&wahwah); // and this not?
>
>      writeln(*wah);
>
> }
>
> Can't use void delegate(const(int*)) there.

Thanks for clarifying, I didn't quite understand the usage before.

This is a limitation of inout's design.  Technically inout requires a single inout output, and can have multiple inout inputs.  Your example matches that description, so in theory it's possible.

But to simplify things, a function's only inout output must be on the return value.  So things like void fn(inout int* x, out inout(int) y) don't qualify either.

IMO there is a whole host of implicit delegate casting that should be possible, but isn't, including delegate contravariance.  However, let's get inout working as it's currently designed before we go relaxing the requirements.  I'm not a compiler/language designer, so I'm unsure if what you want has any pitfalls.

-Steve
September 07, 2010
On 2010-09-07 17:37, Pelle wrote:
> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>> Yes, a valid return. Your function should be:
>>
>> void foo(void delegate(const(C) f) const
>>
>> It helps to understand that inout/const/immutable has NOTHING to do with
>> code generation, it only has to do with limiting what compiles. For this
>> reason, an inout function is compiled once, and works on all three
>> constancies (4 if you have a nested inout function). For the entire
>> function any inout variable is treated as a non-changeable value, just
>> like const. Then when you return, it's converted at the call site back
>> to the constancy with which it was called. If the return value is void,
>> then there's nothing to convert, and no reason to use inout over const.
>>
>> I'll repeat -- there is no benefit to inout if you are not returning
>> anything.
>>
>> -Steve
>
> That's not an equivalent function signature. Or maybe it is, but look at
> this (sorry it's so long):
>
> class C {
> int x;
> this(int y) { x = y; }
>
> inout(int*) foo() inout {
> return &x;
> }
> void bar(void delegate(int*) f) {
> f(&x);
> }
> void bar(void delegate(const(int*)) f) const {
> f(&x);
> }
> void bar(void delegate(immutable(int*)) f) immutable {
> f(&x);
> }
> }
>
> void main() {
>
> immutable(int)* wah;
> void wahwah(immutable(int*) x) {
> wah = x;
> }
> auto c = new immutable(C)(10);
> wahwah(c.foo); // why is this privilegied with inout
> c.bar(&wahwah); // and this not?
>
> writeln(*wah);
>
> }
>
> Can't use void delegate(const(int*)) there.

That won't work, you can't have inout on return of a function without having inout for a least one parameter. The compiler can't know what to resolve inout to, mutable, immutable or const.

-- 
/Jacob Carlborg
September 08, 2010
On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> On Tue, 07 Sep 2010 11:37:20 -0400, Pelle <pelle.mansson@gmail.com> wrote:
>
>> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>>> Yes, a valid return. Your function should be:
>>>
>>> void foo(void delegate(const(C) f) const
>>>
>>> It helps to understand that inout/const/immutable has NOTHING to do with
>>> code generation, it only has to do with limiting what compiles. For this
>>> reason, an inout function is compiled once, and works on all three
>>> constancies (4 if you have a nested inout function). For the entire
>>> function any inout variable is treated as a non-changeable value, just
>>> like const. Then when you return, it's converted at the call site back
>>> to the constancy with which it was called. If the return value is void,
>>> then there's nothing to convert, and no reason to use inout over const.
>>>
>>> I'll repeat -- there is no benefit to inout if you are not returning
>>> anything.
>>>
>>> -Steve
>>
>> That's not an equivalent function signature. Or maybe it is, but look at this (sorry it's so long):
>>
>> class C {
>>      int x;
>>      this(int y) { x = y; }
>>
>>      inout(int*) foo() inout {
>>          return &x;
>>      }
>>      void bar(void delegate(int*) f) {
>>          f(&x);
>>      }
>>      void bar(void delegate(const(int*)) f) const {
>>          f(&x);
>>      }
>>      void bar(void delegate(immutable(int*)) f) immutable {
>>          f(&x);
>>      }
>> }
>>
>> void main() {
>>
>>      immutable(int)* wah;
>>      void wahwah(immutable(int*) x) {
>>          wah = x;
>>      }
>>      auto c = new immutable(C)(10);
>>      wahwah(c.foo);  // why is this privilegied with inout
>>      c.bar(&wahwah); // and this not?
>>
>>      writeln(*wah);
>>
>> }
>>
>> Can't use void delegate(const(int*)) there.
>
> Thanks for clarifying, I didn't quite understand the usage before.
>
> This is a limitation of inout's design.  Technically inout requires a single inout output, and can have multiple inout inputs.  Your example matches that description, so in theory it's possible.

I realized last night that this won't work.  Simple reason -- during an inout function, the function promises to treat the arguments as if they were const.

If your class instance was mutable, this would not be true, e.g.:

class C
{
   int x;
   void bar(void delegate(inout(int)* f) inout { f(&x); }
}

void main() {

   auto c = new C;
   void dg(int *f) {*f = 10;}
   c.bar(&dg); // modifies c, even though the function is marked as inout
}

-Steve
September 08, 2010
On 09/08/2010 02:24 PM, Steven Schveighoffer wrote:
> On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>
>> On Tue, 07 Sep 2010 11:37:20 -0400, Pelle <pelle.mansson@gmail.com>
>> wrote:
>>
>>> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>>>> Yes, a valid return. Your function should be:
>>>>
>>>> void foo(void delegate(const(C) f) const
>>>>
>>>> It helps to understand that inout/const/immutable has NOTHING to do
>>>> with
>>>> code generation, it only has to do with limiting what compiles. For
>>>> this
>>>> reason, an inout function is compiled once, and works on all three
>>>> constancies (4 if you have a nested inout function). For the entire
>>>> function any inout variable is treated as a non-changeable value, just
>>>> like const. Then when you return, it's converted at the call site back
>>>> to the constancy with which it was called. If the return value is void,
>>>> then there's nothing to convert, and no reason to use inout over const.
>>>>
>>>> I'll repeat -- there is no benefit to inout if you are not returning
>>>> anything.
>>>>
>>>> -Steve
>>>
>>> That's not an equivalent function signature. Or maybe it is, but look
>>> at this (sorry it's so long):
>>>
>>> class C {
>>> int x;
>>> this(int y) { x = y; }
>>>
>>> inout(int*) foo() inout {
>>> return &x;
>>> }
>>> void bar(void delegate(int*) f) {
>>> f(&x);
>>> }
>>> void bar(void delegate(const(int*)) f) const {
>>> f(&x);
>>> }
>>> void bar(void delegate(immutable(int*)) f) immutable {
>>> f(&x);
>>> }
>>> }
>>>
>>> void main() {
>>>
>>> immutable(int)* wah;
>>> void wahwah(immutable(int*) x) {
>>> wah = x;
>>> }
>>> auto c = new immutable(C)(10);
>>> wahwah(c.foo); // why is this privilegied with inout
>>> c.bar(&wahwah); // and this not?
>>>
>>> writeln(*wah);
>>>
>>> }
>>>
>>> Can't use void delegate(const(int*)) there.
>>
>> Thanks for clarifying, I didn't quite understand the usage before.
>>
>> This is a limitation of inout's design. Technically inout requires a
>> single inout output, and can have multiple inout inputs. Your example
>> matches that description, so in theory it's possible.
>
> I realized last night that this won't work. Simple reason -- during an
> inout function, the function promises to treat the arguments as if they
> were const.
>
> If your class instance was mutable, this would not be true, e.g.:
>
> class C
> {
> int x;
> void bar(void delegate(inout(int)* f) inout { f(&x); }
> }
>
> void main() {
>
> auto c = new C;
> void dg(int *f) {*f = 10;}
> c.bar(&dg); // modifies c, even though the function is marked as inout
> }
>
> -Steve

Well, inout was conceived as a counter to where you need to write the exact same function for every type of constness, was it not? :-)
September 08, 2010
On Wed, 08 Sep 2010 12:38:44 -0400, Pelle <pelle.mansson@gmail.com> wrote:

> On 09/08/2010 02:24 PM, Steven Schveighoffer wrote:
>> On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer
>> <schveiguy@yahoo.com> wrote:
>>
>>> On Tue, 07 Sep 2010 11:37:20 -0400, Pelle <pelle.mansson@gmail.com>
>>> wrote:
>>>
>>>> On 09/07/2010 04:33 PM, Steven Schveighoffer wrote:
>>>>> Yes, a valid return. Your function should be:
>>>>>
>>>>> void foo(void delegate(const(C) f) const
>>>>>
>>>>> It helps to understand that inout/const/immutable has NOTHING to do
>>>>> with
>>>>> code generation, it only has to do with limiting what compiles. For
>>>>> this
>>>>> reason, an inout function is compiled once, and works on all three
>>>>> constancies (4 if you have a nested inout function). For the entire
>>>>> function any inout variable is treated as a non-changeable value, just
>>>>> like const. Then when you return, it's converted at the call site back
>>>>> to the constancy with which it was called. If the return value is void,
>>>>> then there's nothing to convert, and no reason to use inout over const.
>>>>>
>>>>> I'll repeat -- there is no benefit to inout if you are not returning
>>>>> anything.
>>>>>
>>>>> -Steve
>>>>
>>>> That's not an equivalent function signature. Or maybe it is, but look
>>>> at this (sorry it's so long):
>>>>
>>>> class C {
>>>> int x;
>>>> this(int y) { x = y; }
>>>>
>>>> inout(int*) foo() inout {
>>>> return &x;
>>>> }
>>>> void bar(void delegate(int*) f) {
>>>> f(&x);
>>>> }
>>>> void bar(void delegate(const(int*)) f) const {
>>>> f(&x);
>>>> }
>>>> void bar(void delegate(immutable(int*)) f) immutable {
>>>> f(&x);
>>>> }
>>>> }
>>>>
>>>> void main() {
>>>>
>>>> immutable(int)* wah;
>>>> void wahwah(immutable(int*) x) {
>>>> wah = x;
>>>> }
>>>> auto c = new immutable(C)(10);
>>>> wahwah(c.foo); // why is this privilegied with inout
>>>> c.bar(&wahwah); // and this not?
>>>>
>>>> writeln(*wah);
>>>>
>>>> }
>>>>
>>>> Can't use void delegate(const(int*)) there.
>>>
>>> Thanks for clarifying, I didn't quite understand the usage before.
>>>
>>> This is a limitation of inout's design. Technically inout requires a
>>> single inout output, and can have multiple inout inputs. Your example
>>> matches that description, so in theory it's possible.
>>
>> I realized last night that this won't work. Simple reason -- during an
>> inout function, the function promises to treat the arguments as if they
>> were const.
>>
>> If your class instance was mutable, this would not be true, e.g.:
>>
>> class C
>> {
>> int x;
>> void bar(void delegate(inout(int)* f) inout { f(&x); }
>> }
>>
>> void main() {
>>
>> auto c = new C;
>> void dg(int *f) {*f = 10;}
>> c.bar(&dg); // modifies c, even though the function is marked as inout
>> }
>>
>> -Steve
>
> Well, inout was conceived as a counter to where you need to write the exact same function for every type of constness, was it not? :-)

Not exactly, it was conceived as a solution for the case where you would normally write a const function, but you don't want it to alter your const contract with the object in question.  Basically, you want a function that promises not to alter the parameters, but gives you back one of your parameters or a portion of one of them in the same constancy you pass in.  The classic example is a property getter.

If you are not returning a portion of the input, then you can use const instead.

-Steve
September 12, 2010
"Jacob Carlborg" <doob@me.com> wrote in message news:i5t61q$2j76$1@digitalmars.com...
>
> If you're not going to modify the content of the array I think this will work:
>
> void foo (T) (const(T)[] collection, T elem) {}
>
> This will allow both mutable, immutable and const arrays. But it will not let you modify the array like this:
>
> collection[3] = 'a';
>

On DMD 2.048, This isn't working for me:

-----------------------------------------
void foo(T)(const(T)[] coll, T elem)
{
}

void main()
{
    string x = "hello";
    foo(x, x[1]);
}

-----------------------------------------

Result:
-----------------------------------------
testStringAndChar.d(8): Error: template testStringAndChar.foo(T) does not
match any function template declaration
testStringAndChar.d(8): Error: template testStringAndChar.foo(T) cannot
deduce template function from argument types !()(string,immutable(char))
-----------------------------------------

I figured that was just because 'const(immutable(T))[]' doesn't make much sence, so I tried this and got the exact same error messages:

-----------------------------------------
import std.traits;

void foo(T)(const(Unqual!T)[] coll, T elem)
{
}

void main()
{
    string x = "hello";
    foo(x, x[1]);
}
-----------------------------------------

It seems to be a problem with IFTI, because this does work with both
versions:
foo!char(x, x[1]);

Kind of a pain.


September 12, 2010
On 9/11/2010 9:32 PM, Nick Sabalausky wrote:
> "Jacob Carlborg" <doob@me.com> wrote in message news:i5t61q$2j76$1@digitalmars.com...
>>
>> If you're not going to modify the content of the array I think this will work:
>>
>> void foo (T) (const(T)[] collection, T elem) {}
>>
>> This will allow both mutable, immutable and const arrays. But it will not let you modify the array like this:
>>
>> collection[3] = 'a';
>>
> 
> On DMD 2.048, This isn't working for me:
> 
> -----------------------------------------
> void foo(T)(const(T)[] coll, T elem)
> {
> }
> 
> void main()
> {
>     string x = "hello";
>     foo(x, x[1]);
> }
> 
> -----------------------------------------
> 
> Result:
> -----------------------------------------
> testStringAndChar.d(8): Error: template testStringAndChar.foo(T) does not
> match any function template declaration
> testStringAndChar.d(8): Error: template testStringAndChar.foo(T) cannot
> deduce template function from argument types !()(string,immutable(char))
> -----------------------------------------
> 
> I figured that was just because 'const(immutable(T))[]' doesn't make much sence, so I tried this and got the exact same error messages:
> 
> -----------------------------------------
> import std.traits;
> 
> void foo(T)(const(Unqual!T)[] coll, T elem)
> {
> }
> 
> void main()
> {
>     string x = "hello";
>     foo(x, x[1]);
> }
> -----------------------------------------
> 
> It seems to be a problem with IFTI, because this does work with both
> versions:
> foo!char(x, x[1]);
> 
> Kind of a pain.
> 

http://d.puremagic.com/issues/show_bug.cgi?id=2594

1 2
Next ›   Last »