Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
February 04, 2013 __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
I wanted to put forth again a proposal I had for getting a delegate to an overloaded function. Only because I think it's relevant to the latest property debate. When getting the address of a delegate, it's as simple as: struct S { void foo(int x) {} } S s; auto dg = &s.foo; // delegate obtained However, if foo is overloaded, this becomes more complex: struct S { void foo(int x) {} void foo(string s) {} } S s; auto dg = &s.foo; // which one? Compiler chooses! Turns out, it's somewhat possible to specify, but it can be painful/uintuitive: auto dg = cast(void delegate(string))&s.foo; // oops, what if I use the wrong delegate signature, or S.foo is changed later! How about getting a delegate using __traits? auto dg = __traits(getDelegate, s.foo, string); Maybe not quite as pretty as &s.foo, but at least allows you to form a good expression without a cast. Now, why is this relevant now? It could be useful for properties as well. It could allow obtaining a delegate to a property (arguably a very rare occurrence), where the current property proposal uses a funky parentheses technique for it (which seems unintuitive for a C expression to be changed by adding parentheses). Full proposal: __traits(getDelegate, symbol, arg1, arg2, ..., argN) The args are optional, only needed if overloads exist. If overloads exist, args MUST be specified (to protect against future changes). In the special case where one of the overloads has no arguments, void must be specified for that overload. Rules/syntax subject to debate. Destroy! -Steve |
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2/4/13 12:14 AM, Steven Schveighoffer wrote:
> I wanted to put forth again a proposal I had for getting a delegate to
> an overloaded function. Only because I think it's relevant to the latest
> property debate.
>
> When getting the address of a delegate, it's as simple as:
>
> struct S
> {
> void foo(int x) {}
> }
>
> S s;
> auto dg = &s.foo; // delegate obtained
>
> However, if foo is overloaded, this becomes more complex:
>
> struct S
> {
> void foo(int x) {}
> void foo(string s) {}
> }
>
> S s;
> auto dg = &s.foo; // which one? Compiler chooses!
>
> Turns out, it's somewhat possible to specify, but it can be
> painful/uintuitive:
>
> auto dg = cast(void delegate(string))&s.foo; // oops, what if I use the
> wrong delegate signature, or S.foo is changed later!
void delegate(string) dg = &s.foo;
Andrei
|
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Mon, 04 Feb 2013 00:20:22 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > On 2/4/13 12:14 AM, Steven Schveighoffer wrote: >> Turns out, it's somewhat possible to specify, but it can be >> painful/uintuitive: >> >> auto dg = cast(void delegate(string))&s.foo; // oops, what if I use the >> wrong delegate signature, or S.foo is changed later! > > void delegate(string) dg = &s.foo; That seems, ... odd. How does the lhs dictate the rhs expression type? Trying to think of a case where an expression is more handy than assigning to a variable first... Possibly this? Kind of a stretch. void delayedCall(D)(D dg) { // put dg as a delegate onto a message queue to call later... } -Steve |
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2/4/13 12:32 AM, Steven Schveighoffer wrote:
> On Mon, 04 Feb 2013 00:20:22 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>
>> On 2/4/13 12:14 AM, Steven Schveighoffer wrote:
>>> Turns out, it's somewhat possible to specify, but it can be
>>> painful/uintuitive:
>>>
>>> auto dg = cast(void delegate(string))&s.foo; // oops, what if I use the
>>> wrong delegate signature, or S.foo is changed later!
>>
>> void delegate(string) dg = &s.foo;
>
> That seems, ... odd. How does the lhs dictate the rhs expression type?
>
> Trying to think of a case where an expression is more handy than
> assigning to a variable first...
>
> Possibly this? Kind of a stretch.
>
> void delayedCall(D)(D dg)
> {
> // put dg as a delegate onto a message queue to call later...
> }
>
> -Steve
This is well-trodden ground. The rule has been in C++ forever and has worked well. It's time-proven, and there is little reason to mess with what works.
Andrei
|
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Mon, 04 Feb 2013 00:39:04 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > This is well-trodden ground. The rule has been in C++ forever and has worked well. It's time-proven, and there is little reason to mess with what works. Fair enough. Withdrawn. -Steve |
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 4 February 2013 at 05:39:04 UTC, Andrei Alexandrescu wrote:
> This is well-trodden ground. The rule has been in C++ forever and has worked well. It's time-proven, and there is little reason to mess with what works.
>
C++ is notoriously confusing, odd, weird, and basically any adjective except straightforward, simple and clear.
|
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2013-02-04 06:20, Andrei Alexandrescu wrote: > void delegate(string) dg = &s.foo; I know that this expression works. But since this works, why can't we overload on the return value. This seems to be do exactly this. The arguments I heard against overloading on the return value is due the LHS of an expression shouldn't affect the RHS. -- /Jacob Carlborg |
February 04, 2013 Re: __traits(getDelegate, ...) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 2/4/13 3:01 AM, Jacob Carlborg wrote:
> On 2013-02-04 06:20, Andrei Alexandrescu wrote:
>
>> void delegate(string) dg = &s.foo;
>
> I know that this expression works. But since this works, why can't we
> overload on the return value. This seems to be do exactly this. The
> arguments I heard against overloading on the return value is due the LHS
> of an expression shouldn't affect the RHS.
I think overloading on the return value of functions can be made to work. I understand how it makes it more difficult on the side of the compiler writer, but it's not impossible. The main argument against it is that it adds yet another layer of difficulty in name resolution for function calls.
Andrei
|
Copyright © 1999-2021 by the D Language Foundation