Jump to page: 1 2
Thread overview
Properties no longer work?
Jul 26, 2006
Hasan Aljudy
Jul 27, 2006
Don Clugston
Jul 27, 2006
Bruno Medeiros
Jul 29, 2006
Bruno Medeiros
Jul 30, 2006
Stewart Gordon
Jul 31, 2006
Bruno Medeiros
Aug 01, 2006
Stewart Gordon
Jul 27, 2006
BCS
Jul 27, 2006
BCS
Jul 27, 2006
BCS
July 26, 2006
Did properties stop working?

assuming object abc has a method foo:
# auto x = abc.foo;
gives a compiler error: x cannot be a function (or something like that)

If I change it to the following instead:
# auto x = abc.foo();
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;
}
--------
July 26, 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:
> # auto x = abc.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.


July 27, 2006
Jarrett Billingsley wrote:
> "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:
>> # auto x = abc.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. 

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?
July 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.


July 27, 2006
Jarrett Billingsley wrote:
> "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:
>># auto x = abc.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. 
> 
> 

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).
July 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.


July 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
July 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 unambiguous

Actually, 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.


July 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.
July 27, 2006
Don Clugston wrote:
> Jarrett Billingsley wrote:
>> "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:
>>> # auto x = abc.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. 
> 
> 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.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
« First   ‹ Prev
1 2