Skip to content

Comments

Issue 7538 - All kinds of property functions should be called before getting their types inside typeof#2123

Merged
WalterBright merged 1 commit intodlang:masterfrom
9rnsr:fix7538
Jul 10, 2013
Merged

Issue 7538 - All kinds of property functions should be called before getting their types inside typeof#2123
WalterBright merged 1 commit intodlang:masterfrom
9rnsr:fix7538

Conversation

@9rnsr
Copy link
Contributor

@9rnsr 9rnsr commented Jun 2, 2013

@9rnsr
Copy link
Contributor Author

9rnsr commented Jun 3, 2013

@andralex, this is contrary to a part of DIP24, but I think it is necessary.

In DIP24, you proposed that typeof(func) should always return the type of function call func() instead of the function type, even if func is not annotated with @property.
In the forum discussion I had agreed with that, but later I found that the change will break not few existing code.


Currently is(typeof(func)) is widely used as an idiom for checking "whether the func actually exists or not".
If func is a non-template function, it returns its function type. If func is a template function, it returns void and is(void) returns true. And then, if func is a @property function, it returns the type of property (== the return type of @property function).

However, if the typeof(func) behavior is changed, the idiom will not work anymore. If func has one or more arguments, it makes error because func is not callable with zero-args.


So I think we should continue current behavior. This change does it more strictly.

@andralex
Copy link
Member

andralex commented Jun 9, 2013

This seems like an odd special case to me to support. A template function with parameters is called as foo!(int)(). (We allow that without parens, which I don't think has a bearing on this issue: foo!int().) Then, if foo is a property, you get to invoke it with foo!(int) or foo!int.

Now transporting that to parameter-less template functions, we ordinarily call them with foo!()(). It follows if they're properties, we get to invoked them with foo!() and that's consistent in every way.

I am not sure I understand the argument around is(typeof(func)). So if func is a regular function, fine, typeof yields the type of the function. If it's a template function with any number of arguments, then func!(), func!arg, or func!args should take the place of the function name. Then properties decide the meaning of an /extra/ pair of parens after that.

So I guess I'm confused...

@9rnsr
Copy link
Contributor Author

9rnsr commented Jun 10, 2013

The core issue in bug 7538 is that current typeof checks only non-template @property functions.

Current compiler behaves as follows.

// non-template functions
long nfunc1() { return 1; }
void nfunc2(long) { }
pragma(msg, typeof(nfunc1));    // prints 'long()'
pragma(msg, typeof(nfunc2));    // prints 'void(long)'

For non-template normal functins, typeof yields the type of the function.
Then, is(typeof(nfunc)) always return true.

@property long nprop1() { return 1; }
@property void nprop2(long) {  }
pragma(msg, typeof(nprop1));    // prints 'long'
pragma(msg, typeof(nprop2));    // error

For non-template getter property function, typeof yields its return type.
For non-template setter property function, typeof yields an error.

Then, is(typeof(nprop)) returns true only when nprop is a getter property.

Up to this point, each of them expected?

OK. Let's see template cases.

// template functions
long tfunc1()() { return 1; }
void tfunc2(T)(T) { }
pragma(msg, typeof(tfunc1));    // prints 'void'
pragma(msg, typeof(tfunc2));    // prints 'void'

For template normal functins, typeof yields void. In both cases, template is not yet instantiated, but accessing them is valid.
Then, is(typeof(tfunc)) always returns true.

@property long tprop1()() { return 1; }
@property void tprop2(T)(T) {  }
pragma(msg, typeof(tprop1));    // prints void - inconsistent with nprop1
pragma(msg, typeof(tprop2));    // prints void - inconsistent with nprop2

Finally, for template @property functions, typeof yields void, as same as template normal functions.
Then, is(typeof(tprop)) always returns true.

I think the last case: typeof(tprop) should behave as same as typeof(nprop). This pull request fixes the issue.

Any opinions about this?

WalterBright added a commit that referenced this pull request Jul 10, 2013
Issue 7538 - All kinds of property functions should be called before getting their types inside typeof
@WalterBright WalterBright merged commit 88b60e7 into dlang:master Jul 10, 2013
@9rnsr
Copy link
Contributor Author

9rnsr commented Jul 11, 2013

Thanks, @WalterBright . This change has been a basis for both #2130 and #2305.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants