June 01, 2012
>
> 1. It's needed so that you can call it when calling C code.
>

Why can't we just use information from the C function signature to determine when an address needs to be passed? Why is manual intervention required here?

> 2. Just because ref is often better than a pointer doesn't mean that it's
> never valuable to be able to pass a pointer to a variable.

Passing a pointer may be useful but IMO we should restrict such things to the unsafe context.

>
> 3. ref doesn't work with variadic templates very well. Take a look a
> std.getopt.getopt. It takes pointers, not refs, and there isn't a way to make
> it take refs.
>

Is it because getopt() is a C function? If it is see my reply to your point #1. I'll admit I do not know enough D to understand what you are saying, some explanation will be helpful.

> 4. & is useful for getting function pointers.

What does the function name represent when not used with an ampersand? If it doesn't represent anything then I think the language can be changed to yield an address directly without an ampersand.
June 01, 2012
On 06/01/12 19:19, Sandeep Datta wrote:
>>
>> 1. It's needed so that you can call it when calling C code.
>>
> 
> Why can't we just use information from the C function signature to determine when an address needs to be passed? Why is manual intervention required here?
> 
>> 2. Just because ref is often better than a pointer doesn't mean that it's never valuable to be able to pass a pointer to a variable.
> 
> Passing a pointer may be useful but IMO we should restrict such things to the unsafe context.
> 
>>
>> 3. ref doesn't work with variadic templates very well. Take a look a std.getopt.getopt. It takes pointers, not refs, and there isn't a way to make it take refs.
>>
> 
> Is it because getopt() is a C function? If it is see my reply to your point #1. I'll admit I do not know enough D to understand what you are saying, some explanation will be helpful.
> 
>> 4. & is useful for getting function pointers.
> 
> What does the function name represent when not used with an ampersand? If it doesn't represent anything then I think the language can be changed to yield an address directly without an ampersand.
> 

   import std.stdio;
   @property f() { writeln("oops"); return 0; }
   void main() { auto p = f; }

artur
June 01, 2012
>
>    import std.stdio;
>    @property f() { writeln("oops"); return 0; }
>    void main() { auto p = f; }
>
> artur

I understand what you are trying to say but I hear parens will become mandatory soon. This may not be a problem then.
June 01, 2012
On Friday, 1 June 2012 at 15:58:04 UTC, Andrej Mitrovic wrote:
> On 5/31/12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
>> 2. Just because ref is often better than a pointer doesn't mean that it's
>> never valuable to be able to pass a pointer to a variable.
>
> 5. And '&' documents code better at the call site. I personally refuse
> to use out/ref arguments because the call site makes it ambiguous
> whether an argument is passed by reference or not.

Please see http://forum.dlang.org/post/ycwrmmvnpdwkonjwogax@forum.dlang.org
June 01, 2012
On 06/01/12 19:41, Sandeep Datta wrote:
>>
>>    import std.stdio;
>>    @property f() { writeln("oops"); return 0; }
>>    void main() { auto p = f; }
>>
>> artur
> 
> I understand what you are trying to say but I hear parens will become mandatory soon. This may not be a problem then.

No, it's the other way around - parens are accepted now, but shouldn't be. The whole point of properties is to behave as fields.

   import std.stdio;

   struct S {
      @property int x() { return 42; }
   }

   void main() {
      S s;
      auto p1 = &s.x; writeln(p1);
      auto p2 = s.x;  writeln(p2);
   }

> While writing code we expect the compiler to understand what we want to do without writing a lot of code.

Do you really consider '&' to be "a lot of code"?

D is not as compact as it could be, but '&' is not part of that problem. It is
necessary to disambiguate and makes the code more readable by being explicit.

artur
June 01, 2012
On Friday, 1 June 2012 at 17:07:57 UTC, Sandeep Datta wrote:
> 1. While writing code we expect the compiler to understand what we want to do without writing a lot of code.


    &

is not "a lot of code".
June 01, 2012
On Friday, 1 June 2012 at 18:07:12 UTC, Artur Skawina wrote:
> On 06/01/12 19:41, Sandeep Datta wrote:
>>>
>>>    import std.stdio;
>>>    @property f() { writeln("oops"); return 0; }
>>>    void main() { auto p = f; }
>>>
>>> artur
>> 
>> I understand what you are trying to say but I hear parens will become mandatory soon. This may not be a problem then.
>
> No, it's the other way around - parens are accepted now, but shouldn't be.
> The whole point of properties is to behave as fields.

Ok, I overlooked the @property declaration. Sorry about that.

>
>> While writing code we expect the compiler to understand what we want to do without writing a lot of code.
>
> Do you really consider '&' to be "a lot of code"?
>

Actually no I don't consider it to be a lot of code but I think it is an annoyance nevertheless...one which I can live with.
June 01, 2012
On Friday, 1 June 2012 at 18:07:12 UTC, Artur Skawina wrote:
> On 06/01/12 19:41, Sandeep Datta wrote:
>>>
>>>    import std.stdio;
>>>    @property f() { writeln("oops"); return 0; }
>>>    void main() { auto p = f; }
>>>
>>> artur
>> 
>> I understand what you are trying to say but I hear parens will become mandatory soon. This may not be a problem then.
>
> No, it's the other way around - parens are accepted now, but shouldn't be.
> The whole point of properties is to behave as fields.

Ok, I overlooked the @property declaration. Sorry about that.

>
>> While writing code we expect the compiler to understand what we want to do without writing a lot of code.
>
> Do you really consider '&' to be "a lot of code"?
>

Actually no I don't consider it to be a lot of code but I think
it is an annoyance nevertheless...one which I can live with.
June 01, 2012
On Friday, June 01, 2012 19:19:17 Sandeep Datta wrote:
> > 1. It's needed so that you can call it when calling C code.
> 
> Why can't we just use information from the C function signature to determine when an address needs to be passed? Why is manual intervention required here?

How about something like

int myVar;
cFunc(&myVar, 7);

The C function takes a pointer, and I want to pass a local variable to it. & is the way to do that. Even if I would have used ref or out for such a function if it were a D function, it's a C function, so I can't do that.

> > 2. Just because ref is often better than a pointer doesn't mean
> > that it's
> > never valuable to be able to pass a pointer to a variable.
> 
> Passing a pointer may be useful but IMO we should restrict such things to the unsafe context.

If you don't want to use them, don't use them. But pointers _are_ part of @safe because they _are_ safe. It's pointer arithmetic which isn't @safe. AA's in returns a pointer. If you want to put something other than a class on the heap, you need a pointer. Pointers aren't going anywhere. And if you need a pointer to something which isn't a pointer, then you need &.

> > 3. ref doesn't work with variadic templates very well. Take a
> > look a
> > std.getopt.getopt. It takes pointers, not refs, and there isn't
> > a way to make
> > it take refs.
> 
> Is it because getopt() is a C function? If it is see my reply to your point #1. I'll admit I do not know enough D to understand what you are saying, some explanation will be helpful.

It's not a C function. It's a variadic template. It's instantiated with whatever types it's given. It's literally _impossible_ to use ref with that sort of function. So, if you want it to take the variable and write to it, you have to pass a pointer to it.

> > 4. & is useful for getting function pointers.
> 
> What does the function name represent when not used with an ampersand? If it doesn't represent anything then I think the language can be changed to yield an address directly without an ampersand.

That wouldn't work due to properties.

Really, if you prefer to use ref over pointers, then use ref and don't use &. But & is useful and necessary for some circumstances and removing it would cripple us for little to no benefit.

- Jonathan M Davis
June 01, 2012
On 06/01/12 22:03, Jonathan M Davis wrote:
> On Friday, June 01, 2012 21:48:01 Artur Skawina wrote:
>> On 06/01/12 21:18, Jonathan M Davis wrote:
>>>>> 3. ref doesn't work with variadic templates very well. Take a
>>>>> look a
>>>>> std.getopt.getopt. It takes pointers, not refs, and there isn't
>>>>> a way to make
>>>>> it take refs.
>>>>
>>>> Is it because getopt() is a C function? If it is see my reply to your point #1. I'll admit I do not know enough D to understand what you are saying, some explanation will be helpful.
>>>
>>> It's not a C function. It's a variadic template. It's instantiated with
>>> whatever types it's given. It's literally _impossible_ to use ref with
>>> that
>>> sort of function. So, if you want it to take the variable and write to it,
>>> you have to pass a pointer to it.
>>
>> import std.stdio;
>>
>> void go(A...)(auto ref A a) {
>> a[0] = 42;
>> a[1].y--;
>> }
>>
>> struct S { int y; }
>>
>> void main() {
>> int x;
>> S s;
>>
>> go(x, s);
>>
>> writeln(x, " ", s);
>> }
> 
> auto ref is _completely_ different from ref. The compiler chooses whether to pass by ref or not with the idea that it will pick whatever is most efficient for that type, but it's implementation-dependent whether something will be passed by ref or not. And using ref is no solution, because then _all_ of the arguments must be lvalues. If you want a function to take an arbitrary set of arguments where some of them are passed by ref and others not, you _can't do it_. You have to use pointers instead, because the types of all of the parameters are inferred from the arguments, and nothing ever gets inferred as ref, because ref is not a type constructor.

I only used "auto ref" so that nobody would complain that it fails for non-lvalues. You can use just 'ref', and i'd agree that such an interface would be saner.

However, if you know of a case where 'auto ref' behaves as you describe, file it as
a bug. That's not how it's defined, and that is not how it could be sanely implemented.
The sane definition is 'if it's an lvalue then it's a ref parameter'. And if you go
and check http://dlang.org/template.html you will see it's defined exactly like that.
Really, the compiler *cannot* decide by itself if something is passed by value or
not, it would make this feature unusable.

artur