July 28, 2016
On Friday, July 29, 2016 06:44:16 Timon Gehr via Digitalmars-d wrote:
> My parser accepts the following:
>
> int function(int,int)ref functionPointer;
>
> I wasn't really aware that this was illegal in DMD. (Other function attributes, such as pure, are accepted.)
>
> In fact, even the following is disallowed:
> int foo(int)ref{}
>
>
> Should I file an enhancement request?

Except that ref isn't a function attribute. It's an attribute on the return type. So, it doesn't make sense for it to be on the right. That would be like having the const on the right-hand side of a member function apply to the return type rather than the function itself.

- Jonathan M Davis

July 29, 2016
On 29.07.2016 06:52, Jonathan M Davis via Digitalmars-d wrote:
> On Friday, July 29, 2016 06:44:16 Timon Gehr via Digitalmars-d wrote:
>> My parser accepts the following:
>>
>> int function(int,int)ref functionPointer;
>>
>> I wasn't really aware that this was illegal in DMD. (Other function
>> attributes, such as pure, are accepted.)
>>
>> In fact, even the following is disallowed:
>> int foo(int)ref{}
>>
>>
>> Should I file an enhancement request?
>
> Except that ref isn't a function attribute.

Yes it is.

int x;
ref{
    int foo(){ return x;}
}
pragma(msg, typeof(&foo()));


> It's an attribute on the return type.

There is no such thing. Types cannot have attributes.

> So, it doesn't make sense for it to be on the right. That would be
> like having the const on the right-hand side of a member function apply to
> the return type rather than the function itself.
> ...

You have it backwards.
July 28, 2016
On Friday, July 29, 2016 08:29:19 Timon Gehr via Digitalmars-d wrote:
> On 29.07.2016 06:52, Jonathan M Davis via Digitalmars-d wrote:
> > On Friday, July 29, 2016 06:44:16 Timon Gehr via Digitalmars-d wrote:
> >> My parser accepts the following:
> >>
> >> int function(int,int)ref functionPointer;
> >>
> >> I wasn't really aware that this was illegal in DMD. (Other function attributes, such as pure, are accepted.)
> >>
> >> In fact, even the following is disallowed:
> >> int foo(int)ref{}
> >>
> >>
> >> Should I file an enhancement request?
> >
> > Except that ref isn't a function attribute.
>
> Yes it is.
>
> int x;
> ref{
>      int foo(){ return x;}
> }
> pragma(msg, typeof(&foo()));

That's downright bizzarre given that ref applies to the return type and not to the this pointer (and that function doesn't even have a this pointer, since it's not a member function).

> > It's an attribute on the return type.
>
> There is no such thing. Types cannot have attributes.

Sure they can. e.g.

auto func(ref int param) {...}

The same with in and out. They apply to the type of the parameter without actually being part of it.

> > So, it doesn't make sense for it to be on the right. That would be
> > like having the const on the right-hand side of a member function apply to
> > the return type rather than the function itself.
> > ...
>
> You have it backwards.

It looks to me like the compiler is treating ref in a schizophrenic manner given that when it's used on a parameter, it treats it as part of the parameter, whereas with the return type, it's treating it as a function attribute instead of associating it with the return type. I'd guess that that stems from the fact that while ref is really supposed to be associated with the type, it's not actually part of the type.

- Jonathan M Davis

July 29, 2016
On 29.07.2016 08:51, Jonathan M Davis via Digitalmars-d wrote:
> On Friday, July 29, 2016 08:29:19 Timon Gehr via Digitalmars-d wrote:
>> On 29.07.2016 06:52, Jonathan M Davis via Digitalmars-d wrote:
>>> On Friday, July 29, 2016 06:44:16 Timon Gehr via Digitalmars-d wrote:
>>>> My parser accepts the following:
>>>>
>>>> int function(int,int)ref functionPointer;
>>>>
>>>> I wasn't really aware that this was illegal in DMD. (Other function
>>>> attributes, such as pure, are accepted.)
>>>>
>>>> In fact, even the following is disallowed:
>>>> int foo(int)ref{}
>>>>
>>>>
>>>> Should I file an enhancement request?
>>>
>>> Except that ref isn't a function attribute.
>>
>> Yes it is.
>>
>> int x;
>> ref{
>>      int foo(){ return x;}
>> }
>> pragma(msg, typeof(&foo()));
>
> That's downright bizzarre given that ref applies to the return type and not
> to the this pointer (and that function doesn't even have a this pointer,
> since it's not a member function).
> ...

It does not apply to the return type. There is actually no way to tell whether a function returns ref or not by just examining the return type. It's the function which is ref.

>>> It's an attribute on the return type.
>>
>> There is no such thing. Types cannot have attributes.
>
> Sure they can. e.g.
>
> auto func(ref int param) {...}
>
> The same with in and out. They apply to the type of the parameter without
> actually being part of it.
> ...

No, typeof(param) is int. The type is not changed at all. The attribute applies to the parameter declaration.

>>> So, it doesn't make sense for it to be on the right. That would be
>>> like having the const on the right-hand side of a member function apply to
>>> the return type rather than the function itself.
>>> ...
>>
>> You have it backwards.
>
> It looks to me like the compiler is treating ref in a schizophrenic manner
> given that when it's used on a parameter, it treats it as part of the
> parameter, whereas with the return type, it's treating it as a function
> attribute instead of associating it with the return type. I'd guess that
> that stems from the fact that while ref is really supposed to be associated
> with the type, it's not actually part of the type.
>
> - Jonathan M Davis
>

'ref' has nothing to do with the type. This is not C++.

The only thing that is inconsistent here is that 'ref' is not accepted on the right for function declarations.
July 29, 2016
On Friday, July 29, 2016 09:03:18 Timon Gehr via Digitalmars-d wrote:
> 'ref' has nothing to do with the type. This is not C++.
>
> The only thing that is inconsistent here is that 'ref' is not accepted on the right for function declarations.

ref may not be part of the type, but it just seems totally wrong for it to be applying to anything else. I mean, how does it make any sense for a _function_ to be ref or not? It may return by ref, but the function itself is a function. It's what's going on with the return value that changes based or ref or not.

Maybe I'm just looking at this wrong, but it seems completely bizarre to consider the _function_ to be ref or not. It sounds like it's just a weird biproduct of trying to make it so that ref doesn't propagate beyond the return type or the parameter so that you can't have ref variables in general.

I've always looked at D's ref as being essentially the same as C++'s & except that it's not considered to be part of the type, just attached to it in a way that doesn't propagate. The same with with in or out. I just don't see how it even makes conceptual sense for ref to be an attribute of the function itself.

- Jonathan M Davis

July 29, 2016
On 7/29/2016 1:34 AM, Jonathan M Davis via Digitalmars-d wrote:
> I've always looked at D's ref as being essentially the same as C++'s &
> except that it's not considered to be part of the type, just attached to it
> in a way that doesn't propagate. The same with with in or out. I just don't
> see how it even makes conceptual sense for ref to be an attribute of the
> function itself.

C++'s & is a bizarre type constructor in that it has completely wacky and special cased behavior in just about everything involving types, including type deduction, type inference, overloading, etc. For example, you can't have a pointer to a ref. Or a ref of a ref. Sometimes the ref is considered part of the type, sometimes not. Etc.

With D, making it a sort of storage class completely sidesteps that mess.

July 29, 2016
On Friday, July 29, 2016 02:55:14 Walter Bright via Digitalmars-d wrote:
> On 7/29/2016 1:34 AM, Jonathan M Davis via Digitalmars-d wrote:
> > I've always looked at D's ref as being essentially the same as C++'s &
> > except that it's not considered to be part of the type, just attached to
> > it
> > in a way that doesn't propagate. The same with with in or out. I just
> > don't
> > see how it even makes conceptual sense for ref to be an attribute of the
> > function itself.
>
> C++'s & is a bizarre type constructor in that it has completely wacky and special cased behavior in just about everything involving types, including type deduction, type inference, overloading, etc. For example, you can't have a pointer to a ref. Or a ref of a ref. Sometimes the ref is considered part of the type, sometimes not. Etc.
>
> With D, making it a sort of storage class completely sidesteps that mess.

I understand that part. It's treating it like a function attribute that makes no sense to me. Even if it's not treated as part of the return type exactly, it's still the return type that it's affecting, not the function. ref, in, and out are all in this kind of weird place where they affect a type without being part of the type, and I'm guessing that because of how oddball they are, there really wasn't a good way to deal with ref on the return type, since it wasn't actually part of the type, so in the implementation, it got tied to the function instead rather than trying to add a new concept to the compiler. So, I guess that from an implementation perspective, it makes some sense, but it's still downright weird given that ref really has to do with the return type and not the function itself, even if ref is a storage class rather than actually being part of the type.

- Jonathan M Davis

July 29, 2016
On 07/29/2016 02:05 PM, Jonathan M Davis via Digitalmars-d wrote:
> On Friday, July 29, 2016 02:55:14 Walter Bright via Digitalmars-d wrote:
>> On 7/29/2016 1:34 AM, Jonathan M Davis via Digitalmars-d wrote:
>>> I've always looked at D's ref as being essentially the same as C++'s &
>>> except that it's not considered to be part of the type, just attached to
>>> it
>>> in a way that doesn't propagate. The same with with in or out. I just
>>> don't
>>> see how it even makes conceptual sense for ref to be an attribute of the
>>> function itself.
>>
>> C++'s & is a bizarre type constructor in that it has completely wacky and special cased behavior in just about everything involving types, including type deduction, type inference, overloading, etc. For example, you can't have a pointer to a ref. Or a ref of a ref. Sometimes the ref is considered part of the type, sometimes not. Etc.
>>
>> With D, making it a sort of storage class completely sidesteps that mess.
> 
> I understand that part. It's treating it like a function attribute that makes no sense to me. Even if it's not treated as part of the return type exactly, it's still the return type that it's affecting, not the function. ref, in, and out are all in this kind of weird place where they affect a type without being part of the type, and I'm guessing that because of how oddball they are, there really wasn't a good way to deal with ref on the return type, since it wasn't actually part of the type, so in the implementation, it got tied to the function instead rather than trying to add a new concept to the compiler. So, I guess that from an implementation perspective, it makes some sense, but it's still downright weird given that ref really has to do with the return type and not the function itself, even if ref is a storage class rather than actually being part of the type.

What you want it contradictory to the concept of "storage class".

July 29, 2016
On 7/29/16 12:44 AM, Timon Gehr wrote:
>
> My parser accepts the following:
>
> int function(int,int)ref functionPointer;
>
> I wasn't really aware that this was illegal in DMD. (Other function
> attributes, such as pure, are accepted.)
>
> In fact, even the following is disallowed:
> int foo(int)ref{}
>
>
> Should I file an enhancement request?

Yes. Worst that happens is it doesn't get accepted :)

-Steve
July 29, 2016
On Thursday, 28 July 2016 at 20:16:11 UTC, Jonathan M Davis wrote:
> Well, if we decided to make parens with ref legal, then we could make it work. e.g.
>
> ref(int) function(int, int) functionPointer;
>
> Now, I don't know of any other case where you'd actually use parens with ref if it were legal, but it would solve this particular case if we wanted to provide a way around the ambiguity.

I had an idea of putting function attributes between return type and function name:
int ref function(int, int)