OT: Properties, was RAII, value classes and implicit conversion

Chad J gamerChad at _spamIsBad_gmail.com
Wed Nov 15 14:12:52 PST 2006


Boris Kolar wrote:
> == Quote from Chad J (gamerChad at _spamIsBad_gmail.com)'s article
> 
>>Reason #1: delegate ambiguity ...
> 
> 
> You're right, but it seems to me that your example is more of a hypothetical
> problem than a practical one. Not sold on reason #1 ;)
> 

It's practical, I've been bitten by it.  Otherwise I probably would have 
never thought about it.

> 
>>Reason #2:
>>No op*Assign.  This is why we have to type
>>array.length = array.length + 1;
>>instead of
>>array.length++;
> 
> 
> That convinced me. I remember now that I have stumbled on this problem
> as well. Still, a smart compiler might allow array.length++.
> 

A smart compiler won't save this.  That's because it will make the 
language depend on Quality Of Implementation (QOI).  If one were to 
write code while using said smart compiler, then the code gets moved to 
a 'dumb' compiler, the code will break if array.length++; was ever used. 
  This trashes the ability to easily port code between compilers.

> 
>>Reason #3:
>>It's one more possible way to write code that just doesn't make sense.
>>I suppose this isn't too bad since programmers tend to shoot for
>>clarity, but I've run into it.
>>writefln = sqrt = 4.0f; // what?!?
> 
> 
> That's a good one :) Never thought of that. Although it's merely a bad
> style - I always assume there are already infinite number of ways to
> write program in a cryptic style.
> 
> 
>>Well that's my case.  Could you explain why you prefer D-style
>>properties, please?  I'd like to know if there are any significant
>>advantages to having it this way.
> 
> 
> Well, I could never decide if a something is just a parameterless
> function, a property, or a field. In D, it's all used the same way.
> 
> You can, for example, build an early prototype by using a field and
> then turn it into a property (that, for example, logs every call).
> 

You would be able to do that with C# syntax too.  You just wouldn't be 
able to call it like a function.

IMO, calling a field is nonsensicle.  It's right alongside assigning to 
a function/method.

> Also, I like the fact that writing the parameterless function is
> exactly as verbose (not less, as in C#) than writing a read-only
> property.
> 

Maybe C# properties aren't perfect :)  Perhaps we can work on this...

> Also, Eiffel and Wikipedia make some convincing arguments:
> http://www.eiffel.com/general/monthly_column/2005/Sept_October.html
> http://en.wikipedia.org/wiki/Uniform_access_principle

I think that D fails to acheive UAP with the current property syntax.

foo.bar++; // implies field.

This betrays whether bar is implemented through storage or computation - 
it is implied that bar is implemented through storage.
I'm going to venture an educated guess that Eiffel does not have such 
opOperateApply type operators.  Ditch the ++, --, +=, -=, *=, etc. and 
UAP is restored.

Also:

int a = foo.bar(); // implies method

Now we know that bar is implemented through computation.

One important feature of UAP seems to be that it allows you to change 
the implementation of any object member without breaking code that uses 
that member.  D fails here, due to the above.  Indeed, this is the part 
I forgot to mention in my earlier post.  It is a corollary to Reason#2, 
and IMO a much more important reason to ditch the current syntax than 
having to write opOperateAssign the longhand way.

C# style syntax does break UAP as well, but I argue that it does not do 
so in a very damaging way.  Suppose you want to change a member from 
being a field, to being a method.  Why?  The reason I see is to add 
extra functionality to the field, as in logging, inheritance, program 
state update, etc.  Another would be to use fields and methods 
interchangably.  The former I find valuable, and C# accomplishes it. 
The latter I find nonsensicle in many cases (writefln = 2;), and C# 
prohibits it.  Now, suppose you want to change a member from being a 
method to being a field.  Why?  I see two reasons.  One is to reduce the 
code size of the method from small to slightly smaller (it was small 
already since you can reduce almost all functionality by simply writing 
func() { return m_val; }).  The other is to use fields and methods 
interchangably.  I don't see much value in the former, and am still 
opposed to the latter, so the fact that C# doesn't really support this 
is fine by me.

Another good argument leveled against C# style properties: too much 
keyword usage.  This shouldn't be too difficult to fix.

prop int getter()
{
	return myval;
}

prop void setter( int toAssign )
{
	myval = toAssign;
}

Now it has been reduced to one extra keyword, 'prop'.  Also, most of the 
current behaviour of D's properties is maintained.  Indeed, these may 
not necessarily even be in classes or structs, but also modules and 
functions and other scopes, as they can be nowadays.  It also seems to 
give the compiler all of the information it needs to determine usage in 
an easy and straightforward fashion.

There was also a suggestion to allow methods without parens

int foo
{
	return 5;
}

void main()
{
	writefln( foo ); // prints 5
}

No new keyword, but it breaks for setters.
hmmmm, maybe something like this for the setters:

private int m_assignable;
void foo[ int toAssign ]
{
	m_assignable = toAssign;
}

Or other possibilities:

void foo.( int toAssign ) {...}
void foo!{ int toAssign } {...}
void foo.{ int toAssign } {...}
void foo.[ int toAssign ] {...}
and so on...

Or perhaps the paren-less suggestion above, with an implicit variable 
defined like in variadic functions.  Let's call it _arg.  (perhaps it 
could be prettier?)

void foo
{
	m_assignable = _arg;
}

Perhaps it should be mandated in the above case that the function does 
not have a return type, in order to help the compiler tell at first 
glance that it is indeed a setter.

I'm sure there are many other possibilities, more than one of which are 
viable.



More information about the Digitalmars-d mailing list