Hello, I think the biggest part of our problem with @property is, that we are using the wrong words. I'm no native english speaker so it may be that i'm totaly wrong with this, but that's my impression. When i hear the word property i'm thinking: "ok, this is a well defined part of the internal state of that object instance that i'm allowed to interact with".
That's what i think a property is. It is not about parentheses or not parentheses. It is not about just marking functions to change their call behaviour. I think a property should be about *first* naming and defining a distinct part of the object state and thereafter *optionally* defining how to deal with it. I really don't want to talk much about syntax but i like the way Moose has solved this problem for Perl5. Even if its syntax is not compatible to a C derived language language like D (btw. why not?), a quick skim of its documentation may be a source of inspiration. It clearly was for me. http://search.cpan.org/~drolsky/Moose-0.94/lib/Moose.pm The coolest thing about Moose is, that it doesn't change the language of Perl5 in any way. For attributes (their name for properties) it just implements a declarative syntax that is valid perl code and executed at compile time to define fields and accessor functions. so a simple has 'x' => (is => 'rw', isa => 'Int'); just defines a field that can hold an integer and two accessor functions x() and x(int). The name of the real field and how it is stored is adjustable but defaults to the way perl objects are normaly constructed. has 'x' => (is => 'ro', isa => 'Int'); just omits constructing a write accessor. To be exact at this a readonly property doesn't mean it is const, it means that you don't have a write accessor and therefore can't substitute its content. You can get a mutable subobject or struct via a read accesseor and manipulate it via its own property accessors but you can't substitute it since you have no write accessor. If you don't want to let the client manipulate intenal state via a read accessor of a complex property just make it return a const subobject. Semantically this turns a property into a little sub-class even if it is not defined as such. It is implemented as old school fields and accessor functions. But they are auto generated until you feel the need to define them explicitly. There are much more ideas in Moose that may be applicable to D that i won't go any deeper in here. Please skim it's documentation if you're interested. For me it has turned Perl into something beautiful while being extremly flexible. But I don't want to advertise any Perl, just hoping the idees behind Moose can be helpful. So back to D. The simplest property definition i can think of ist this: class c { public: int a; } This can be interpreted as a property with name 'a' that has compiler generated accessor functions int a(), and a (int) or int a(int) .The compiler can not only auto generate them, it can also opimize them away. So at the end of the day a field can be seen as an optimized property. This implicates that i should be able to access fields using accessor function syntax. Yes, i really mean someting like x = c.a() or c.a( x) also for field access. Even auto old = c.a( x) may be usefull. I think this can be essential for templates or meta programming. Syntax like x = c.a or c.a = x is cute but should be rewritten to the above by the compiler and then optimized away in case of auto-generated accessors. The whole talk about using parentheses or not for accessor functions, just to better distinguish accessors from real fields when reading D sources i have a really simple solution for. Just conceptually get rid of real fields in objects. Then we don't have to distinguish. And if "int a;" in a class definition simply defines a lightweight rw property that internally is implemented by the compiler as a field, we get the benefits of real properties for each field without changing one line of already written source code. The danger of confusing field access with a function call omitting empty parentheses vanishes as well because every field access is now consequently a call of a property accessor even when optimized away. So function calls can safely omit empty parentheses without being ambigious. Then later we can think about creating a DSL that helps us to *declare* more complex types of properties and have the compiler construct the implicit parts at compile time. For instance i can think of a boolean property that has a toggle accessor. We shouldn't compose our classes from fields and functions that we declare to be called with or without parentheses. We should compose our classes from properties we declare (public, privat or whatever) and let the compiler do the boring work for us. Now to your problem with byLine: > > Some said it should be stdin.byLine(), some others said it should be stdin.byLine. They invoked contradictory rules that led to contradictory conclusions. If byLine internally constructs a new range instance that happens to use stdin for iterating by line, this to me ist clearly a function. And then the normal rules for calling a function in the D language must apply. This has nothing to do with properties. If you have a single ByLineRange instance stored in stdin that is simply handed out by the byLine function, than this can be seen as a getter function of a byLine property and *both* forms should be applicable. So, that is my opinion about properties. I hope it makes some sense to you or is helpful to anyone. -- Gerrit