www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Would like to see ref and out required for function calls

reply "Kevin McTaggart" <kevin.mctaggart drdc-rddc.gc.ca> writes:
I've been looking at migrating a reasonably large ship motion 

quite enthusiastic about D, and most of my problems have been 
relatively minor (e.g., inconsistent bugs with 
std.container.Array, would like orange serialization to give me 
an error telling me I didn't register a class before calling 
serialize).  I suggest that the language require ref and out when 

to understand, and would also eliminate the problem I had when 
the wrong function from the following choices was mistakenly 
called:

parseLineInts(string text, int positionStart, out int j0, out int 
j1)

parseLineInts(string text, out int j0, out int j1, out int j2)

I note that the second function calls another function as follows:
int positionStart = 1;
parseLineInts(text, positionStart, j0, j1, j2);

I look forward to seeing feedback from D experts.  This is the 
only significant change that I could think of recommending for 
the language.
Sep 07 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/7/12 1:34 PM, Kevin McTaggart wrote:
 I've been looking at migrating a reasonably large ship motion library

 enthusiastic about D, and most of my problems have been relatively minor
 (e.g., inconsistent bugs with std.container.Array, would like orange
 serialization to give me an error telling me I didn't register a class
 before calling serialize). I suggest that the language require ref and

 to understand, and would also eliminate the problem I had when the wrong
 function from the following choices was mistakenly called:

 parseLineInts(string text, int positionStart, out int j0, out int j1)

 parseLineInts(string text, out int j0, out int j1, out int j2)

 I note that the second function calls another function as follows:
 int positionStart = 1;
 parseLineInts(text, positionStart, j0, j1, j2);

 I look forward to seeing feedback from D experts. This is the only
 significant change that I could think of recommending for the language.
used to be required up until 4.0). Apparently users complained it was too unsightly. Andrei
Sep 07 2012
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/7/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 used to be required up until 4.0). Apparently users complained it was
 too unsightly.
If you like implicit ref then why did you choose to use pointers when implementing std.getopt?
Sep 07 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/7/12 4:55 PM, Andrej Mitrovic wrote:
 On 9/7/12, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:

 used to be required up until 4.0). Apparently users complained it was
 too unsightly.
If you like implicit ref then why did you choose to use pointers when implementing std.getopt?
At the time ref variadics weren't implemented. I should also add I joined D after ref was there. I don't have strong feelings one way or another. Andrei
Sep 07 2012
prev sibling next sibling parent dennis luehring <dl.soluz gmx.net> writes:
Am 07.09.2012 16:38, schrieb Andrei Alexandrescu:

 used to be required up until 4.0). Apparently users complained it was
 too unsightly.
reference link?
Sep 07 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/07/2012 04:38 PM, Andrei Alexandrescu wrote:
 ...

 used to be required up until 4.0). Apparently users complained it was
 too unsightly.

 Andrei
How do they deal with the increased ambiguity in overload resolution?
Sep 07 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/07/2012 05:51 PM, Timon Gehr wrote:
 How do they deal with the increased ambiguity in overload resolution?
Actually, it is simple. They just have to call the non-out overload when there is no out at the call site, regardless of the actual argument.
Sep 07 2012
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:


 in 5.0 (it used to be required up until 4.0). Apparently users 
 complained it was too unsightly.
Are you sure? This page about the Visual Studio 2012 shows that ref and out are required: http://msdn.microsoft.com/en-us/library/14akc2c7.aspx something. The idea of requiring ref/out at the all site was discussed some times in past. This idea has both advantages and disadvantages. It makes the code a bit longer, but gives the reader more information about what the call will do. In D there are also ref at the return value, I presume this is never going to require a "ref" at the call site. Bye, bearophile
Sep 07 2012
parent "Mehrdad" <wfunction hotmail.com> writes:
On Friday, 7 September 2012 at 16:46:36 UTC, bearophile wrote:
 Andrei Alexandrescu:


 in 5.0 (it used to be required up until 4.0). Apparently users 
 complained it was too unsightly.
Are you sure? This page about the Visual Studio 2012 shows that ref and out are required: http://msdn.microsoft.com/en-us/library/14akc2c7.aspx
+1
Sep 07 2012
prev sibling parent "David Piepgrass" <qwertie256 gmail.com> writes:

 in 5.0 (it used to be required up until 4.0). Apparently users 
 complained it was too unsightly.

 Andrei
multiple times and I never heard that. Anyway I don't mind if ref is not required, but it ticks me off that it is not *allowed*. Even in C++ I can use "OUT" and "IN OUT" at both the definition and call sites (I may as well, since Windows header files #define them already). The compiler doesn't verify it but I find it useful to make the code self-documenting. Some have said that "well if the the compiler doesn't enforce it then it's pointless, you won't be able to tell if a call site without 'ref' is passed by ref". But no, it's not pointless, because (1) if you see a call site WITH 'ref' then clearly it is passed by reference, (2) I would use 'ref' consistently in my own code so that when I look back at my code a year later, the absence of 'ref' is a clear indication that it is an input parameter, and (3) if the compiler offered the option to issue a warning when 'ref' is absent, statement (2) would be true 100% of the time, in my code, instead of just 98%. Most of the code I look at is my own so that's my primary motive for wanting 'ref'. Yes, if 'ref' were allowed, some people would not use it; so when looking at a new code base I'd have no guarantee that a parameter NOT marked ref is passed by value. But at least (1) still applies.
Sep 11 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, September 07, 2012 13:34:02 Kevin McTaggart wrote:
 I look forward to seeing feedback from D experts.  This is the
 only significant change that I could think of recommending for
 the language.
Regardless of the pros and cons of requiring explicit ref and out, it would break a lot of code if we started requiring it, so I don't think that there's any chance of such a change being made at this point. If/When we create D3 (which is years off), it could be discussed and possibly changed then, but I think that it's clearly too large a change for D2 at this point. - Jonathan M Davis
Sep 07 2012
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-09-07 13:34, Kevin McTaggart wrote:
 I've been looking at migrating a reasonably large ship motion library

 enthusiastic about D, and most of my problems have been relatively minor
 (e.g., inconsistent bugs with std.container.Array, would like orange
 serialization to give me an error telling me I didn't register a class
 before calling serialize).
Please report any bugs about Orange to https://github.com/jacob-carlborg/orange and I'll see what I can do about it. -- /Jacob Carlborg
Sep 07 2012
prev sibling next sibling parent reply "Chris Nicholson-Sauls" <ibisbasenji gmail.com> writes:
Given:

void func (ref int[], int)

If ref/out were required at the call site, this destroys UFCS.

int[] array;
array.func(0); // error, ref not specified by caller

Or would one expect something like:

(ref array).func(0);

...put simply, I hope not.

This suggestion has come up a couple times before, and each time 
failed to gain traction.  I wouldn't mind it as an option -- 
possibly even as a recommendation in most library code -- but as 
a requirement it honestly just gives me a headache.  Generally 
speaking, if a parameter being ref/out is surprising, there is 
something wrong with the design.  (There are times it is 
non-obvious in otherwise good code, this seems uncommon.)

For example, calling one of the *InPlace functions from Phobos, I 
immediately expect 'ref' -- otherwise, how to modify "in place" 
in a reliable (ie, non-allocating) manner?  Likewise, 'out' -- 
used pretty rarely in the first place -- sits in the same place 
pointers typically do, as auxiliary returns.  The category of 
functions/methods which use them is pretty self consistent.  
(What few corner cases remain would be better served by cleaning 
up tuples to make them more sane as return values.)

Given:

bool checkedEmitJ (Op, Params, ref const(Scope), Address, out 
Address)

I really don't want to have to call it as:

auto handled = checkedEmitJ(Op.CJmp, parms, ref _scope, suggest, 
out lval);

When the 'ref' and 'out' parameters listed are specified by the 
design and consistent across all the "-emit-" functions.
Sep 08 2012
parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 Given:

 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied. Also for 'const ref' parameters, callsite ref should not be necessary.
 This suggestion has come up a couple times before, and each time failed
 to gain traction.
argument modification should be explicit for value types, it is arguably important. It might be nice to have for D3.
 I wouldn't mind it as an option -- possibly even as a
 recommendation in most library code -- but as a requirement it honestly
 just gives me a headache.
As an option it would serve no practical purpose other than documentation.
 Generally speaking, if a parameter being
 ref/out is surprising, there is something wrong with the design.  (There
 are times it is non-obvious in otherwise good code, this seems uncommon.)
Yes but unfortunately bad design is going to be a reality sometimes. Also there is a difference between 'surprising' and 'obvious'. Callsite ref makes it quicker to understand code for a negligible cost, occasionally a lot quicker if you're coming back to code you haven't seen for a while.
 For example, calling one of the *InPlace functions from Phobos, I
 immediately expect 'ref' -- otherwise, how to modify "in place" in a
 reliable (ie, non-allocating) manner?  Likewise, 'out' -- used pretty
 rarely in the first place -- sits in the same place pointers typically
 do, as auxiliary returns.  The category of functions/methods which use
 them is pretty self consistent. (What few corner cases remain would be
 better served by cleaning up tuples to make them more sane as return
 values.)

 Given:

 bool checkedEmitJ (Op, Params, ref const(Scope), Address, out Address)

 I really don't want to have to call it as:

 auto handled = checkedEmitJ(Op.CJmp, parms, ref _scope, suggest, out lval);

 When the 'ref' and 'out' parameters listed are specified by the design
 and consistent across all the "-emit-" functions.
The point is that the signature of checkedEmitJ is not always there when you are reading code that calls checkedEmitJ, so the ref and out parameters are useful in saving the reader time. Making code easier to read is much more important than making it easier to write. When I first saw: swap(ref a, ref b); I thought that looked ugly with the refs, but now I don't mind it. IMO it's only functions whose arguments are all passed by ref that don't really need annotation, and these are infrequent. All others stand to benefit.
Sep 08 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Nick Treleaven:

 IMO it's only functions whose arguments are all passed by ref 
 that don't really need annotation, and these are infrequent. 
 All others stand to benefit.
For arguments that use "const ref", "in ref", "immutable ref" I think ref at the call site is not so important. Bye, bearophile
Sep 08 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, September 08, 2012 17:05:25 Nick Treleaven wrote:
 As an option it would serve no practical purpose other than documentation.
It's worse than that. It's not even documentation that you can trust. If it were optional, and ref were used in a function call, then you know that the argument is being passed by ref (since presumably, you'll get a compilation error if it's not), but if there is no ref, it tells you _nothing_. It could be ref, but it might not be. And if you used ref at the call site frequently, then the lack of ref would end up giving the false impression that the argument wasn't being passed by ref in the case where the ref was forgotten. There's some argument for requiring it (though at this point in its development, I think that it's too late to make it required even if it were determined that that were desirable), but making it optional is _definitely_ a bad idea IMHO. - Jonathan M Davis
Sep 08 2012
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Agh, sent a private mail again. I don't seem to be the only one though.
Has there been a thunderbird UI change?

On 09/08/2012 06:05 PM, Nick Treleaven wrote:
 On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 Given:

 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
Why? UFCS means uniform function call syntax.
 Also for 'const ref' parameters, callsite ref should not be necessary.
The callee might escape a pointer to the argument. Which is 'non-obvious' as well when there is no callsite ref.
 This suggestion has come up a couple times before, and each time failed
 to gain traction.
argument modification should be explicit
It is already explicit. The information is just not repeated at the call site.
 for value types, it is arguably important.
This is not necessarily a valid conclusion. Popularity does not imply importance.
 It might be nice to have for D3.

 I wouldn't mind it as an option -- possibly even as a
 recommendation in most library code -- but as a requirement it honestly
 just gives me a headache.
As an option it would serve no practical purpose other than documentation.
Requiring it makes lack of call site annotations carry some information. The only practical purpose would still be documentation.
 Generally speaking, if a parameter being
 ref/out is surprising, there is something wrong with the design.  (There
 are times it is non-obvious in otherwise good code, this seems uncommon.)
Yes but unfortunately bad design is going to be a reality sometimes.
Bad design never should be a motivation for adding language features. In fact, it seems to be a motivation for creating languages that have few features.
 Also there is a difference between 'surprising' and 'obvious'. Callsite
 ref makes it quicker to understand code for a negligible cost,
 occasionally a lot quicker if you're coming back to code you haven't
 seen for a while.
IMHO it is better left to the future D editor. It can highlight ref/out arguments in a distinct style. Why clutter the language core even more with somewhat complex rules specifying in what cases call site ref is required?
 ...
 The point is that the signature of checkedEmitJ is not always there when
 you are reading code that calls checkedEmitJ, so the ref and out
 parameters are useful in saving the reader time.
I'd still have to look up its declaration to understand exactly what it does.
 Making code easier to read is much more important than making it easier to
write.
I don't know why this quote is repeated all the time. It is not like ease of writing and ease of reading are decoupled or something. What is most important is designing the language such that code that is easy to write is easy to read. What is easy to read is to some extent subjective. eg. I'd prefer to just look at the called function's documentation rather than having every call I later inspect redundantly repeat information present in the function declaration. IMHO it's just noise.
 When I first saw:
 swap(ref a, ref b);

 I thought that looked ugly with the refs, but now I don't mind it. IMO
 it's only functions whose arguments are all passed by ref that don't
 really need annotation,
We are talking about call site annotations. Functions will always require annotation to change the parameter passing style.
 and these are infrequent.
What is this claim based on? The use case above is probably one of the more common ones.
Sep 08 2012
next sibling parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 08/09/2012 19:17, Timon Gehr wrote:
 On 09/08/2012 06:05 PM, Nick Treleaven wrote:
 On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 Given:

 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
Why? UFCS means uniform function call syntax.
I meant if callsite ref was required for parameters, it should not be required for array in 'array.func()'. It would be bizarre to require '(ref array).func()'.
 Also for 'const ref' parameters, callsite ref should not be necessary.
The callee might escape a pointer to the argument. Which is 'non-obvious' as well when there is no callsite ref.
Knowing modification is more important to the local scope than knowing escapes, after all (in theory) the compiler should enforce that only data safe to be escaped is allowed to be escaped, at least in safe mode. In any case, escaping is orthogonal to modification, so shouldn't use 'ref'.
 This suggestion has come up a couple times before, and each time failed
 to gain traction.
argument modification should be explicit
It is already explicit. The information is just not repeated at the call site.
It is not explicit at the call site. That is the crux of the argument for the feature.
 for value types, it is arguably important.
This is not necessarily a valid conclusion. Popularity does not imply importance.
I only said it was *arguably* important, given that the parent post said the idea failed to gain traction. Go and Rust are relatively new and decided for the explicit callsite approach (AFAIU).
 It might be nice to have for D3.
BTW if this was desired (and it seems a long shot ATM) I was thinking there should be an automatic tool to upgrade code from D2 to D3.
 I wouldn't mind it as an option -- possibly even as a
 recommendation in most library code -- but as a requirement it honestly
 just gives me a headache.
As an option it would serve no practical purpose other than documentation.
Requiring it makes lack of call site annotations carry some information. The only practical purpose would still be documentation.
Yes, albeit compiler enforced documentation.
 Generally speaking, if a parameter being
 ref/out is surprising, there is something wrong with the design.  (There
 are times it is non-obvious in otherwise good code, this seems
 uncommon.)
Yes but unfortunately bad design is going to be a reality sometimes.
Bad design never should be a motivation for adding language features. In fact, it seems to be a motivation for creating languages that have few features.
OK, but ref/out parameters aren't always a bad design.
 Also there is a difference between 'surprising' and 'obvious'. Callsite
 ref makes it quicker to understand code for a negligible cost,
 occasionally a lot quicker if you're coming back to code you haven't
 seen for a while.
IMHO it is better left to the future D editor. It can highlight ref/out arguments in a distinct style. Why clutter the language core even more with somewhat complex rules specifying in what cases call site ref is required?
1. Unix tools will never highlight ref/out parameters - e.g. grep. 2. Github probably won't ever. 3. Not everyone will use an editor that does so. Some people prefer a simple editor.
 ...
 The point is that the signature of checkedEmitJ is not always there when
 you are reading code that calls checkedEmitJ, so the ref and out
 parameters are useful in saving the reader time.
I'd still have to look up its declaration to understand exactly what it does.
Sometimes you're not concerned with the precise effect of a function, you just want to work out how it impacts the surrounding code.
 Making code easier to read is much more important than making it
 easier to write.
I don't know why this quote is repeated all the time. It is not like ease of writing and ease of reading are decoupled or something. What is most important is designing the language such that code that is easy to write is easy to read. What is easy to read is to some extent subjective. eg. I'd prefer to just look at the called function's documentation rather than having every call I later inspect redundantly repeat information present in the function declaration. IMHO it's just noise.
It would likely become a motor-skill to ignore the keywords when you're not interested in them.
 When I first saw:
 swap(ref a, ref b);

 I thought that looked ugly with the refs, but now I don't mind it. IMO
 it's only functions whose arguments are all passed by ref that don't
 really need annotation,
We are talking about call site annotations. Functions will always require annotation to change the parameter passing style.
Can't disagree there ;-)
 and these are infrequent.
What is this claim based on? The use case above is probably one of the more common ones.
How often do you use swap?
Sep 09 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/09/2012 02:54 PM, Nick Treleaven wrote:
 On 08/09/2012 19:17, Timon Gehr wrote:
 On 09/08/2012 06:05 PM, Nick Treleaven wrote:
 On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 Given:

 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
Why? UFCS means uniform function call syntax.
I meant if callsite ref was required for parameters, it should not be required for array in 'array.func()'. It would be bizarre to require '(ref array).func()'.
Not more bizarre as in other positions.
...
 This is not necessarily a valid conclusion. Popularity does not imply
 importance.
I only said it was *arguably* important, given that the parent post said the idea failed to gain traction. Go and Rust are relatively new and decided for the explicit callsite approach (AFAIU).
Yes, Go uses explicit pointer types. Regarding Rust, you are wrong. I have built the latest Rust compiler. import io; fn modify(&a:int){ a = 2; } fn swap<T>(&a:T,&b:T){ let tmp<-a; a<-b; b<-tmp; } fn main(){ let mut a= 1; io::println(fmt!("%d",a)); // "1" modify(a); io::println(fmt!("%d",a)); // "2" let mut b=2, c=3; io::println(fmt!("%d %d",b,c)); // "2 3" swap(b,c); io::println(fmt!("%d %d",b,c)); // "3 2" let mut f = fn (a:int)->int{ a + 1 }; let mut g = fn (a:int)->int{ a - 1 }; io::println(fmt!("%d %d",f(2),g(2))); // "3 1" swap(f,g); io::println(fmt!("%d %d",f(2),g(2))); // "1 3" }
 ...
 What is this claim based on? The use case above is probably one of the
 more common ones.
How often do you use swap?
Whenever I want to swap the values of two variables. All other functions in my current project except one that use ref either pass by const/immutable ref, or all arguments are ref, or they are function pointer literals that are part of a polymorphic value type where it is obvious that the first parameter is passed by ref. The remaining function is private and declared right between the methods that use it.
Sep 10 2012
next sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 10/09/2012 21:36, Timon Gehr wrote:
 On 09/09/2012 02:54 PM, Nick Treleaven wrote:
 On 08/09/2012 19:17, Timon Gehr wrote:
 On 09/08/2012 06:05 PM, Nick Treleaven wrote:
 On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 Given:

 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
Why? UFCS means uniform function call syntax.
I meant if callsite ref was required for parameters, it should not be required for array in 'array.func()'. It would be bizarre to require '(ref array).func()'.
Not more bizarre as in other positions.
The brackets make it more ugly though. The reason why it is not necessary is that in general, function arguments are not implicitly modified (and some languages enforce this). But when you see foo.bar() and you don't know what bar does, you don't assume that foo won't be modified, even across many languages.
 This is not necessarily a valid conclusion. Popularity does not imply
 importance.
I only said it was *arguably* important, given that the parent post said the idea failed to gain traction. Go and Rust are relatively new and decided for the explicit callsite approach (AFAIU).
Yes, Go uses explicit pointer types. Regarding Rust, you are wrong.
OK, I misunderstood Rust & I apologize. Thanks for providing the example code.
 What is this claim based on? The use case above is probably one of the
 more common ones.
How often do you use swap?
Whenever I want to swap the values of two variables. All other functions in my current project except one that use ref either pass by const/immutable ref, or all arguments are ref, or they are function pointer literals that are part of a polymorphic value type where it is obvious that the first parameter is passed by ref. The remaining function is private and declared right between the methods that use it.
Then callsite ref might not help you at all. I think Manuel's recent post is better than anything I could write to support the idea.
Sep 11 2012
prev sibling parent reply Ziad Hatahet <hatahet gmail.com> writes:
On Mon, Sep 10, 2012 at 1:36 PM, Timon Gehr <timon.gehr gmx.ch> wrote:

 Yes, Go uses explicit pointer types.
 Regarding Rust, you are wrong.
 I have built the latest Rust compiler.

 import io;

 fn modify(&a:int){
     a = 2;
 }
 fn swap<T>(&a:T,&b:T){
    let tmp<-a;
    a<-b;
    b<-tmp;
 }
The `fn foo(&a: T)` syntax is being deprecated in favor of `fn foo(a: &mut T)`. So your modify function becomes: `fn modify(a: &mut int)`, and gets called as `modify(&mut a)`. Your swap function becomes `fn swap<T>(a: &mut T, b: &mut T)` and gets called as `swap(&mut a, &mut b)`. So effectively, Rust also opted for explicit ref at the call site. -- Ziad
Sep 18 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/18/2012 11:26 PM, Ziad Hatahet wrote:
 On Mon, Sep 10, 2012 at 1:36 PM, Timon Gehr <timon.gehr gmx.ch
 <mailto:timon.gehr gmx.ch>> wrote:


     Yes, Go uses explicit pointer types.
     Regarding Rust, you are wrong.
     I have built the latest Rust compiler.

     import io;

     fn modify(&a:int){
          a = 2;
     }
     fn swap<T>(&a:T,&b:T){
         let tmp<-a;
         a<-b;
         b<-tmp;
     }


 The `fn foo(&a: T)` syntax is being deprecated in favor of `fn foo(a:
 &mut T)`.

 So your modify function becomes: `fn modify(a: &mut int)`, and gets
 called as `modify(&mut a)`.

 Your swap function becomes `fn swap<T>(a: &mut T, b: &mut T)` and gets
 called as `swap(&mut a, &mut b)`.

 So effectively, Rust also opted for explicit ref at the call site.

 --
 Ziad
I see. Thank you for the clarification.
Sep 19 2012
prev sibling next sibling parent reply =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= <sludwig outerproduct.org> writes:
Am 08.09.2012 20:17, schrieb Timon Gehr:
 Agh, sent a private mail again. I don't seem to be the only one though.
 Has there been a thunderbird UI change?
 
They exchanged the order of the "Reply" and "Smart reply" buttons in TB 15. This also hit me several times, very annoying. You can switch them back using "Customize" in the context menu though.
Sep 11 2012
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Tue, 11 Sep 2012 13:36:23 +0200
S=F6nke Ludwig <sludwig outerproduct.org> wrote:

 Am 08.09.2012 20:17, schrieb Timon Gehr:
 Agh, sent a private mail again. I don't seem to be the only one
 though. Has there been a thunderbird UI change?
=20
=20 They exchanged the order of the "Reply" and "Smart reply" buttons in TB 15. This also hit me several times, very annoying. You can switch them back using "Customize" in the context menu though. =20
Mozilla's constantly screwing around with their UIs. You're lucky in this case: Usually you can't revert their UI shenanigans without just simply downgrading or going through the bother of writing a whole plug-in.
Sep 11 2012
prev sibling parent reply "David Piepgrass" <qwertie256 gmail.com> writes:
 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
+1
 Why? UFCS means uniform function call syntax.
It is already understood that the thing left of '.' may be passed by reference: struct Foo { int x = 0; void f() { x++; } } void obvious() { Foo foo; foo.f(); // x is passed to f() by reference } Perhaps your argument makes sense for classes, but not for structs. In any case the syntax (ref foo).f() would require extra work for Walter so I would not propose it. What I might propose instead is that, if the user requests (via command-line argument such as '-callSiteRef') that a warning be issued for arguments passed without 'ref' at the call site, then a situation like this should prompt a warning. class Bar { int b; } void changeBar(ref Bar b) { b = new Bar(); } void warning() { Bar bar = new Bar(); bar.b = 10; bar.changeBar(); // Warning: 'bar' is implicitly passed by reference. To eliminate this warning, use 'changeBar(ref bar)' instead or do not compile with '-callSiteRef' } Again, this problem only applies to classes, since it is understood that structs are normally passed by reference.
 Also for 'const ref' parameters, callsite ref should not be 
 necessary.
The callee might escape a pointer to the argument. Which is 'non-obvious' as well when there is no callsite ref.
If you're referring to the fact that it's easy to have a D pointer to a stack variable outlive the variable... I don't think that this 'flaw' (I think of it as a flaw, others may think of it as a feature) is a good enough reason to say 'call site ref should be required for const ref parameters'.
 for value types, it is arguably important.
This is not necessarily a valid conclusion. Popularity does not imply importance.
and liked it. I didn't start putting 'IN OUT' and 'OUT' in my C++ site.
 Generally speaking, if a parameter being
 ref/out is surprising, there is something wrong with the 
 design.  (There
 are times it is non-obvious in otherwise good code, this 
 seems uncommon.)
I often want to 'scan' code to see what it does. Especially for debugging, I want to see where the side-effects are QUICKLY. Guessing which parameters are 'ref' requires me to analyze the code in my head. Even if I myself wrote the code, it can be time consuming. That's why I would prefer to explicitly mark possible side effects with 'ref' (of course, when passing a class to a function, the class members may be modified when the reference to the class was passed by value. But it is far easier to keep track of which classes are mutable than to keep track of which parameters of which functions are 'ref', because functions far outnumber classes.)
 IMHO it is better left to the future D editor.
That's probably a long way off.
Sep 11 2012
next sibling parent "Manuel" <manuel d.org> writes:
On Tuesday, 11 September 2012 at 17:57:17 UTC, David Piepgrass 
wrote:
 void func (ref int[], int)

 If ref/out were required at the call site, this destroys 
 UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
+1
 Why? UFCS means uniform function call syntax.
It is already understood that the thing left of '.' may be passed by reference: struct Foo { int x = 0; void f() { x++; } } void obvious() { Foo foo; foo.f(); // x is passed to f() by reference } Perhaps your argument makes sense for classes, but not for structs. In any case the syntax (ref foo).f() would require extra work for Walter so I would not propose it. What I might propose instead is that, if the user requests (via command-line argument such as '-callSiteRef') that a warning be issued for arguments passed without 'ref' at the call site, then a situation like this should prompt a warning. class Bar { int b; } void changeBar(ref Bar b) { b = new Bar(); } void warning() { Bar bar = new Bar(); bar.b = 10; bar.changeBar(); // Warning: 'bar' is implicitly passed by reference. To eliminate this warning, use 'changeBar(ref bar)' instead or do not compile with '-callSiteRef' } Again, this problem only applies to classes, since it is understood that structs are normally passed by reference.
 Also for 'const ref' parameters, callsite ref should not be 
 necessary.
The callee might escape a pointer to the argument. Which is 'non-obvious' as well when there is no callsite ref.
If you're referring to the fact that it's easy to have a D pointer to a stack variable outlive the variable... I don't think that this 'flaw' (I think of it as a flaw, others may think of it as a feature) is a good enough reason to say 'call site ref should be required for const ref parameters'.
 for value types, it is arguably important.
This is not necessarily a valid conclusion. Popularity does not imply importance.
I think 'ref' is a popular idea because people have used it in the call site.
it at first annoying but now i wished i would have it in C++ too. One possibility to simulate this in C++ is like the pbrt people have done it with const references and pointers (look at my post above for further details).
 Generally speaking, if a parameter being
 ref/out is surprising, there is something wrong with the 
 design.  (There
 are times it is non-obvious in otherwise good code, this 
 seems uncommon.)
I often want to 'scan' code to see what it does. Especially for debugging, I want to see where the side-effects are QUICKLY. Guessing which parameters are 'ref' requires me to analyze the code in my head. Even if I myself wrote the code, it can be time consuming. That's why I would prefer to explicitly mark possible side effects with 'ref' (of course, when passing a class to a function, the class members may be modified when the reference to the class was passed by value. But it is far easier to keep track of which classes are mutable than to keep track of which parameters of which functions are 'ref', because functions far outnumber classes.)
+1 It's not only that you yourself want to 'scan' through your code and QUICKLY see where parameters in function calls are modified but others might have to read your code aswell for code reviewing without browsing in the hopefully existing documentation for every single function / method. People in companies normally are not programming in isolation but are working in a team and teams often change.
 IMHO it is better left to the future D editor.
That's probably a long way off.
Yes. Looking at the current overall state of the d toolchain that might be a very long way off. And even then, inmho, it would be a not so good solution because it would be a feature which would tie users who want this feature to a specific editor / ide.
Sep 11 2012
prev sibling parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 11/09/2012 18:57, David Piepgrass wrote:
 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
For UFCS, ref should be implied.
+1
 Why? UFCS means uniform function call syntax.
It is already understood that the thing left of '.' may be passed by reference: struct Foo { int x = 0; void f() { x++; } } void obvious() { Foo foo; foo.f(); // x is passed to f() by reference } Perhaps your argument makes sense for classes, but not for structs. In any case the syntax (ref foo).f() would require extra work for Walter so I would not propose it. What I might propose instead is that, if the user requests (via command-line argument such as '-callSiteRef') that a warning be issued for arguments passed without 'ref' at the call site, then a situation like this should prompt a warning. class Bar { int b; } void changeBar(ref Bar b) { b = new Bar(); } void warning() { Bar bar = new Bar(); bar.b = 10; bar.changeBar(); // Warning: 'bar' is implicitly passed by reference. To eliminate this warning, use 'changeBar(ref bar)' instead or do not compile with '-callSiteRef' } Again, this problem only applies to classes, since it is understood that structs are normally passed by reference.
I had only thought about UFCS and ref parameters for value types. You are right that requiring callsite ref for class ref parameters would be a useful idea, as modifying the ref itself is unusual behavior. And because of that, disallowing UFCS for functions that have a class ref parameter as the first parameter might be an elegant solution.
Sep 12 2012
parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 12/09/2012 13:39, Nick Treleaven wrote:
 class Bar { int b; }
 void changeBar(ref Bar b) { b = new Bar(); }
 void warning()
 {
      Bar bar = new Bar();
      bar.b = 10;
      bar.changeBar(); // Warning: 'bar' is implicitly passed by
 reference. To eliminate this warning, use 'changeBar(ref bar)' instead
 or do not compile with '-callSiteRef'
 }

 Again, this problem only applies to classes, since it is understood that
 structs are normally passed by reference.
I had only thought about UFCS and ref parameters for value types. You are right that requiring callsite ref for class ref parameters would be a useful idea, as modifying the ref itself is unusual behavior. And because of that, disallowing UFCS for functions that have a class ref parameter as the first parameter might be an elegant solution.
Also the same applies to ref parameters with any reference types: On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
 void func (ref int[], int)

 If ref/out were required at the call site, this destroys UFCS.

 int[] array;
 array.func(0); // error, ref not specified by caller
So the above poster was right, I completely missed this :-/ (But disallowing UFCS here still might be a good solution).
Sep 12 2012
next sibling parent reply "Minas" <minas_mina1990 hotmail.co.uk> writes:
I disagree that it would be useful.

D.

Consider this:

void f(ref int x)
{
...
}

...
int x = 5;
f(ref x); // good, passed by reference
...


But:
void g(int* p)
{
...
}

...
int x = 5;
g(&x); // passed by reference as well, but it is not explicit 
like before. You don't even know if it's a const pointer if you 
don't read the function's signature.
...

So someone has this cool idea which is also present in some other 
programming language and thinks it would be nice to add it to D. 
That's not how it works. Then come the problem with things not 
properly designed etc etc.

Anyway, who needs to see f(ref x) when you can put your mouse 
above the function call and see its declaration? All modern IDEs 

Sep 12 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Minas:

 g(&x); // passed by reference as well, but it is not explicit 
 like before. You don't even know if it's a const pointer if you 
 don't read the function's signature.
The presence of "&" at call site acts exactly like the "ref" at the call site. In both cases you don't know if it's const/immutable. Bye, bearophile
Sep 12 2012
prev sibling parent "F i L" <witte2008 gmail.com> writes:
Minas wrote:
 Anyway, who needs to see f(ref x) when you can put your mouse 
 above the function call and see its declaration? All modern 

 editors.
People debugging large bodies of code should not be required to hover the mouse over each and every function parameter for a second to properly understand structure. People using non-tooltip text editors have an even harder time. I think you're missing the point. This code: int* x; foo(&x); at least tells you there's a _potential_ x is being manipulated rather than just used. We don't need full insight into what's going on, just a helpful hint which narrows the potential culprits when debugging. If fact, it would nice if even reference types where required to follow similar "is modified in function" semantics, and I have ideas about that, but I'm not going there right now...
Sep 12 2012
prev sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 12/09/2012 13:55, Nick Treleaven wrote:
 On 12/09/2012 13:39, Nick Treleaven wrote:
 class Bar { int b; }
 void changeBar(ref Bar b) { b = new Bar(); }
 void warning()
 {
      Bar bar = new Bar();
      bar.b = 10;
      bar.changeBar(); // Warning: 'bar' is implicitly passed by
 reference. To eliminate this warning, use 'changeBar(ref bar)' instead
 or do not compile with '-callSiteRef'
 }

 Again, this problem only applies to classes, since it is understood that
 structs are normally passed by reference.
I had only thought about UFCS and ref parameters for value types. You are right that requiring callsite ref for class ref parameters would be a useful idea, as modifying the ref itself is unusual behavior. And because of that, disallowing UFCS for functions that have a class ref parameter as the first parameter might be an elegant solution.
Also the same applies to ref parameters with any reference types: On 08/09/2012 14:05, Chris Nicholson-Sauls wrote: > void func (ref int[], int) > > If ref/out were required at the call site, this destroys UFCS. > > int[] array; > array.func(0); // error, ref not specified by caller So the above poster was right
Ignore that last reply, slices are value types. The syntax array.func() looks like it might modify array's contents and/or length, so UFCS is OK. It is only ref class and ref pointer arguments that UFCS should be disallowed on to enforce call-site ref.
Sep 14 2012
prev sibling next sibling parent reply "F i L" <witte2008 gmail.com> writes:
On Friday, 7 September 2012 at 11:33:41 UTC, Kevin McTaggart 
wrote:
 I've been looking at migrating a reasonably large ship motion 

 quite enthusiastic about D, and most of my problems have been 
 relatively minor (e.g., inconsistent bugs with 
 std.container.Array, would like orange serialization to give me 
 an error telling me I didn't register a class before calling 
 serialize).  I suggest that the language require ref and out 

 easier to understand, and would also eliminate the problem I 
 had when the wrong function from the following choices was 
 mistakenly called:

 parseLineInts(string text, int positionStart, out int j0, out 
 int j1)

 parseLineInts(string text, out int j0, out int j1, out int j2)

 I note that the second function calls another function as 
 follows:
 int positionStart = 1;
 parseLineInts(text, positionStart, j0, j1, j2);

 I look forward to seeing feedback from D experts.  This is the 
 only significant change that I could think of recommending for 
 the language.
+1. The fact that a value type is modified should be information the programmer can see at a glance. Andrei Alexandrescu wrote:

 in 5.0 (it used to be required up until 4.0). Apparently users 
 complained it was too unsightly.
right now and ref/out are still required at the call sight of functions.
Sep 08 2012
parent reply "Manuel" <manuel test.es> writes:
On Saturday, 8 September 2012 at 17:20:21 UTC, F i L wrote:
 On Friday, 7 September 2012 at 11:33:41 UTC, Kevin McTaggart 
 wrote:
 I've been looking at migrating a reasonably large ship motion 

 become quite enthusiastic about D, and most of my problems 
 have been relatively minor (e.g., inconsistent bugs with 
 std.container.Array, would like orange serialization to give 
 me an error telling me I didn't register a class before 
 calling serialize).  I suggest that the language require ref 

 make code easier to understand, and would also eliminate the 
 problem I had when the wrong function from the following 
 choices was mistakenly called:

 parseLineInts(string text, int positionStart, out int j0, out 
 int j1)

 parseLineInts(string text, out int j0, out int j1, out int j2)

 I note that the second function calls another function as 
 follows:
 int positionStart = 1;
 parseLineInts(text, positionStart, j0, j1, j2);

 I look forward to seeing feedback from D experts.  This is the 
 only significant change that I could think of recommending for 
 the language.
+1. The fact that a value type is modified should be information the programmer can see at a glance.
from D too. It's not only that the information that a value type is modified should be visible to the programmer at a glance who had originally written the code but also to other team members who just want to do a quick read over code someone else has written or to the people who do code review. From my personal experience within commercial software development code is much more often read than written. And most of the time it will be read by a larger amount of people one can initially think of. But i have to admit, that it might be too late for changes in D2 regarding this just because it would break too much existing code (and at the moment code still breaks too often).
 Andrei Alexandrescu wrote:

 in 5.0 (it used to be required up until 4.0). Apparently users 
 complained it was too unsightly.
I have never heard anyone complaining about this syntax nor have i read of anyone complaining about this online in newsgroups or such. From my colleagues and my circle of acquaintances only former C++ programmers were initially complaining but they were soon adopting this syntax and at the end they had to admit that these additional syntax annotations at the call site make sense. I think ref/out is like the now "forced" "override" keyword for overridden methods - it just helps to avoid mistakes and makes things a little bit safer.

 8 right now and ref/out are still required at the call sight of 
 functions.
I have Visual Studio 2012 RC and can confirm, that ref and out compiler switch to disable this ??)
Sep 10 2012
next sibling parent reply "zerg" <Sergey.Chelombitko gmail.com> writes:
 But i have to admit, that it might be too late for changes in D2
regarding this just because it would break too much existing code Such feature can be implemented as optional in D2 with compiler switch to enforce explicit ref and out syntax.
Sep 10 2012
parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <alex lycus.org> writes:
On 11-09-2012 06:21, zerg wrote:
 But i have to admit, that it might be too late for changes in D2
regarding this just because it would break too much existing code Such feature can be implemented as optional in D2 with compiler switch to enforce explicit ref and out syntax.
It's already highly problematic that we have -property (and that it isn't the default). D code shouldn't stop being valid just because of a missing compiler switch (or the presence of one). -- Alex Rønne Petersen alex lycus.org http://lycus.org
Sep 10 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/11/12 1:28 AM, Manuel wrote:

 now and ref/out are still required at the call sight of functions.
I have Visual Studio 2012 RC and can confirm, that ref and out compiler switch to disable this ??)
Erik Meijer didn't get back to me yet about that with a link, but he did mention that the relaxation was only allowed for COM calls. Andrei
Sep 11 2012
parent reply "Manuel" <manuel d.org> writes:
On Tuesday, 11 September 2012 at 08:10:21 UTC, Andrei 
Alexandrescu wrote:
 On 9/11/12 1:28 AM, Manuel wrote:

 Windows 8 right
 now and ref/out are still required at the call sight of 
 functions.
I have Visual Studio 2012 RC and can confirm, that ref and out compiler switch to disable this ??)
Erik Meijer didn't get back to me yet about that with a link, but he did mention that the relaxation was only allowed for COM calls. Andrei
OK, i see. For COM calls that might make sense, since binary COM modules are mostly written in C/C++ and must also not depend on any feature of any programming language so that the calling specific annotations are of no use since you don't get any additional safety and you just have to write more code which at the end gains you nothing. In general, i can understand the objections against adding these syntax annotations at the call site. When i started programming additional annotations rendundant and annoying and a complete waste of time. But when you are developing in a team where you often have to read the code written by other team members and they have to read your code, then you really begin to see the merits. But it is also a good reminder for yourself when you have to look or modify code you have written a long time ago. A colleague of mine also mentioned, that you can see "a simulation" of the ref/out annotations using pointers / references as an idiom nowadays in a lot of C++ code too. If a function argument will be modified in some way you use a pointer and const references when it won't: e.g. if you have a function / method: void transmogrify(const MogrifyType& a, const MogrifyType& b, MogrifyType* out) you would call it: transmogrify(a, b, &c); Using this convention throughout the code you can see at the call site that a and b are input parameters and c will be modified. For example the render system "pbrt" ( http://pbrt.org/ ) uses this as an convention in their C++ code and it is explicitly mentioned in chapter 1.5.1 "pointer or reference" in the introduction.
Sep 11 2012
parent reply "Paulo Pinto" <pjmlp progtools.org> writes:
On Tuesday, 11 September 2012 at 16:49:45 UTC, Manuel wrote:
 On Tuesday, 11 September 2012 at 08:10:21 UTC, Andrei 
 Alexandrescu wrote:
 On 9/11/12 1:28 AM, Manuel wrote:

 Windows 8 right
 now and ref/out are still required at the call sight of 
 functions.
I have Visual Studio 2012 RC and can confirm, that ref and out compiler switch to disable this ??)
Erik Meijer didn't get back to me yet about that with a link, but he did mention that the relaxation was only allowed for COM calls. Andrei
OK, i see. For COM calls that might make sense, since binary COM modules are mostly written in C/C++ and must also not depend on any feature of any programming language so that the calling should be easily possible from any language. There any additional safety and you just have to write more code which at the end gains you nothing. In general, i can understand the objections against adding these syntax annotations at the call site. When i started writing these additional annotations rendundant and annoying and a complete waste of time.
Having used Turbo Pascal before I was doing C, I never understood why so many developers cry for this at the call site. I never had any problem with "var" parameters on Turbo Pascal (or other languages from Wirth), nor with references in C++. As I am not language religious, I just use them the way the language provides them. -- Paulo
Sep 12 2012
parent reply "Manuel" <manuel d.org> writes:
On Wednesday, 12 September 2012 at 07:36:24 UTC, Paulo Pinto 
wrote:
 On Tuesday, 11 September 2012 at 16:49:45 UTC, Manuel wrote:
 On Tuesday, 11 September 2012 at 08:10:21 UTC, Andrei 
 Alexandrescu wrote:
 On 9/11/12 1:28 AM, Manuel wrote:

 Windows 8 right
 now and ref/out are still required at the call sight of 
 functions.
I have Visual Studio 2012 RC and can confirm, that ref and out compiler switch to disable this ??)
Erik Meijer didn't get back to me yet about that with a link, but he did mention that the relaxation was only allowed for COM calls. Andrei
OK, i see. For COM calls that might make sense, since binary COM modules are mostly written in C/C++ and must also not depend on any feature of any programming language so that the calling should be easily possible from any language. There get any additional safety and you just have to write more code which at the end gains you nothing. In general, i can understand the objections against adding these syntax annotations at the call site. When i started writing these additional annotations rendundant and annoying and a complete waste of time.
Having used Turbo Pascal before I was doing C, I never understood why so many developers cry for this at the call site. I never had any problem with "var" parameters on Turbo Pascal (or other languages from Wirth), nor with references in C++. As I am not language religious, I just use them the way the language provides them. -- Paulo
You just have cut away the last part of the history of my life and completely changed my statement to the reverse ;-) That last part was were i was getting my enlightenment and started to embrace additional annotations at the call site. From there i never looked back and lived a happier and more glorious life with a lot of profit and lot less errors ;-) Kevin just put this up for discussion because he realized while overloaded functions because of missing call site parameter annotations and just asked about the general opinion in the D community to add these to the language. I and a lot of the other participants in this thread just asserted that it would be a nice addition to D. That does not mean, we were "crying" for these or that we are "language religious" or that without them we would have unsolvable problems and would forever quit programming in D and switch over to QuickBasic again. It was more just a survey about the general opinion in the community. And as an intermediate result (which is not even close to be representive), the majority of the participants of this thread would like to have these added to the language, some just don't care and some don't like the idea at all. From those who didn't like the idea the most heared counter-argument was more like: "I know my code, i have written it, so i know which method modifies which parameters. I don't need this it makes me do more work." Which in my opinion is a bit shortsighted since in commercial development or in general when you work in a team you don't program in isolation and you have to often use third-party-frameworks were you don't have written every method by yourself. That's why the Microsoft language designer added realised with references and pointers. The only valid counter-arguments brought up so far, were possible breakage of code (when it would be enforced) and maybe UCFS.
 As I am not language religious, I just use them the way the
 language provides them.
The good thing here in the open source world is that we are not bound to the decision of a big committee. It's not "you'll eat what's put in front of you". If a bigger part of the D community would like to have these annotations added to the language, at least as an optional feature, then that might persuade our "benevolent dictators" (just joking - you are great!) Walther and Andrei to add them or we could just make a fork of the language and add them ourselves (more joking - no, just skip this last part - it's late) :-) There might be other problems, maybe with the compiler internals or breakage of parts of the language. These were severe. But i think only Walther and Andrei might tell. If these wouldn't exist it would at least be possible, how David proposed it in his post, to make them optional. At the end that won't stop me or any other poster from programming in D. It would just really be nice to see this little extra of parameter checking at least optionally in D since with all the other safeness-features like safeD, contracts, etc. it would be a good addition to the language.
Sep 12 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/13/12 1:02 AM, Manuel wrote:
 If a bigger part of the D community would like to have these annotations
 added to the language, at least as an optional feature, then that might
 persuade our "benevolent dictators" (just joking - you are great!)
 Walther and Andrei to add them or we could just make a fork of the
 language and add them ourselves (more joking - no, just skip this last
 part - it's late) :-)

 There might be other problems, maybe with the compiler internals or
 breakage of parts of the language. These were severe. But i think only
 Walther and Andrei might tell. If these wouldn't exist it would at least
 be possible, how David proposed it in his post, to make them optional.
I don't think there would be problems with allowing ref/out optionally at the call site. The thing is, however, that in this matter reasonable people may disagree. In C++, the equivalent argument (should we pass everything modifiable by pointer or not?) erupts every six months on internal fora at Facebook. No winning argument is made by either part. For example, it is often brought up that it's good to see "&" at the call site when debugging some urgent matter at 3am. Yet there are other people who are just as apt at debugging urgent matters at 3am, and the absence of "&" doesn't seem to be a handicap for them at all. I'd be unable to identify any pattern in engineers choosing one preference over the other. As a consequence, our code has a mix of pass-by-pointer and pass-by-reference-to-nonconst, all engineers manage either style just as well, and we've never been able to find any evidence pointing one way or another. Now that the subject has been broken, we do have good evidence of a pattern that generates significant and difficult bugs: escaping the address of a reference. In C++: struct A { A(int& host) : host_(host) {} private: int& host_; }; In D: class A { // or struct A(ref int host) : _host(&host) {} private: int* _host; } A solution we use for C++ is to require escaped addresses to be always passed as pointers or smart pointers. Walter and I have discussed this for quite a while. We have recently decided to disallow, at least in SafeD, escaping the address of a ref parameter. In the beginning we'll be overly conservative by disallowing taking the address of a ref altogether. I'll write a DIP on that soon. Andrei
Sep 13 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
In D:

class A { // or struct
     A(ref int host) : _host(&host) { }
private:
     int* _host;
}

Since when do we have initialization lists in D? ;)

at topic: +1
Sep 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/13/12 6:58 AM, Namespace wrote:
 In D:

 class A { // or struct
 A(ref int host) : _host(&host) { }
 private:
 int* _host;
 }

 Since when do we have initialization lists in D? ;)
Oops, sorry :o).
 at topic: +1
One question Walter and I thought about a lot was whether we should disallow escaping addresses of ref parameters in general or only in safe code. We decided to go for the latter in order to avoid breakage of existing code. Thoughts? Andrei
Sep 13 2012
parent reply Sean Kelly <sean invisibleduck.org> writes:
On Sep 13, 2012, at 7:21 AM, Andrei Alexandrescu =
<SeeWebsiteForEmail erdani.org> wrote:
=20
 One question Walter and I thought about a lot was whether we should =
disallow escaping addresses of ref parameters in general or only in = safe code. We decided to go for the latter in order to avoid breakage = of existing code. Thoughts? I love the idea. However, this could complicate working with C APIs, = particularly regarding structs which are often passed by reference as a = matter of course. For example: struct some_c_struct {} void fn(ref some_c_struct s) { some_c_func(&s); } I guess the only way to know if this will turn out to be a real issue is = to give it a try though.=
Sep 13 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-09-13 18:28, Sean Kelly wrote:

 I love the idea.  However, this could complicate working with C APIs,
particularly regarding structs which are often passed by reference as a matter
of course.  For example:

 struct some_c_struct {}

 void fn(ref some_c_struct s) {
      some_c_func(&s);
 }

 I guess the only way to know if this will turn out to be a real issue is to
give it a try though.
This applies to static arrays as well: extern (C) void foo (ref int[3] a); Since in D static arrays have value semantics. -- /Jacob Carlborg
Sep 13 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Thursday, 13 September 2012 at 10:34:00 UTC, Andrei 
Alexandrescu wrote:
 The thing is, however, that in this matter reasonable people 
 may disagree.
Sep 13 2012
prev sibling next sibling parent reply "David Piepgrass" <qwertie256 gmail.com> writes:
 I don't think there would be problems with allowing ref/out 
 optionally at the call site. The thing is, however, that in 
 this matter reasonable people may disagree.
 I'd be unable to identify any pattern in engineers choosing one 
 preference over the other.
call-site ref?
 Now that the subject has been broken, we do have good evidence 
 of a pattern that generates significant and difficult bugs: 
 escaping the address of a reference. In C++:

 struct A {
     A(int& host) : host_(host) {}
 private:
     int& host_;
 };

 In D:

 class A { // or struct
     A(ref int host) : _host(&host) {}
 private:
     int* _host;
 }

 A solution we use for C++ is to require escaped addresses to be 
 always passed as pointers or smart pointers.

 Walter and I have discussed this for quite a while. We have 
 recently decided to disallow, at least in SafeD, escaping the 
 address of a ref parameter. In the beginning we'll be overly 
 conservative by disallowing taking the address of a ref 
 altogether. I'll write a DIP on that soon.
Err, wouldn't that break a lot of stuff, a lot of which is actually safe code? void a(ref int x) { b(&x); } void b(int* x) { if(x != null) (*x)++; } Escaping the addresses of stack variables, not just ref parameters, is a general problem in "safe" D. Do you have any ideas about that?
Sep 13 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/13/12 10:53 AM, David Piepgrass wrote:
 Walter and I have discussed this for quite a while. We have recently
 decided to disallow, at least in SafeD, escaping the address of a ref
 parameter. In the beginning we'll be overly conservative by
 disallowing taking the address of a ref altogether. I'll write a DIP
 on that soon.
Err, wouldn't that break a lot of stuff, a lot of which is actually safe code? void a(ref int x) { b(&x); } void b(int* x) { if(x != null) (*x)++; }
Yes. Disallowing taking the address of a local is conservative and would disallow a number of valid programs. Arguably, such programs are in poor style anyway. A good program takes pointers only if it needs to keep them around; if all that's needed is to use the parameter transitorily or pass it down, ref is best.
 Escaping the addresses of stack variables, not just ref parameters, is a
 general problem in "safe" D. Do you have any ideas about that?
Same thing. By and large safe programs will need to make more use of the garbage collector than others. It's the way things work; stack allocation can be made safer if we add typed regions, but that's a very significant escalation of complication. There is no simple solution to this today. Andrei
Sep 13 2012
parent reply "David Piepgrass" <qwertie256 gmail.com> writes:
On Thursday, 13 September 2012 at 15:01:28 UTC, Andrei 
Alexandrescu wrote:
 On 9/13/12 10:53 AM, David Piepgrass wrote:
 Walter and I have discussed this for quite a while. We have 
 recently
 decided to disallow, at least in SafeD, escaping the address 
 of a ref
 parameter. In the beginning we'll be overly conservative by
 disallowing taking the address of a ref altogether. I'll 
 write a DIP
 on that soon.
Err, wouldn't that break a lot of stuff, a lot of which is actually safe code? void a(ref int x) { b(&x); } void b(int* x) { if(x != null) (*x)++; }
Yes. Disallowing taking the address of a local is conservative and would disallow a number of valid programs. Arguably, such programs are in poor style anyway. A good program takes pointers only if it needs to keep them around; if all that's needed is to use the parameter transitorily or pass it down, ref is best.
Another common reason to use a pointer (instead of ref) is if it's optional (nullable). If the parameter is ref then the caller must go to the trouble of creating a variable. However, this could be solved with a feature like the following: int* find(string searchString, out int index) { ... } // _ means "don't care", assuming no variable "_" is defined void caller() { find("foo", out _); } In fact this is arguably better for 'out' variables since the callee (find) no longer has to check whether 'index' is null before assigning it. However this doesn't totally solve the problem for 'ref' parameters, since such parameters are both output and input parameters and the programmer may want 'null' to have some special meaning as an input.
 Escaping the addresses of stack variables, not just ref 
 parameters, is a
 general problem in "safe" D. Do you have any ideas about that?
Btw just a simple illustrative example: int* unsafe1() { int x = 1; return unsafe2(&x); } int* unsafe2(int* x) { return x; } int unsafe3() { int y = 7; *unsafe1() = 8; return y; } enum gaff = unsafe3(); // ICE, no line number given
 Same thing. By and large safe programs will need to make more 
 use of the garbage collector than others. It's the way things 
 work; stack allocation can be made safer if we add typed 
 regions, but that's a very significant escalation of 
 complication. There is no simple solution to this today.
Same thing meaning that you'd propose disallowing taking the address of a stack variable in SafeD? (I guess this would include escaping 'this' within a struct.)
Sep 13 2012
parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 13/09/2012 16:29, David Piepgrass wrote:
 On Thursday, 13 September 2012 at 15:01:28 UTC, Andrei Alexandrescu wrote:
 On 9/13/12 10:53 AM, David Piepgrass wrote:
 Walter and I have discussed this for quite a while. We have recently
 decided to disallow, at least in SafeD, escaping the address of a ref
 parameter. In the beginning we'll be overly conservative by
 disallowing taking the address of a ref altogether. I'll write a DIP
 on that soon.
Err, wouldn't that break a lot of stuff, a lot of which is actually safe code? void a(ref int x) { b(&x); } void b(int* x) { if(x != null) (*x)++; }
Yes. Disallowing taking the address of a local is conservative and would disallow a number of valid programs.
What about: void b(scope int* x) { if(x != null) (*x)++; } Then 'a' could compile safely.
 Arguably, such programs are in poor style anyway. A good program takes
 pointers only if it needs to keep them around; if all that's needed is
 to use the parameter transitorily or pass it down, ref is best.
Another common reason to use a pointer (instead of ref) is if it's optional (nullable). If the parameter is ref then the caller must go to the trouble of creating a variable.
Maybe std.typecons.Nullable or something like it helps there.
Sep 14 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, September 13, 2012 12:34:34 Andrei Alexandrescu wrote:
 I don't think there would be problems with allowing ref/out optionally
 at the call site. The thing is, however, that in this matter reasonable
 people may disagree.
I really think that optionally allowing ref and out at the call site is more damaging than beneficial. _Requiring_ it could be beneficial, since then you know that the arguments are being taken by ref, but if it's optional, it gives you a false sense of security and can be misleading. Presumabyl, any time that ref or out is used at a call site, presumably the compiler would check that it really was passed by ref our out, which would be of some benefit, but it would mean _nothing_ if ref or out wasn't used, since it could be an argument being passed by ref but which wasn't marked or an argument which wasn't passed by ref at all. So, if you have code where ref and out is used at the call site semi-religiously, then it'll become very easy to falsely think that the lack of them means that ref or out _isn't_ being used when it really is, misleading people about what the code is doing. So, if it wasn't going to break so much code, I'd see some argument for changing things so that ref and out were required at the call site, but I think that _allowing_ them but not requiring them would actually be detrimental. - Jonathan M Davis
Sep 13 2012
next sibling parent reply "David Piepgrass" <qwertie256 gmail.com> writes:
 I really think that optionally allowing ref and out at the call 
 site is more
 damaging than beneficial. _Requiring_ it could be beneficial, 
 since then you
 know that the arguments are being taken by ref, but if it's 
 optional, it gives
 you a false sense of security and can be misleading.
It gives *who* a false sense of security? If it's optional then I *know* lack of ref/out doesn't imply that the parameter won't change. Only people who don't know the rules would have this false sense of security. I think it would be nice to have it required, but it's very bad to break everyone's code. It could only be reasonably enforced with a compiler switch--or, wait, come to think of it, a pragma would probably be better way to introduce language changes like this: module foo; pragma(callSiteRef); // and would it make sense to offer an alternative to -property too? pragma(property); Now you can tell whether a program uses ref/out religiously or not.
Sep 13 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/13/12 11:47 AM, David Piepgrass wrote:
 I really think that optionally allowing ref and out at the call site
 is more
 damaging than beneficial. _Requiring_ it could be beneficial, since
 then you
 know that the arguments are being taken by ref, but if it's optional,
 it gives
 you a false sense of security and can be misleading.
It gives *who* a false sense of security?
It's "whom". Andrei P.S. All of my life I've been waiting for this moment!!!
Sep 13 2012
parent "Mehrdad" <wfunction hotmail.com> writes:
On Thursday, 13 September 2012 at 16:29:19 UTC, Andrei 
Alexandrescu wrote:
 It gives *who* a false sense of security?
It's "whom". Andrei P.S. All of my life I've been waiting for this moment!!!
LOL
Sep 13 2012
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, September 13, 2012 17:47:45 David Piepgrass wrote:
 It gives *who* a false sense of security? If it's optional then I
 *know* lack of ref/out doesn't imply that the parameter won't
 change. Only people who don't know the rules would have this
 false sense of security.
More like anyone reading the code but especially when someone _other_ than you is reading your code. I'd fully expect that there would be quite a few programmers who would assume that the lack of ref at the call site would mean that it's not passed by ref when the code uses ref and out at the call site all over the place. And because the lack of ref or out at the call site means nothing, you're always going to have to either know whether the function takes its arguments by ref or not, or you're going to have to look up the function anyway. And if that's the case, actually using ref or out at the call site buys you almost nothing. - Jonathan M Davis
Sep 13 2012
parent reply "ixid" <nuaccount gmail.com> writes:
Couldn't this easily be supported by an IDE by coloured function 
arguments based on their type? Then the information is clearly 
visible without cluttering the code.
Sep 13 2012
parent reply "F i L" <witte2008 gmail.com> writes:
On Thursday, 13 September 2012 at 22:21:34 UTC, ixid wrote:
 Couldn't this easily be supported by an IDE by coloured 
 function arguments based on their type? Then the information is 
 clearly visible without cluttering the code.
no because... wait... that... that could work.
Sep 13 2012
parent reply "Manuel" <manuel d.org> writes:
On Friday, 14 September 2012 at 06:55:00 UTC, F i L wrote:
 On Thursday, 13 September 2012 at 22:21:34 UTC, ixid wrote:
 Couldn't this easily be supported by an IDE by coloured 
 function arguments based on their type? Then the information 
 is clearly visible without cluttering the code.
no because... wait... that... that could work.
Ok. Then ... who is writing this IDE ?
Sep 14 2012
next sibling parent "F i L" <witte2008 gmail.com> writes:
On Friday, 14 September 2012 at 22:20:16 UTC, Manuel wrote:
 On Friday, 14 September 2012 at 06:55:00 UTC, F i L wrote:
 On Thursday, 13 September 2012 at 22:21:34 UTC, ixid wrote:
 Couldn't this easily be supported by an IDE by coloured 
 function arguments based on their type? Then the information 
 is clearly visible without cluttering the code.
no because... wait... that... that could work.
Ok. Then ... who is writing this IDE ?
I'm just saying it's a solution that doesn't require adding a breaking feature to D. I know MonoDevelop has the ability to color user-types and such, maybe eventually Alex will be able to add such a feature. If the compiler developers can't or won't add 'foo(ref x)' semantics to the compiler, then this is really the only option left available that gives the same level of insight to developers
Sep 14 2012
prev sibling parent "ixid" <nuaccount gmail.com> writes:
It'd be great if the guy doing Visual D could give it a try. We 
could also resolve the property vs function issue in a similar 
manner to avoid the need to enforce unnecessary brackets 
everywhere. It would seem like a more practical approach than 
breaking all D2 code that actually addresses the legitimate issue.
Sep 14 2012
prev sibling parent "Manuel" <manuel d.org> writes:
On Thursday, 13 September 2012 at 15:18:06 UTC, Jonathan M Davis 
wrote:
 On Thursday, September 13, 2012 12:34:34 Andrei Alexandrescu 
 wrote:
 I don't think there would be problems with allowing ref/out 
 optionally
 at the call site. The thing is, however, that in this matter 
 reasonable
 people may disagree.
I really think that optionally allowing ref and out at the call site is more damaging than beneficial. _Requiring_ it could be beneficial, since then you know that the arguments are being taken by ref, but if it's optional, it gives you a false sense of security and can be misleading. Presumabyl, any time that ref or out is used at a call site, presumably the compiler would check that it really was passed by ref our out, which would be of some benefit, but it would mean _nothing_ if ref or out wasn't used, since it could be an argument being passed by ref but which wasn't marked or an argument which wasn't passed by ref at all. So, if you have code where ref and out is used at the call site semi-religiously, then it'll become very easy to falsely think that the lack of them means that ref or out _isn't_ being used when it really is, misleading people about what the code is doing. So, if it wasn't going to break so much code, I'd see some argument for changing things so that ref and out were required at the call site, but I think that _allowing_ them but not requiring them would actually be detrimental. - Jonathan M Davis
I see your point here but, as David already argued in his post, it would only be detrimental if people would not realise that these annotations are not obligatory. If that is clearly stated, i don't see so much of a problem here. E.g. if we have a function / method call: transmogrify(myValueType1, myValueType2, myValueType3); Right now we don't know whether any of these values is going to be modified or not. And with _optional_ annotations allowed we couldn't say neither. That situation is not worse than the situation we have now. Things would only be bad if people would wrongly think that call site annotations are obligatory. But if we would see the function call: transmogrify(myValueType1, myValueType2, out myValueType3); in some unknown piece of code we could at least surely know that myValueType3 is going to be modified. We couldn't say anything about myValueType1 or myValueType2 with optional annotations. The other parameters could or couldn't be modified. But we have at least a bit more context / information (e.g. that the function has side-effects). Normally functions / methods have better names so we would have even more context. If it would be possible to allow call site annotations for the people who want to use them as an additional documentation / safety feature and maybe make the compiler emit warnings (through an optional compiler switch) if they are omitted or just allow them, as long as it's clear that they are optional, i don't see any problem with it.
Sep 13 2012
prev sibling parent "Manuel" <manuel d.org> writes:
On Thursday, 13 September 2012 at 10:34:00 UTC, Andrei 
Alexandrescu wrote:
 On 9/13/12 1:02 AM, Manuel wrote:
 If a bigger part of the D community would like to have these 
 annotations
 added to the language, at least as an optional feature, then 
 that might
 persuade our "benevolent dictators" (just joking - you are 
 great!)
 Walther and Andrei to add them or we could just make a fork of 
 the
 language and add them ourselves (more joking - no, just skip 
 this last
 part - it's late) :-)

 There might be other problems, maybe with the compiler 
 internals or
 breakage of parts of the language. These were severe. But i 
 think only
 Walther and Andrei might tell. If these wouldn't exist it 
 would at least
 be possible, how David proposed it in his post, to make them 
 optional.
I don't think there would be problems with allowing ref/out optionally at the call site. The thing is, however, that in this matter reasonable people may disagree. In C++, the equivalent argument (should we pass everything modifiable by pointer or not?) erupts every six months on internal fora at Facebook. No winning argument is made by either part. For example, it is often brought up that it's good to see "&" at the call site when debugging some urgent matter at 3am. Yet there are other people who are just as apt at debugging urgent matters at 3am, and the absence of "&" doesn't seem to be a handicap for them at all. I'd be unable to identify any pattern in engineers choosing one preference over the other. As a consequence, our code has a mix of pass-by-pointer and pass-by-reference-to-nonconst, all engineers manage either style just as well, and we've never been able to find any evidence pointing one way or another. Now that the subject has been broken,
Thanks Andrei for sharing your experience with this matter in your working environment (after all, it's "Facebook" and not "John Nobody and Sons Inc."). To be honest, i and i think even Kevin, who started this thread, didn't expect such lively reactions. But Kevins thread seems to struck a nerve. And i think you made a very important point here. Whether someone would like to have this feature in the language or not is, despite all technical reasons / merits, also a psychological thing or a matter of taste.
 people who are just as apt at debugging urgent matters at 3am, 
 and the absence of "&" doesn't seem to be a handicap for them 
 at all
I think every competent programmer can handle both cases well (even at 3am). It's more, and here you are right, where you want to spend your time. Do you want to spend your time looking up all the function/method signatures you don't know / remember or spend it writing endless call site annotations. Do you want to spend your time debugging strange side-effects or want to write annoying annotations just to please the compiler. At the end, at 3am, it might result in the same level of productivity. (1) transmogrify(MyValueType1, MyValueType2, MyValueType3); The disadvantage here is, that if you don't know / have written the function you don't know whether if and which parameters might be modified. So you have to look the function signature up, no other choice here. There is no way for a quick read over the code. The advantage is that you save yourself writing endless annoying anotations, safe some typing and have less noise. (2) transmogrify(MyValueType1, MyValueType2, out MyValueType3); The disadvantage here is more typing, more noise. The advantage is that you as a programmer are forced to confirm that you know that this call will modify the value type and you want it this way, so nothing happens accidently. It's basically a double-check. You say i know this function will modify things and i want it that way. It gives people who read / review the code also more informations at a quick glance so they don't have too look things up constantly. Whether you want something double checked might really depend on your personality (maybe i am more the anxious type and you are the bungee jumper type ;-) ). So i think it basically boils down to this. I think it would fit do D because of the safety concept inside the language (as it is similar to contracts). Since you don't seem to be overzealous regarding this (if i interpreted your confession rightly ;-) ) then it might be the best to leave all as it is. I would like to have heared more arguments like: it breaks down certain language constructs, there are problems with templates or UCFS, or maybe from Walther that it makes too much work on the compiler side which could be spend better for other things or such. But as i have written i haved lived without call site annotations in D and can live on without them. And honestly, i even think there are also more important things to be adressed in D (the classic one like bugs, toolchain, etc.). So maybe the best contribution so far came from Paulo Pinto. To take things as they are and concentrate on more important things. But it's at least a good thing that we discussed this ;-)
 we do have good evidence of a pattern that generates 
 significant and difficult bugs: escaping the address of a 
 reference. In C++:

 struct A {
     A(int& host) : host_(host) {}
 private:
     int& host_;
 };

 In D:

 class A { // or struct
     A(ref int host) : _host(&host) {}
 private:
     int* _host;
 }

 A solution we use for C++ is to require escaped addresses to be 
 always passed as pointers or smart pointers.

 Walter and I have discussed this for quite a while. We have 
 recently decided to disallow, at least in SafeD, escaping the 
 address of a ref parameter. In the beginning we'll be overly 
 conservative by disallowing taking the address of a ref 
 altogether. I'll write a DIP on that soon.


 Andrei
Sep 13 2012
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Fri, 07 Sep 2012 13:34:02 +0200
"Kevin McTaggart" <kevin.mctaggart drdc-rddc.gc.ca> wrote:

 I suggest that the language require ref and out when 

see D fixed in this regard, and I've argued in favor of it some time ago. Unfortunately I don't think it's going to happen. Certainly not for D2 anyway, it's too late :(
Sep 08 2012
prev sibling parent "Kevin McTaggart" <kevin.mctaggart drdc-rddc.gc.ca> writes:
I'm amazed and very pleased at the discussion that this has 
generated.  I think it would be great if ref and out required for 
function calls in D3.  As others have mentioned, it would greatly 
assist with code readability.

On Friday, 7 September 2012 at 11:33:41 UTC, Kevin McTaggart 
wrote:
 I've been looking at migrating a reasonably large ship motion 

 quite enthusiastic about D, and most of my problems have been 
 relatively minor (e.g., inconsistent bugs with 
 std.container.Array, would like orange serialization to give me 
 an error telling me I didn't register a class before calling 
 serialize).  I suggest that the language require ref and out 

 easier to understand, and would also eliminate the problem I 
 had when the wrong function from the following choices was 
 mistakenly called:

 parseLineInts(string text, int positionStart, out int j0, out 
 int j1)

 parseLineInts(string text, out int j0, out int j1, out int j2)

 I note that the second function calls another function as 
 follows:
 int positionStart = 1;
 parseLineInts(text, positionStart, j0, j1, j2);

 I look forward to seeing feedback from D experts.  This is the 
 only significant change that I could think of recommending for 
 the language.
Sep 19 2012