August 03, 2009
On Mon, 03 Aug 2009 11:06:53 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> That is, split as a property is an adjective, meaning "give me this data in a split form" , and as an adjective, split means "split this data", the result of which is the split data.

Oops, that second part of the sentence should read split as a *verb*.

-Steve
August 03, 2009

Steven Schveighoffer wrote:
> ...
> 
> The only issue with this is if the type returned from the getter actually defines a get field or method.  While having a method called get might be a likely possibility, having that on a type that is likely to be returned as a property is probably unlikely. There is of course a workaround:
> 
> ...
> 
> -Steve

Or you could just use __traits and avoid having to invent increasingly obtuse layers of syntax.
August 03, 2009
On Mon, 03 Aug 2009 11:24:54 -0400, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>
> Steven Schveighoffer wrote:
>> ...
>>
>> The only issue with this is if the type returned from the getter
>> actually defines a get field or method.  While having a method called
>> get might be a likely possibility, having that on a type that is likely
>> to be returned as a property is probably unlikely. There is of course a
>> workaround:
>>
>> ...
>>
>> -Steve
>
> Or you could just use __traits and avoid having to invent increasingly
> obtuse layers of syntax.

Yes.  As I said elsewhere, this has my vote.

-Steve
August 03, 2009
On 2009-08-03 11:03:54 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Now that I think of it, even if properties don't readily return delegates, they are trivially easy to obtain:
> 
> class A
> {
>      ... define property foo with whatever syntax ...
> }
> 
> unittest
> {
>      auto a = new A;
>      auto getter = () { return a.foo; }
>      auto setter = (int x) { a.foo = x; }
>      setter(5);
>      writeln(getter());
> }
> 
> I actually compiled and ran that with foo defined as a regular field.

They're indeed very easy to obtain, and using this method improves compatibility with regular fields, so it's great.

That said, can you see the property through reflection?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

August 03, 2009
On 2009-08-03 10:06:23 -0400, "Robert Jacques" <sandford@jhu.edu> said:

> On Mon, 03 Aug 2009 00:27:45 -0400, Nick Sabalausky <a@a.a> wrote:
> 
>> "Robert Jacques" <sandford@jhu.edu> wrote in message
>> news:op.ux2gvcvi26stm6@sandford.myhome.westell.com...
>>> 
>>> I agree 1) is an issue, but I view it as a corner case. (I use zero/one
>>> arg functions all the time and make use of the 'property' syntax left
>>> right and center, but I've never run into the opCall problem) It would  be
>>> nice if it were fixed, but we may be cutting off the nose to spite the
>>> face, as it were. (Or alternatively, taking the scientific instead of
>>> engineering approach)
>>> 
>> 
>> It'll become a major PITA when D gets used for heavy functional-style  stuff.
> 
> Maybe. But how often will people return zero-argument opCalls (function  pointers/delegates/structs) from zero-argument functions? (i.e. how often  do you run into this today?)

The compiler isn't as smart as you think. This doesn't compile, it requires an empty pair of parenthesis:

	void delegate(int) func();

	func(1);

And I somewhat doubt it should be smart enough for this, because if you then add a overloaded function "func" that takes an int you're silently chaning the meaning of the code.

Solve this for fun:

	void delegate() func(int);
	void delegate(int) func();

	func(1); // which one?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

August 03, 2009
On 2009-08-03 10:39:17 -0400, "Robert Jacques" <sandford@jhu.edu> said:

> Thank you for the very elegant expression of the problem and for posting  the programming guidelines wiki. My criticism is that you're defining your  context to narrowly. A function/property/field isn't just defined by it's  name, but also by it's type and the context it's in. A 'transform' of type  void or typeof(this) is obviously an action, while a 'transform' of type  Matrix might be a coordinate frame. The object's type also conveys context  information; a 'transform' on an autobot might be an action, while a  'transform' on it's 3D model might be a coordinate frame. Even if you  don't know the return type off the top of you're head (i.e. you're doing a  code review), 'transform;' or 'object.transform;' are obviously actions  while 'auto a = object.transform;' or 'object.transform = a' is a noun.  English solves it language ambiguity issues with context, so why can't the  same solution apply to programming languages? Sure, pathological examples  are possible, just as they're possible in English, but that's no reason to  switch to a different language.

Interesting remark. You're right of course about the transform example is much clearer in context. I'll conceed that point. But take note you let the user of the API do the disambiguation instead of the designer who wrote the function in the first place. I believe the later is better placed to decide. That said, it's rather a minor point in my opinion.

I'm more concerned by the ambiguity when returning callable objects or delegates when functions have omittable parentheses.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

August 03, 2009
Mon, 03 Aug 2009 11:06:53 -0400, Steven Schveighoffer wrote:

> I just thought of another issue with property definitions.  How do you declare a property of an array?  Today it's:
> 
> char[] chomped(char[] input);
> 
> Note that any getter property contains an argument which is the object you're calling the property on (normally implied because the definition is inside an aggregate definition).  But with arrays it's explicit.
> 
> So how does this fit in Walter's proposed syntax?
> 
> char[] chomped {...}
> 
> Where does the input go?

I proposed a keyword, 'inject', a year ago.  Or it could be an annotation.  I suppose such a keyword might significantly simplify implmentation of external functions and properties:

@inject @property char[] chomped(char[] arr) {...}
@inject void sort!(alias pred, T)(T[] arr) {...}

Though prepending 'this' to the first parameter may also work, C# style.
August 04, 2009
On Mon, 03 Aug 2009 11:42:51 -0400, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2009-08-03 10:06:23 -0400, "Robert Jacques" <sandford@jhu.edu> said:
>
>> On Mon, 03 Aug 2009 00:27:45 -0400, Nick Sabalausky <a@a.a> wrote:
>>
>>> "Robert Jacques" <sandford@jhu.edu> wrote in message
>>> news:op.ux2gvcvi26stm6@sandford.myhome.westell.com...
>>>>  I agree 1) is an issue, but I view it as a corner case. (I use zero/one
>>>> arg functions all the time and make use of the 'property' syntax left
>>>> right and center, but I've never run into the opCall problem) It would  be
>>>> nice if it were fixed, but we may be cutting off the nose to spite the
>>>> face, as it were. (Or alternatively, taking the scientific instead of
>>>> engineering approach)
>>>>
>>>  It'll become a major PITA when D gets used for heavy functional-style  stuff.
>>  Maybe. But how often will people return zero-argument opCalls (function  pointers/delegates/structs) from zero-argument functions? (i.e. how often  do you run into this today?)
>
> The compiler isn't as smart as you think. This doesn't compile, it requires an empty pair of parenthesis:
>
> 	void delegate(int) func();
>
> 	func(1);
>
> And I somewhat doubt it should be smart enough for this, because if you then add a overloaded function "func" that takes an int you're silently chaning the meaning of the code.
>
> Solve this for fun:
>
> 	void delegate() func(int);
> 	void delegate(int) func();
>
> 	func(1); // which one?
>

Ah. Thank you for the informative post. That is a fairly big deficiency. However, isn't that really a bug? There's a similar one with ref return properties. According to the spec, there's nothing (I think) preventing DMD from doing the right thing.

As for your example, 'void delegate() func(int);' would end up being called. But it's pretty obvious 'void delegate(int) func();' was meant. This particular example looks very pathological, if both funcs are part of the same module. Ultimately, this is just another form of function hijacking. Detecting this would require all combinations of call variations to enter into the lookup tree, but from there it's trivial to detect a collision, and issue an error. That would work for both out of module and in module double definitions. I don't know how difficult that is for the compiler, but it sounds fairly straight-forward.
August 04, 2009
On Mon, 03 Aug 2009 11:57:40 -0400, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2009-08-03 10:39:17 -0400, "Robert Jacques" <sandford@jhu.edu> said:
>
>> Thank you for the very elegant expression of the problem and for posting  the programming guidelines wiki. My criticism is that you're defining your  context to narrowly. A function/property/field isn't just defined by it's  name, but also by it's type and the context it's in. A 'transform' of type  void or typeof(this) is obviously an action, while a 'transform' of type  Matrix might be a coordinate frame. The object's type also conveys context  information; a 'transform' on an autobot might be an action, while a  'transform' on it's 3D model might be a coordinate frame. Even if you  don't know the return type off the top of you're head (i.e. you're doing a  code review), 'transform;' or 'object.transform;' are obviously actions  while 'auto a = object.transform;' or 'object.transform = a' is a noun.  English solves it language ambiguity issues with context, so why can't the  same solution apply to programming languages? Sure, pathological examples  are possible, just as they're possible in English, but that's no reason to  switch to a different language.
>
> Interesting remark. You're right of course about the transform example is much clearer in context. I'll conceed that point. But take note you let the user of the API do the disambiguation instead of the designer who wrote the function in the first place. I believe the later is better placed to decide. That said, it's rather a minor point in my opinion.
>
> I'm more concerned by the ambiguity when returning callable objects or delegates when functions have omittable parentheses.
>

I believe in a systems language, the default should be to user choice. That said, having a way for an api designer to enforce a particular usage, isn't necessarily bad thing either. The lack of an either-or/flexible option is, in my opinion, a flaw in all of the proposals so far.
August 04, 2009
Andrei Alexandrescu wrote:
> Michiel Helvensteijn wrote:
>> void empty.set(bool value) { ... }
>> bool empty.get() { ... }
>>
>> and have the same meaning as my earlier example.
> 
> Yah, I was thinking the same. This is my #1 fave so far.
> 
> Andrei

Agreed!

I see the appeal of putting getter/setter pairs within a single pair of braces, since it groups them together as one logical unit.

BUT...

I think it's more valuable to define them as completely separate, since you sometimes want to define get/set properties with different access modifiers (protected setter & public getter == very nice). And then the brace-enclosed syntax looks kinda goofy to my eyes:

   property MyProperty int {
      public get; protected set; // WEIRD
   }


--benji