Revised RFC on range design for D2

Steven Schveighoffer schveiguy at yahoo.com
Mon Sep 29 11:36:25 PDT 2008


"Andrei Alexandrescu" wrote
> Steven Schveighoffer wrote:
>> "Andrei Alexandrescu" wrote
>>> Steven Schveighoffer wrote:
>>>> "Andrei Alexandrescu" wrote
>>>>> Steven Schveighoffer wrote:
>>>>>> "Andrei Alexandrescu" wrote
>>>>>>>> P.S. If src.next() is too lengthy, why not just adopt ++src?
>>>>>>> Because people (in wake of the recently introduced array operations) 
>>>>>>> may legitimately expect that to mean "increment all elements of 
>>>>>>> src".
>>>>>> So in one case, you believe people's assumptions aren't important, 
>>>>>> i.e. an assumption that .next without parens will not change anything 
>>>>>> on the object, yet in another case you believe people's assumptions 
>>>>>> are the main argument. This doesn't sound consistent.
>>>>> Of course it is. One expectation has to do with operational 
>>>>> consistency (albeit a tad far-fetched), the other has to do with being 
>>>>> used to a mistaken decision in the C language design.
>>>> You are assuming that the C language decision to require parentheses 
>>>> for all functions was a design mistake.  I would argue that the design 
>>>> was on purpose and correctly served that purpose.  The purpose was to 
>>>> remove ambiguity when faced with understanding code without all the 
>>>> context.
>>> I have stated my assumption and its basis.
>>
>> Forgive me, but I must have missed it.  I saw only your assumption (or 
>> supposition) that the C designers made a mistake.
>
> My post on 25 Sep 2008 17:58:52 -0500 mentions:
>
> "One principle that I consider universal is that a language should 
> minimize the number of syntactic constructs that are semantically and/or 
> pragmatically meaningless. Another that I also consider universal is that 
> the more frequently-used constructs should be given syntactic priority 
> over the less-used constructs, particularly when the latter are also at 
> risk of breaking the first principle."

Hidden in this statement is that you consider () to be semantically 
meaningless.  I see it not as meaningless, but a distinction between what 
the symbol is supposed to represent.  A property should represent a value. 
A function should represent an action.

I'll also note that your basis/proof is not any more proof than mine ;)  You 
just made statements about what you believe, as did I.

>>> What is the basis of yours?
>>
>> I don't have any actual proof that they did this on purpose, I wasn't 
>> working at Bell labs when C was invented, in fact, I don't even think I 
>> was born ;)
>>
>> But it makes logical sense, and still does.  If you want to call a 
>> function, you have to use parentheses.  If you want to access the 
>> function address, no parentheses.
>
> This is no logic. Your proof is just stating the conclusion. It's a 
> logical fallacy called proof by assertion.

Sorry, change my statement to 'But it makes sense and still does'.  And I 
never said it was a proof.  It's a statement of my reasons behind believing 
the () decision was on purpose.

>> It follows other design decisions they made:
>>
>> pointers:  Access what it's pointing to, use ->, get address it's 
>> pointing to, use symbol alone.
>
> This is wrong too. If you use symbol alone, you are not getting its 
> address. You are referring the pointer, which is an address. It would have 
> been consistent with other design decisions if referring a variable alone 
> would take its address.

Not really.  A function symbol by itself is the address of the function.  A 
pointer symbol by itself is the address of the data it points to.  It's the 
same.  I don't think you understood the detail that I stated, 'get address 
it's pointing to', not 'get address of the pointer'.

>>>> But that isn't even the questioned practice here.  C designers didn't 
>>>> even come across the question of whether an accessor-property should 
>>>> imply no changes to the object, because they don't have properties. 
>>>> The real problem is that no matter how you define next(), you can use 
>>>> it in a way which makes it appear like an accessor, not a function 
>>>> which modifies the object.  The source of the problem is D's lack of 
>>>> expressiveness, where I cannot define whether a function cannot be used 
>>>> as a property.
>>> I understand your argument, but it hinges on its own definitions and 
>>> assumptions. You define "accessor" and then complain that something 
>>> looks like one unexpectedly. Well in some languages a.b does not change 
>>> anything. In others it does. What gives?
>>
>> There is no hard-fast rule that an accessor cannot change things.  The 
>> issue is that since any function can be an accessor you can't even try to 
>> adopt a policy in your library that says 'accessors will not change 
>> things'. Because you can't define which functions can be used as 
>> accessors and which ones can't.
>
> Const takes care of that.

If I state that 'all accessors used in my library will not change things,' 
then how can I enforce this?  I can't, if I ever want non-const methods that 
do not take arguments, because those methods could be called as properties.

>
>> I WANT a.b to be able to be a function call, I just want to specify which 
>> functions can be called that way, and which ones cannot, so I can define 
>> how my library behaves and someone reading code that uses it will know 
>> that my rules were followed.
>
> Why do you want to specify that? What difference does it make? Why would 
> you complicate the language just for a hypothetical convention that's not 
> even compiler-checked?

It allows for (in my opinion) better coding practices that are impossible 
today.  For one, if I restrict a member to being only accessed as a 
property, it is interchangable with a field later on.  I think there have 
already been many given instances where having a defined property makes it 
clearer, I'm not going to repeat them all.

>
>>>> Even with a true property definition syntax, you cannot prevent someone 
>>>> from changing an object while inside an accessor, that should be 
>>>> defined by the constancy of the object in question.  But indicating 
>>>> that it is preferred to use the property-style means to access the 
>>>> next() member function seems to be misleading to some people.
>>> So that further weakens your argument.
>>
>> How so?  I'm not talking about whether or not the compiler should 
>> restrict the developer on being able to make changes in accessors.  That 
>> is what const is for.  I'm talking about being able to specify a coding 
>> convention that says 'accessors shall not change things'.  Currently, 
>> there's no way to prevent any function from being used as an accessor, so 
>> a library developer cannot enforce this rule to people using his library.
>
> I personally think it's great that any function can be used as an 
> accessor. I'd be convinced otherwise presented a good arguments against 
> it. What problems are you foreseeing with not being able to enforce 
> against not using ()?

I have given good arguments.  You seem to dismiss them as failed proofs, but 
that is your call.

>>>> The problem I have with your argument is how you used one case to say 
>>>> 'this is misleading to people, so it's not a valid solution', and in 
>>>> another case say 'it's only misleading because you are used to it, that 
>>>> doesn't matter.' The assumption of which people are important to please 
>>>> is the issue.  I understand you can't please everyone, but you 
>>>> shouldn't use the 'people won't like it' argument without real evidence 
>>>> or proof.
>>> I agree that ++array may not be easily confused with ++array[]. The 
>>> situation I am trying to help is improve on a mistake in the C language 
>>> design that we got so used to, we actually think it's the right thing.
>>
>> According to comments on this newsgroup, and some quoted bug reports, 
>> many believe that it's the D methodology of not requiring parentheses 
>> that is a mistake.  As far as I can tell, it's a matter of opinion, not 
>> fact.
>>
>>>>>> Not that I care too much :)  I am also in the camp of 'defined 
>>>>>> properties should be a language feature,' but I admit to using 
>>>>>> D-properties quite often.
>>>>>>
>>>>>> The two things that bug me the most about D property syntax:
>>>>>>
>>>>>> stuff like this:
>>>>>>
>>>>>> x;
>>>>>>
>>>>>> What the hell does this mean?  It looks like it does nothing.  But it 
>>>>>> could be a function call.  If explicit properties were required, and 
>>>>>> x was defined as a function, not a property, then x; would be a 
>>>>>> syntax error.
>>>>> And what would be the advantage? I routinely use writeln; without 
>>>>> feeling it makes for inferior style.
>>>> The advantage is not to you, it is to the reader of your code. 
>>>> writeln; is a complete misuse of property syntax, and IMO should not be 
>>>> allowed. writeln is not a property, and shouldn't be used like a 
>>>> property.
>>> Aside from just saying it, do you have any substantive argument?
>>
>> The arguments have been made.   As I stated, it's my opinion.
>>
>>>> I routinely use Tango's Stdout.newline; which I admit goes against what 
>>>> I am saying, but it's because I know what Stdout.newline does, and that 
>>>> it is a function.  I would gladly change everything to Stdout.newline() 
>>>> if it was required.
>>> To what benefit? You seem to be using it today, and that makes your own 
>>> style incongruent with your argument, yet surely you'd change the style 
>>> in an iffy if you thought it has serious drawbacks.
>>
>> The benefit is clarity.
>>
>> Stdout.newline;
>>
>> looks like a property or field of Stdout.  By itself, it's somewhat 
>> jarring, but it's somewhat clear that newline is a function if you know 
>> the rules of D.
>
> But you do use Stdout.newline and the alleged loss in clarity doesn't seem 
> to be phasing you.

It does phase me.  I sometimes catch myself doing it and add the 
parentheses.

>> However, something like this isn't so clear:
>>
>> Stdout.newline.formatln("Hi there {}", var);
>>
>> Is newline a property of Stdout, on which I'm calling formatln, or is 
>> newline a function that I'm calling, and then using the result of that 
>> function to call formatln?  Compare with:
>>
>> Stdout.newline().formatln("Hi there {}", var);
>>
>> There is no ambiguity.  newline is clearly a function, not a property.
>
> There is no ambiguity either case. You evaluate Stdout.newline. The 
> evaluation yields a value of some type. Then you evaluate formatln against 
> that value.

OK, then tell me what this does:

x.y.z();

Is y a property/field of x or a function call with no args?  I see a benefit 
to being able to understand a line of code without requiring lots of extra 
context.  I have to do less lookups of the source of a function or property.

> What's missing is the unstated assumption that "if it doesn't have 
> trailing parens, it must be a field". I don't think it is useful to be 
> making that assumption.

Not in D's current state, which leaves the reader to continually look up 
what a symbol is until he can hammer into his brain whether a symbol is a 
function or not.

>
>> My personal habits are ones I would like to change.  I'd prefer to write 
>> clearer code, not shorter code.  I consider writing Stdout.newline; a bad 
>> habit fostered by the lax function calling rules of D ;)
>
> Giving the choice of shorter vs. clearer is a false choice, another 
> fallacy if I remember correctly. Put another way, wouldn't you at best 
> write shorter and clearer code?

Sure, the shortest clear code I have seen is that with parentheses.  There 
is a point at which shorter becomes less clear, in which case the choice is 
required.  How is that a fallacy?

>>>> The problem is not that you or anyone might forget that writeln is a 
>>>> function and not a property, the problem is when you start using the 
>>>> property syntax to call functions that aren't so standard, someone 
>>>> reading the code will be confused as to what the code is supposed to 
>>>> do.
>>>>
>>>> The advantage is, you are able to define how a symbol behaves, what the 
>>>> rules are for using it.  It makes for clearer code.
>>> I am not sure.
>>
>> Neither answer is definitely the 'correct' one, there are tradeoffs 
>> between both styles.  I like the how D properties are so easy to write, 
>> and can be accessed like functions when needed, but I don't like how you 
>> can have weird looking code to have to decipher.  Having written 
>> properties in C# quite a bit, I prefer that method of requiring a formal 
>> property definition.
>
> I am not seeing weird code that is there to be deciphered. There is this 
> "writeln = 3" weirdness that I'd love to weed out, but all this required 
> trailing parens stuff simply doesn't have any good argument working in its 
> favor.

I think we're all in agreement about writeln = 3.  If this is the only thing 
that gets fixed, it would be a huge step.  I'd prefer full properties, but 
this at least makes things much clearer.

'simply doesn't have any good argument' is your opinion, not a fact.

-Steve 




More information about the Digitalmars-d-announce mailing list