Properties

Nick Sabalausky a at a.a
Sat Jan 10 20:59:29 PST 2009


"Miles" <_______ at _______.____> wrote in message 
news:gkbk5p$14gr$1 at digitalmars.com...
>
> So, what is "better" about properties is not shorter syntax, but giving
> proper semantics for a given symbol.
>

I'd say the point of properties is both a matter of clean implementation 
syntax and proper calling semantics/syntax. In the case of the calling 
semantics/syntax, I see it as essentially boiling down to an issue of "nouns 
vs verbs" and proper abstraction.

The way I see it: Variables are the programming world's nouns, and functions 
are the programming world's verbs. Objects (nouns) have attributes (nouns) 
and are capable of doing things (verbs). Thus, things that are noun-like and 
can be thought of as an attribute of an object should be accessed using 
noun/variable syntax (this means no parentheses), and things that are 
conceptualized as actions the object can perform should be invoked using 
verb/function syntax (this means parentheses). Although if you're merely 
*referring* to a verb/function (as in the phrase "the act of walking"), then 
you're using the verb as a noun and should refer to the verb with the 
standard noun syntax (no parens).

Example of proper design strategy:
We want to programmatically represent the noun of "color". First thing we 
need is a type. There's no built-in, so we need to define a custom type, a 
class. Next thing we need is a list of attributes and actions associated 
with "color":

Actions (things color can do):
Color isn't a physical object so there's not much it can actually do:
- Inspire an Artist (Artist being the grammatical "direct object", and 
therefore the parameter)

Attributes (things color has):
- Hue
- Saturation
- Brightness/Darkness
- Red component
- Green component
- Blue component
- Yellow component
- Cyan component
- Magenta component
- Transparency/Opaqueness
- Shininess
- etc...

Now to translate into (psuedo)code:

void inspire(Artist artist) { /* magic code here */ }
val hue;
val saturation;
val blackness;
val red;
val green;
val blue;
val yellow;
val cyan;
val magenta;
val transparency
val shininess;
("val", of course, being a type representing the range of "max".."min")

Now at this point any sane programmer would see the redundancy (and 
potential for invalid, self-contradicting state) in storing HSV, RGB, *and* 
CMYK. They'd then probably choose a single internal format (we'll say RGB), 
and decide to calculate all of the redundant attributes from that. This is 
good design.

But here's the part where many people go wrong. They say "Since I'm 
calculating HSVCM and Y, that means 'function'" (And yes, it does mean 
"function", but only on the *implementation* side.) Then they do something 
like this:

val getHue();
val getSaturation();
val getBlackness();
val red; // Might be changed to getRed() for consistency
val green;
val blue;
val getYellow();
val getCyan();
val getMagenta();

Bad programmer! Bad, bad, bad programmer! Hue and Yellow aren't actions of 
color, they're attributes! Nouns, nouns, nouns! Turning them into verbs by 
sticking "get" in front just made a bastardized mockery out of 
high-level-language abstraction. Not only that but the implementation detail 
of "some of these are calculated instead of stored internally" has leaked 
out into the interface and slapped the idea of encapsulation in the face.

At this point, D comes in and tries to solve the problem with omittable 
parens on functions. But that puts the onus on the caller. So what, the 
caller is now supposed to be defining the interface? That's dumb because the 
author of the class has already decided whether a particular member is a 
noun or a verb by naming it "red" instead of "getRed" or vice versa.

If you've got something like "red component" that is conceptually understood 
as a noun, it should be accessed with noun syntax. Call it "good redundancy" 
(*nudge* *nudge* Walter?). Whether or not the class author decides to 
*implement* it as a computation or a simple memory access should not impact 
accessing it. As it is now, whenever a conceptual attribute is switched 
between variable and "property", the legality of sticking () on the end of 
it flip-flops. How is that desirable behavior? 





More information about the Digitalmars-d mailing list