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