November 13, 2012
On 13.11.2012 2:16, martin wrote:
> On Monday, 12 November 2012 at 23:38:43 UTC, luka8088 wrote:
>> What about making this a default behavior and introducing a new
>> keyword if the function wants to modify the argument but it is not ref
>> (pass by value) ? The reason I think that this should be a default
>> behavior because not many functions actually modify their arguments
>> and so it leaves a lot of space for optimization.
>>
>> For example:
>>
>> void f (int x, val int y, ref int z) {
>> x = 1; // x is not copied
>> // compiler throws an error, x is not passed by value
>> // and therefor could not / should not be changed
>> y = 2; // ok, y is copied
>> z = 3; // ok, z is a reference
>> }
>
> Your proposal isn't really related to this thread's topic, but I

Um, "Const ref and rvalues again", I suggest it to be the default behavior, how is this not related ?

> understand what you mean (although your code comments distract me a bit):
>
> void f(const int x, int y, ref int z); =>
> void f(int x, val/mutable int y, ref int z);
>

Yes, you understood correctly:
void f (const ref int x, int y, ref int z); =>
void f (int x, val int y, ref int z);

The point here is to make "We need a way for a function to declare that it doesn't want it's argument to be copied, but it also doesn't care whether the argument is an rvalue or an lvalue. " a default behavior.

> I use const/in ;) parameters a lot in my code too to prevent accidental
> modifications, so my function signatures may be more compact by treating
> normal pass-by-value parameters as const if not denoted with a special
> keyword. I guess it wouldn't be very important for optimization though
> because I'd expect the optimizer to detect unchanged parameters. Anyway,
> your proposal would completely break existing code.

Would it ? How many functions actually change their non ref/out arguments ? Can you point out any existing public code that would be broken ?

November 13, 2012
On Tuesday, 13 November 2012 at 08:34:19 UTC, luka8088 wrote:
> Would it ? How many functions actually change their non ref/out arguments ? Can you point out any existing public code that would be broken ?

 It would be possible that if the language became const-preference that a simple regex tool could be made that would do the conversions, thereby any code broken in this way could be un-broken just as easily; But that assumes you aren't using mixins or magic as part of your signatures.

 Somehow this reminds me a little of when I worked at a company where we were trying out asp as a web server; The whole VB script was by default 'by ref' so you littered all your functions with 'byVal' in order for your behavior to act as you expected.


 Anyways, my take on this is consistency would be a lot more difficult and annoying unless you had different rules for the signature vs all other references... I doubt you would say 'this is mutable here but immutable here' type of thing. So.... assuming 'mutable' is used, then the following would be comparable...

//D as of now
int func(int x, int y, const ref int z) {
  int something; //mutable far more likely
  int something2;
  const int lessOften;
}

//then would become...
//if x & y aren't ever changed then mutable may be unneeded.
mutable int func(mutable int x, mutable int y, ref int z) {
  mutable int something;
  mutable int something2;
  int lessOften;      //const (once set)
}

//or for inconsistancy..
//mutable or const as a return? (Or either?)
//and which would/should you use to reverse it?
int func(mutable int x, mutable int y, ref int z) {
  int something;       //mutable
  int something2;
  const int lessOften; //const
}

 Seems in a function body you are far more likely to have mutable items, while in the signature you're more likely to have const items; But mixing them or changing how you do it would likely break code very easily if it isn't signature only, but it doesn't seem like a good idea...

 Now in the above the function may not specify 'x' is const it doesn't guarantees it ever changes it (but it's a local copy so does it matter?), but specifically specifying it may be more clutter than actually useful.

 All in all it seems like it would have far more confusion (and break code) than help; although having it prefer const versions of functions/methods to non-const ones should probably have a higher priority (Although you then couldn't have a non-const one unless it was as part of the struct/class constness and not the variables, (and ref preferred over non-ref)).
November 13, 2012
On 13.11.2012 11:00, Era Scarecrow wrote:
> On Tuesday, 13 November 2012 at 08:34:19 UTC, luka8088 wrote:
>> Would it ? How many functions actually change their non ref/out
>> arguments ? Can you point out any existing public code that would be
>> broken ?
>
> It would be possible that if the language became const-preference that a
> simple regex tool could be made that would do the conversions, thereby
> any code broken in this way could be un-broken just as easily; But that
> assumes you aren't using mixins or magic as part of your signatures.
>
> Somehow this reminds me a little of when I worked at a company where we
> were trying out asp as a web server; The whole VB script was by default
> 'by ref' so you littered all your functions with 'byVal' in order for
> your behavior to act as you expected.
>
>
> Anyways, my take on this is consistency would be a lot more difficult
> and annoying unless you had different rules for the signature vs all
> other references... I doubt you would say 'this is mutable here but
> immutable here' type of thing. So.... assuming 'mutable' is used, then
> the following would be comparable...
>
> //D as of now
> int func(int x, int y, const ref int z) {
> int something; //mutable far more likely
> int something2;
> const int lessOften;
> }
>
> //then would become...
> //if x & y aren't ever changed then mutable may be unneeded.
> mutable int func(mutable int x, mutable int y, ref int z) {
> mutable int something;
> mutable int something2;
> int lessOften; //const (once set)
> }
>
> //or for inconsistancy..
> //mutable or const as a return? (Or either?)
> //and which would/should you use to reverse it?
> int func(mutable int x, mutable int y, ref int z) {
> int something; //mutable
> int something2;
> const int lessOften; //const
> }
>
> Seems in a function body you are far more likely to have mutable items,
> while in the signature you're more likely to have const items; But
> mixing them or changing how you do it would likely break code very
> easily if it isn't signature only, but it doesn't seem like a good idea...
>
> Now in the above the function may not specify 'x' is const it doesn't
> guarantees it ever changes it (but it's a local copy so does it
> matter?), but specifically specifying it may be more clutter than
> actually useful.
>
> All in all it seems like it would have far more confusion (and break
> code) than help; although having it prefer const versions of
> functions/methods to non-const ones should probably have a higher
> priority (Although you then couldn't have a non-const one unless it was
> as part of the struct/class constness and not the variables, (and ref
> preferred over non-ref)).

Can you point out any existing public code that would be broken ?
November 13, 2012
On Tuesday, 13 November 2012 at 10:09:27 UTC, luka8088 wrote:
> Can you point out any existing public code that would be broken?

 Off hand, no.. I'm not that familiar with a lot of the code or the in depth details of phoboes; However suddenly reversing what is mutable and what is const is bound to break a lot of things even unintentionally.

 Hmmm.. Does remind me of a bit of my code sometimes... Something went like...

 class S {
   void func(S s) {
     if (!s)
       s = new S(); //create one if not passed in.

     //process using S and s (be it new or passed in)
   }
 }

 That would certainly cause a problem.. In my own code example it may empty the pointer/reference if certain requirements were met, and then use if the class reference was set or null for later logic (even if the object referenced to wasn't changed...). Course being passed something like a string... (seems the most likely place you'd find it), in which case using .dup on the input string right back into the variable would be completely understandable. ie:

string someStringTransformationWithCOW(string x) {
  //if COW'd then
  x = x.dup;

  //...
  return x;
}

 Course having the input as char[] rather than string makes more sense for on the fly changes before returning it...
November 13, 2012
On Tuesday, 13 November 2012 at 08:34:19 UTC, luka8088 wrote:
>> Your proposal isn't really related to this thread's topic
>
> Um, "Const ref and rvalues again", I suggest it to be the default behavior, how is this not related ?

The topic here is binding rvalues to (const) ref parameters. You, on the other hand, are suggesting to flip the constness of by-value parameters (int => val/mutable int, const int => int), which affects both rvalues and lvalues (no difference between them) and only by-value parameters.

> Yes, you understood correctly:
> void f (const ref int x, int y, ref int z); =>
> void f (int x, val int y, ref int z);
>
> The point here is to make "We need a way for a function to declare that it doesn't want it's argument to be copied, but it also doesn't care whether the argument is an rvalue or an lvalue. " a default behavior.

So now tell me why argument x wouldn't be copied. It's passed by value, so of course it is copied (lvalues)/moved (rvalues) just as it is now. The only difference is that the parameter won't be modified by f().

I guess what you furthermore implicate is that you'd expect the compiler to automatically pass appropriate arguments to such parameters by reference to avoid copying (for large structs or structs with non-trivial copy constructors). Such a (handy!) optimization is sadly not possible due to aliasing issues, e.g.:

int foo(ref int dst, const int src)
{
    dst = 2*src;
    return src;
}
// "optimized" foo():
int bar(ref int dst, const ref int src)
{
    dst = 2*src;
    return src;
}

int i = 1;
assert(foo(i, i) == 1 && i == 2); // okay
i = 1;
assert(bar(i, i) == 2 && i == 2); // wtf?!
// the const src parameter is actually modified since the
// original argument i is also used as mutable dst parameter!

> Would it ? How many functions actually change their non ref/out arguments ? Can you point out any existing public code that would be broken ?

I don't want to look for examples in Phobos etc. as it should be trivial to imagine cases such as:

void bla(float x)
{
    // restrict x to safe range [0,1]
    x = max(0, min(1, x));
}
November 14, 2012
On 13.11.2012 15:07, martin wrote:
> On Tuesday, 13 November 2012 at 08:34:19 UTC, luka8088 wrote:
>>> Your proposal isn't really related to this thread's topic
>>
>> Um, "Const ref and rvalues again", I suggest it to be the default
>> behavior, how is this not related ?
>
> The topic here is binding rvalues to (const) ref parameters. You, on the
> other hand, are suggesting to flip the constness of by-value parameters
> (int => val/mutable int, const int => int), which affects both rvalues
> and lvalues (no difference between them) and only by-value parameters.
>
>> Yes, you understood correctly:
>> void f (const ref int x, int y, ref int z); =>
>> void f (int x, val int y, ref int z);
>>
>> The point here is to make "We need a way for a function to declare
>> that it doesn't want it's argument to be copied, but it also doesn't
>> care whether the argument is an rvalue or an lvalue. " a default
>> behavior.
>
> So now tell me why argument x wouldn't be copied. It's passed by value,
> so of course it is copied (lvalues)/moved (rvalues) just as it is now.
> The only difference is that the parameter won't be modified by f().
>
> I guess what you furthermore implicate is that you'd expect the compiler
> to automatically pass appropriate arguments to such parameters by
> reference to avoid copying (for large structs or structs with
> non-trivial copy constructors). Such a (handy!) optimization is sadly
> not possible due to aliasing issues, e.g.:
>
> int foo(ref int dst, const int src)
> {
> dst = 2*src;
> return src;
> }
> // "optimized" foo():
> int bar(ref int dst, const ref int src)
> {
> dst = 2*src;
> return src;
> }
>
> int i = 1;
> assert(foo(i, i) == 1 && i == 2); // okay
> i = 1;
> assert(bar(i, i) == 2 && i == 2); // wtf?!
> // the const src parameter is actually modified since the
> // original argument i is also used as mutable dst parameter!
>
>> Would it ? How many functions actually change their non ref/out
>> arguments ? Can you point out any existing public code that would be
>> broken ?
>
> I don't want to look for examples in Phobos etc. as it should be trivial
> to imagine cases such as:
>
> void bla(float x)
> {
> // restrict x to safe range [0,1]
> x = max(0, min(1, x));
> }

I see, you are correct, if it is not copied then it can be changed before function finished through some other references hence it must be copied.
Next ›   Last »
1 2 3 4 5 6 7 8 9 10 11
Top | Discussion index | About this forum | D home