July 02, 2013 Member lookup (Was: Re: UFCS and constructors) | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 07/02/2013 03:00 PM, deadalnix wrote:
> On Tuesday, 2 July 2013 at 12:57:50 UTC, Timon Gehr wrote:
>> On 07/02/2013 09:35 AM, monarch_dodra wrote:
>>> ...
>>>
>>> One of the "big" problems with allowing UFCS and constructors is that a
>>> "." which meant "scope" can now mean "function call".
>>> ...
>>
>> I missed this point.
>>
>> 'One of the drawbacks of UFCS is that "bar.foo" which meant "scope
>> lookup" or "opDispatch instantiation" or "alias this lookup" can now
>> also mean "UFCS lookup".'
>>
>> Fixed.
>
> That is an issue, we have all of this, and prioritization mechanism is
> implementation defined right now.
Yup. I'll go with:
1: If member is present (current scope or super class scope), use that,
otherwise try opDispatch in the same scopes. Block alias this at
this point.
2: If no success, loop through all alias this definitions and apply 1.
for the corresponding scopes. Collect possible members.
3: Error out if multiple possible distinct members.
4: Try UFCS rewrite if no matches.
(Of course, even checking whether a member is present, or looping over all alias this definitions are not entirely trivial processes themselves in the general case.)
This seems to be compatible with what DMD does.
|
July 02, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Tuesday, July 02, 2013 14:46:41 Timon Gehr wrote:
> > Do we want to keep it?
>
> There is no reason to artificially ban it.
There's nothing artificial about it. Constructors are not normal functions and should not be treated as such. They're fundamentally different from normal functions.
Also, in all other cases, UFCS involves using a free function as if it were a member function, so it's incredibly bizarre as well as inconsistent with the rest of UFCS to allow constructors to be used with it.
- Jontahan M Davis
|
July 02, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 07/02/2013 07:58 PM, Jonathan M Davis wrote:
> On Tuesday, July 02, 2013 14:46:41 Timon Gehr wrote:
>>> Do we want to keep it?
>>
>> There is no reason to artificially ban it.
>
> There's nothing artificial about it. Constructors are not normal functions and
> should not be treated as such.
> They're fundamentally different from normal
> functions.
>
> Also, in all other cases, UFCS involves using a free function as if it were a
> member function, so it's incredibly bizarre as well as inconsistent with the
> rest of UFCS to allow constructors to be used with it.
>
> - Jontahan M Davis
>
It is an artificial limitation, because you need to add an explicit check after symbol lookup to ban constructors.
Analogies are always broken, but the rest of the post reads to me roughly like:
"Dogs are not pets, and should not be treated as such.
They are fundamentally different from pets.
Also, there are no other pets that bark, so it's incredibly bizarre as well as inconsistent with the rest of the notion of a 'pet' to have a pet dog.
- Tmion M Gehr
"
This has happened before. What am I missing?
|
July 02, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:
>
> Analogies are always broken, but the rest of the post reads to me roughly like:
>
> "Dogs are not pets, and should not be treated as such.
> They are fundamentally different from pets.
>
> Also, there are no other pets that bark, so it's incredibly bizarre as well as inconsistent with the rest of the notion of a 'pet' to have a pet dog.
>
> - Tmion M Gehr
> "
>
class A
{
this() {}
void foo(){}
}
A a = new A; // calls ctor, not foo
Of course constructors are special because not any function is called upon object construction. Same logic was made when ability to overload some operators was blocked. All operators are, well, operators but you cannot overload all of them. It appears that sometimes it does make sense to restrict operation on some particular elements of the set and sometimes not.
Anyway, without final decision on this issue, there would be endless controversy between those who point on commonness of all functions and those who point on peculiarity of some of them.
|
July 02, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On 07/02/2013 10:16 PM, Maxim Fomin wrote: > On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote: >> >> Analogies are always broken, but the rest of the post reads to me >> roughly like: >> >> "Dogs are not pets, and should not be treated as such. >> They are fundamentally different from pets. >> >> Also, there are no other pets that bark, so it's incredibly bizarre as >> well as inconsistent with the rest of the notion of a 'pet' to have a >> pet dog. >> >> - Tmion M Gehr >> " >> > > class A > { > this() {} > void foo(){} > } > > A a = new A; // calls ctor, not foo > > Of course constructors are special because not any function is called > upon object construction. (We are discussing struct constructors.) Of course. I fully agree. Obviously there is a reason why those functions are called constructors. But one could now extend on the original argument, and say that eg. all the overloading rules should be different for constructors, because they are fundamentally different and should under no circumstances be treated like 'normal functions'. Do you see what the point is? This is not a valid way of justifying a breaking language change. > Same logic Logics that can prove some equivalent statements are not necessarily equivalent. (In particular, it does not rule out inconsistency of one of them.) > was made when ability to overload > some operators was blocked. All operators are, well, operators but you > cannot overload all of them. It appears that sometimes it does make > sense to restrict operation on some particular elements of the set and > sometimes not. > ... Such restrictions need to be justified. The justification should make (at least some) sense. There is no point in heuristically designing language features from observations about other language features without applying insight. (Anyway, I do not think that overloading of a fixed set of primitive operators using specially named member functions is a good mechanism for infix notation.) |
July 03, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Tuesday, 2 July 2013 at 19:47:07 UTC, Timon Gehr wrote:
> It is an artificial limitation, because you need to add an explicit check after symbol lookup to ban constructors.
>
That seems very implementation defined. The lookup will gives you a class or struct declaration, so special casing the constructor is mandatory anyway.
|
July 03, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Tuesday, 2 July 2013 at 21:38:26 UTC, Timon Gehr wrote:
> Such restrictions need to be justified. The justification should make (at least some) sense. There is no point in heuristically designing language features from observations about other language features without applying insight.
>
The whole point of UFCS is to be able to provide additional custom "methods" to a object (class or struct). Constructor UFCS don't fulfill that use case.
Nothing is removed from the language as factories method can be introduced anyway.
|
July 03, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | deadalnix:
> The whole point of UFCS is to be able to provide additional custom "methods" to a object (class or struct). Constructor UFCS don't fulfill that use case.
>
> Nothing is removed from the language as factories method can be introduced anyway.
This frames the topic in a wrong way. Constructors are not normal functions, they are special, but functional languages show us that's it's a very good idea to see them as functions.
And the original point of UFCS doesn't matter much. What matters is what are the practical disadvantages of allowing UFCSyntax for constructors (like the original post in this thread), and what are their practical advantages/uses (like a handy usage in UFCS chains). Then we take a look at what's the resulting balance and we decide. And such decisions should then become the written specifics of this part of the D design.
Bye,
bearophile
|
July 03, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, July 03, 2013 04:00:45 bearophile wrote:
> deadalnix:
> > The whole point of UFCS is to be able to provide additional custom "methods" to a object (class or struct). Constructor UFCS don't fulfill that use case.
> >
> > Nothing is removed from the language as factories method can be introduced anyway.
>
> This frames the topic in a wrong way. Constructors are not normal functions, they are special, but functional languages show us that's it's a very good idea to see them as functions.
>
> And the original point of UFCS doesn't matter much. What matters is what are the practical disadvantages of allowing UFCSyntax for constructors (like the original post in this thread), and what are their practical advantages/uses (like a handy usage in UFCS chains). Then we take a look at what's the resulting balance and we decide. And such decisions should then become the written specifics of this part of the D design.
The primary benefit of UFCS is generic code, because if uses UFCS, generic code doesn't have to care whether a function is a member function or a free function (particularly when that can vary drastically depending on what type is used to instantiate the template). Construction is not and cannot be generic. The closest that you could get would be a factory function, which is quite different. But constructors themselves cannot be generic. As such, using constructors with UFCS in generic code just doesn't work, meaning that the only gain that you're getting from using UFCS with constructors is that you get a slightly different syntax that you might like better for one reason or another. But I see no technical reason why it could add any benefit over simply calling the constructor normally. And as such, I think that allowing UFCS to work with constructors is definitely an anti-feature.
- Jonathan M Davis
|
July 03, 2013 Re: UFCS and constructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 07/03/2013 04:12 AM, Jonathan M Davis wrote: > On Wednesday, July 03, 2013 04:00:45 bearophile wrote: >> deadalnix: >>> The whole point of UFCS is to be able to provide additional >>> custom "methods" to a object (class or struct). Constructor >>> UFCS don't fulfill that use case. >>> >>> Nothing is removed from the language as factories method can be >>> introduced anyway. >> >> This frames the topic in a wrong way. Constructors are not normal >> functions, they are special, but functional languages show us >> that's it's a very good idea to see them as functions. >> >> And the original point of UFCS doesn't matter much. What matters >> is what are the practical disadvantages of allowing UFCSyntax for >> constructors (like the original post in this thread), and what >> are their practical advantages/uses (like a handy usage in UFCS >> chains). Then we take a look at what's the resulting balance and >> we decide. And such decisions should then become the written >> specifics of this part of the D design. > > The primary benefit of UFCS is generic code, because if uses UFCS, generic code > doesn't have to care whether a function is a member function or a free > function (particularly when that can vary drastically depending on what type > is used to instantiate the template). No. Generic code has to be careful with UFCS, because every method that is called on a suitable variable via UFCS can be (accidentally) replaced by the client code. > Construction is not and cannot be generic. The point is that struct constructors can be generically used like other callables. import std.stdio, std.algorithm; struct S{ int x; } void main(){ auto x = [1,2,3]; writeln(x.map!S); } There is nothing to be gained from subtly breaking this analogy. UFCS can be applied to any callable. You are probably not going to like this, but the following code also works: import std.stdio; struct S{ int opCall(int x){ return x+1; } } S s; void main(){ auto x = 1; writeln(x.s); } > The closest that you could get would be a factory function, which is > quite different. But constructors themselves cannot be generic. As such, using > constructors with UFCS in generic code just doesn't work, meaning that the > only gain that you're getting from using UFCS with constructors is that you > get a slightly different syntax that you might like better for one reason or > another. But I see no technical reason why it could add any benefit over simply > calling the constructor normally. And as such, I think that allowing UFCS to > work with constructors is definitely an anti-feature. > ... To be an anti-feature it has to be harmful, not just of less benefit than some other (aspect of the) feature. |
Copyright © 1999-2021 by the D Language Foundation