digitalmars.D.learn - Properties no longer work?
- Hasan Aljudy (47/47) Jul 25 2006 Did properties stop working?
- Jarrett Billingsley (10/14) Jul 25 2006 Stop using type inference. ;)
- Don Clugston (4/22) Jul 27 2006 Function types are just bizarre. I only recently discovered that C has
- Jarrett Billingsley (6/9) Jul 27 2006 I think they're mostly a "convenience" type for the compiler. Most of t...
- Bruno Medeiros (10/34) Jul 27 2006 C has them? Where did you see that, I was under the impression that C
- Jarrett Billingsley (10/15) Jul 27 2006 I'm not sure, but I think that skipping the & on getting a function poin...
- Bruno Medeiros (13/36) Jul 29 2006 Ok, I now realize they are subtly different: although the value is the
- Jarrett Billingsley (18/23) Jul 29 2006 Hm.
- Stewart Gordon (17/28) Jul 30 2006 I discovered quite recently that C supports such oddities as
- Bruno Medeiros (9/34) Jul 30 2006 I've quite recently discovered that D supports that as well!
- Stewart Gordon (15/30) Aug 01 2006 Can anyone think of a use case for this? I can't. Just declare a
- Jarrett Billingsley (6/10) Aug 01 2006 Don't get so worked up about it. It'd probably be more complex to add i...
- BCS (6/28) Jul 27 2006 It gets worse. If foo is overloaded, then DMD silently grabs the
- Jarrett Billingsley (18/23) Jul 27 2006 That is ugly. In fact, I even came up with a solution for it in my
- BCS (18/42) Jul 27 2006 Nice. Looks a bit odd though, I'll have to think on that.
- Jarrett Billingsley (16/31) Jul 27 2006 Actually, thinking about it, the & wouldn't even be necessary. The over...
- BCS (31/51) Jul 27 2006 I'd leave it. It would be more consistant.
- Jarrett Billingsley (11/23) Jul 27 2006 I think we could just skip the "&ident" form and make it required to use...
Did properties stop working? assuming object abc has a method foo: gives a compiler error: x cannot be a function (or something like that) If I change it to the following instead: it works fine. Here's an example: -------- class ABC { int foo() { return 10; } } void main() { auto abc = new ABC(); auto x = abc.foo; } ----------- compiler message: main.d(9): variable main.main.x cannot be declared to be a function Like I said, if I add the brackets, it works fine: ----------- class ABC { int foo() { return 10; } } void main() { auto abc = new ABC(); auto x = abc.foo(); } --------- I'm suspecting this could be a bug or something, maybe due to the new delegate syntax. If I change auto to int then it also works --------- class ABC { int foo() { return 10; } } void main() { auto abc = new ABC(); int x = abc.foo; } --------
Jul 25 2006
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:ea6fsm$2lb6$1 digitaldaemon.com...Did properties stop working? assuming object abc has a method foo: gives a compiler error: x cannot be a function (or something like that)Stop using type inference. ;) int x = abc.foo; When you write "abc.foo" as the initializer for a type-inferenced declaration, it tries to deduce the type of the declaration before converting the property access to a function call. Thus, it thinks you're trying to create a variable x with the same type as abc.foo; i.e. a function type (not a function pointer, just a function), which is illegal. This might be a bug, but it's been around for a while, and not just since 0.163.
Jul 25 2006
Jarrett Billingsley wrote:"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:ea6fsm$2lb6$1 digitaldaemon.com...Function types are just bizarre. I only recently discovered that C has them. Are you allowed to do anything with them, other than converting them to a function pointer by taking their address?Did properties stop working? assuming object abc has a method foo: gives a compiler error: x cannot be a function (or something like that)Stop using type inference. ;) int x = abc.foo; When you write "abc.foo" as the initializer for a type-inferenced declaration, it tries to deduce the type of the declaration before converting the property access to a function call. Thus, it thinks you're trying to create a variable x with the same type as abc.foo; i.e. a function type (not a function pointer, just a function), which is illegal. This might be a bug, but it's been around for a while, and not just since 0.163.
Jul 27 2006
"Don Clugston" <dac nospam.com.au> wrote in message news:eaajnj$1mo4$1 digitaldaemon.com...Function types are just bizarre. I only recently discovered that C has them. Are you allowed to do anything with them, other than converting them to a function pointer by taking their address?I think they're mostly a "convenience" type for the compiler. Most of the time it's so hard to actually get a function type that I don't know what you'd do with it. I mean, you can't create variables of a function type; the only way you can do it is by declaring a function.
Jul 27 2006
Don Clugston wrote:Jarrett Billingsley wrote:C has them? Where did you see that, I was under the impression that C only had function pointers, and they were all the same, such that the value a function was the same as the value of taking the address of the function: (func) == (&func) Similarly to what happens to arrays. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:ea6fsm$2lb6$1 digitaldaemon.com...Function types are just bizarre. I only recently discovered that C has them. Are you allowed to do anything with them, other than converting them to a function pointer by taking their address?Did properties stop working? assuming object abc has a method foo: gives a compiler error: x cannot be a function (or something like that)Stop using type inference. ;) int x = abc.foo; When you write "abc.foo" as the initializer for a type-inferenced declaration, it tries to deduce the type of the declaration before converting the property access to a function call. Thus, it thinks you're trying to create a variable x with the same type as abc.foo; i.e. a function type (not a function pointer, just a function), which is illegal. This might be a bug, but it's been around for a while, and not just since 0.163.
Jul 27 2006
"Bruno Medeiros" <brunodomedeirosATgmail SPAM.com> wrote in message news:eabhs0$2kkr$1 digitaldaemon.com...C has them? Where did you see that, I was under the impression that C only had function pointers, and they were all the same, such that the value a function was the same as the value of taking the address of the function: (func) == (&func)I'm not sure, but I think that skipping the & on getting a function pointer in C is an "extension", or part of the newest standard that not all compilers support. Function types are allowed in C; you can't have an array of functions.Similarly to what happens to arrays.Mm? I thought char x[]; x is char* &x is char**
Jul 27 2006
Jarrett Billingsley wrote:"Bruno Medeiros" <brunodomedeirosATgmail SPAM.com> wrote in message news:eabhs0$2kkr$1 digitaldaemon.com...Ok, I now realize they are subtly different: although the value is the same ( func) == (&func) ) , one can "&" a "func" but can't "&" a "&func" (ie, one can't indefinitely use operator "&") , so that's a small difference. :pC has them? Where did you see that, I was under the impression that C only had function pointers, and they were all the same, such that the value a function was the same as the value of taking the address of the function: (func) == (&func)I'm not sure, but I think that skipping the & on getting a function pointer in C is an "extension", or part of the newest standard that not all compilers support.Nope, I think it's there since K&R ANSI C, although I don't have the book here with me to confirm.Function types are allowed in C; you can't have an array of functions."char x[];" is not valid C. "char x[]" is only valid when there is an array initializer "char x[] = {...};", or as a function parameter type, but in this latter case it is not an array, it is a char pointer (char*). -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DSimilarly to what happens to arrays.Mm? I thought char x[]; x is char* &x is char**
Jul 29 2006
"Bruno Medeiros" <brunodomedeirosATgmail SPAM.com> wrote in message news:eafnr8$e4c$1 digitaldaemon.com...Nope, I think it's there since K&R ANSI C, although I don't have the book here with me to confirm.Hm."char x[];" is not valid C. "char x[]" is only valid when there is an array initializer "char x[] = {...};", or as a function parameter type, but in this latter case it is not an array, it is a char pointer (char*).Oh that's right; in C[++], arrays and pointers _are_ separate types, it's just that when you pass an array into a function, the type info is lost and it just becomes a pointer. That's why: char x[] = "hello"; printf("%d", sizeof(x)); Prints 6 (length of string + null char), but void fork(char x[]) // old-fashioned, same as "char* x" { printf("%d", sizeof(x)); } .. char x[] = "hello"; fork(x); prints 4 (the size of a char*). This is why I like D. Arrays are actually first-class types.
Jul 29 2006
Bruno Medeiros wrote:Don Clugston wrote:<snip>I discovered quite recently that C supports such oddities as typedef int qwert(char*); (if I've got the syntax right), thereby defining qwert to be an alias for a function of type int(char*). I've seen it in the LAM MPI headers. But as you say, it seems useless - AFAIK the only thing you can do with it is declare something of type pointer to qwert. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.Function types are just bizarre. I only recently discovered that C has them. Are you allowed to do anything with them, other than converting them to a function pointer by taking their address?C has them? Where did you see that, I was under the impression that C only had function pointers, and they were all the same, such that the value a function was the same as the value of taking the address of the function: (func) == (&func) Similarly to what happens to arrays.
Jul 30 2006
Stewart Gordon wrote:Bruno Medeiros wrote:I've quite recently discovered that D supports that as well! -> http://d.puremagic.com/issues/show_bug.cgi?id=270 But ah... there is a use for such a typedef after all. I thought they could not be used in declarations at all, but forgot about declaring a pointer to it. But still I don't know if they are worth the strange syntax. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DDon Clugston wrote:<snip>I discovered quite recently that C supports such oddities as typedef int qwert(char*); (if I've got the syntax right), thereby defining qwert to be an alias for a function of type int(char*). I've seen it in the LAM MPI headers. But as you say, it seems useless - AFAIK the only thing you can do with it is declare something of type pointer to qwert. Stewart.Function types are just bizarre. I only recently discovered that C has them. Are you allowed to do anything with them, other than converting them to a function pointer by taking their address?C has them? Where did you see that, I was under the impression that C only had function pointers, and they were all the same, such that the value a function was the same as the value of taking the address of the function: (func) == (&func) Similarly to what happens to arrays.
Jul 30 2006
Bruno Medeiros wrote:Stewart Gordon wrote:<snip>Can anyone think of a use case for this? I can't. Just declare a typedef or alias of the function pointer type and be done with it. UIMS there is nothing to be gained, besides empty complexity, by trying to support such things. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.I discovered quite recently that C supports such oddities as typedef int qwert(char*); (if I've got the syntax right), thereby defining qwert to be an alias for a function of type int(char*). I've seen it in the LAM MPI headers. But as you say, it seems useless - AFAIK the only thing you can do with it is declare something of type pointer to qwert.I've quite recently discovered that D supports that as well! -> http://d.puremagic.com/issues/show_bug.cgi?id=270 But ah... there is a use for such a typedef after all. I thought they could not be used in declarations at all, but forgot about declaring a pointer to it. But still I don't know if they are worth the strange syntax.
Aug 01 2006
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:eaoc0i$309e$2 digitaldaemon.com...Can anyone think of a use case for this? I can't. Just declare a typedef or alias of the function pointer type and be done with it. UIMS there is nothing to be gained, besides empty complexity, by trying to support such things.Don't get so worked up about it. It'd probably be more complex to add in checking to make sure that you don't try to create an alias/typedef to a function type. And there's already checking in place to make sure that you don't use function types incorrectly.
Aug 01 2006
Jarrett Billingsley wrote:"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:ea6fsm$2lb6$1 digitaldaemon.com...It gets worse. If foo is overloaded, then DMD silently grabs the lexically first version and uses it. This is in direct contradiction of the idea that lexical order of functions/classes/etc. should not effect semantics. (I seem to recall that this is one of the goals of D, but I can't find the reference).Did properties stop working? assuming object abc has a method foo: gives a compiler error: x cannot be a function (or something like that)Stop using type inference. ;) int x = abc.foo; When you write "abc.foo" as the initializer for a type-inferenced declaration, it tries to deduce the type of the declaration before converting the property access to a function call. Thus, it thinks you're trying to create a variable x with the same type as abc.foo; i.e. a function type (not a function pointer, just a function), which is illegal. This might be a bug, but it's been around for a while, and not just since 0.163.
Jul 27 2006
"BCS" <BCS pathlink.com> wrote in message news:eaarq2$1h47$1 digitaldaemon.com...It gets worse. If foo is overloaded, then DMD silently grabs the lexically first version and uses it. This is in direct contradiction of the idea that lexical order of functions/classes/etc. should not effect semantics. (I seem to recall that this is one of the goals of D, but I can't find the reference).That is ugly. In fact, I even came up with a solution for it in my scripting language (before it was dynamically typed): an "overload resolution expression." It goes like this: void foo(int x) { } void foo(float x) { } &foo // ambiguous &foo.(int) // foo(int) overload &foo.(float) // foo(float) overload The dot is in there so that the parser doesn't interpret it as a function call. And as far as I know, there is no other syntax that allows the ".(" sequence.
Jul 27 2006
Jarrett Billingsley wrote:"BCS" <BCS pathlink.com> wrote in message news:eaarq2$1h47$1 digitaldaemon.com...[...]It gets worse. If foo is overloaded, then DMD silently grabs the lexically first version and uses it. This is in direct contradiction of the idea that lexical order of functions/classes/etc. should not effect semantics. (I seem to recall that this is one of the goals of D, but I can't find the reference).That is ugly. In fact, I even came up with a solution for it in my scripting language (before it was dynamically typed): an "overload resolution expression."&foo // ambiguous &foo.(int) // foo(int) overload &foo.(float) // foo(float) overload The dot is in there so that the parser doesn't interpret it as a function call. And as far as I know, there is no other syntax that allows the ".(" sequence.Nice. Looks a bit odd though, I'll have to think on that. Does D allow taking the address of a return value? Seems to me that could be used to disambiguate the resolution version from the function call version. I'm not sure how this would effect the context free aspect of the syntax. Alternately the [ Identifier "(" Type ] sequence shouldn't ever show up where a function call would be. This, however, still leave a problem with the "function taking void" type. humm byte foo(int); char foo(float); int foo(); auto a = foo(); // a is int auto b = &foo; // ambiguous auto c = &foo(int); // a is byte function(int) auto d = &foo(); // address of return | address of foo(/*void*/) auto e = &foo(void); // inconsistent but unambiguous
Jul 27 2006
"BCS" <BCS pathlink.com> wrote in message news:eab6vo$1h47$4 digitaldaemon.com...Does D allow taking the address of a return value? Seems to me that could be used to disambiguate the resolution version from the function call version. I'm not sure how this would effect the context free aspect of the syntax. Alternately the [ Identifier "(" Type ] sequence shouldn't ever show up where a function call would be. This, however, still leave a problem with the "function taking void" type. humm byte foo(int); char foo(float); int foo(); auto a = foo(); // a is int auto b = &foo; // ambiguous auto c = &foo(int); // a is byte function(int) auto d = &foo(); // address of return | address of foo(/*void*/) auto e = &foo(void); // inconsistent but unambiguousActually, thinking about it, the & wouldn't even be necessary. The overload resolution expression would simply return a function pointer. Then there wouldn't be any ambiguity of whether you're getting the function address or the address of the return value. auto a = foo(); auto b = &foo; // ambiguous auto c = foo.(int); // c is byte function(int) (or byte(int)*, as typeid call it) auto d = foo.(); // d is address of foo(); auto e = foo.(float); No need for foo.(void), which is good because you can't declare a function to take (void) as its arguments in D. And if you're right about the ident(type never showing up where a function call should, the dot might just be unnecessary.
Jul 27 2006
Jarrett Billingsley wrote:Actually, thinking about it, the & wouldn't even be necessary. The overload resolution expression would simply return a function pointer.I'd leave it. It would be more consistant. FunctionPointer ::= "&" FunctionSpecifier; FunctionSpecifier ::= FunctionIdentifier [ OverloadResolver ] OverloadResolver ::= ["." "(" TypeList ")" ] vs. // "&" befor OR resolver after, Hmmm. FunctionPointer ::= "&" FunctionIdentifier | FunctionIdentifier OverloadResolver; OverloadResolver ::= ["." "(" TypeList ")" ] (I don't think that the type of a ID is known at the syntax pass, but this illustrates the point)Then there wouldn't be any ambiguity of whether you're getting the function address or the address of the return value.It would still leave that problem. And I wouldn't count on address-of-returns being invalid. If const references get in, then a const reference to a return value might be handy (see below). I'll have to think some more on that one. // try something until sentinel is false; void fig(bool *const sentinel); bool quit; bool Quit(){return quit;} ... bool local; passToAnotherThread(&local); fig(&local); // time out from another thread quit = true; fig(&Quit()); // no timeout; quit = false; fig(&Quit()); // no blocking;auto a = foo(); auto b = &foo; // ambiguous auto c = foo.(int); // c is byte function(int) (or byte(int)*, as typeid call it) auto d = foo.(); // d is address of foo(); auto e = foo.(float); No need for foo.(void), which is good because you can't declare a function to take (void) as its arguments in D. And if you're right about the ident(type never showing up where a function call should, the dot might just be unnecessary.Thinking about it the "Ident . ( Types )" syntax looks good.
Jul 27 2006
"BCS" <BCS pathlink.com> wrote in message news:eabg5b$1h47$6 digitaldaemon.com...I'd leave it. It would be more consistant. FunctionPointer ::= "&" FunctionSpecifier; FunctionSpecifier ::= FunctionIdentifier [ OverloadResolver ] OverloadResolver ::= ["." "(" TypeList ")" ] vs. // "&" befor OR resolver after, Hmmm. FunctionPointer ::= "&" FunctionIdentifier | FunctionIdentifier OverloadResolver; OverloadResolver ::= ["." "(" TypeList ")" ]I think we could just skip the "&ident" form and make it required to use the "ident.()" form instead. So the only way to get a function pointer would be to use the overload resolve exp.It would still leave that problem.Ah, I see; yeah, there'd be the problem if the "&ident" form were allowed, since it could be a property call (damn D "properties"). Get rid of that, though, and there's _no_ ambiguity ;)Thinking about it the "Ident . ( Types )" syntax looks good.My rationale for it was that it's kind of selecting a member. "ident" declares a sort of namespace of functions with the same name, and you select the correct overload as if it were a member of that namespace.
Jul 27 2006