June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 06/07/2011 11:59 PM, Jonathan M Davis wrote: > On 2011-06-07 23:43, Vladimir Panteleev wrote: >> // Old, C/C++-like syntax - I understand this is pending deprecation >> int a[3][4]; >> static assert(a.length == 3); >> static assert(a[0].length == 4); >> >> // New D syntax >> int[4][3] b; >> static assert(b.length == 3); >> static assert(b[0].length == 4); > > Declarations are read outward from the variable name. That's generally right- > to-left. The important word there is "generally". How can we say that there is any rule when right-to-left is only "generally"? > Putting the array dimensions on the right side results in it being > left-to-right, but that's not the norm. > > int* a; //A pointer to an int No. The type is int* (I read it as "int pointer"), and the variable name is a. I don't have to read it at one breath. > int** b; //A pointer to a pointer to an int. No. The type is int** (I read it consistently as "int pointer pointer"), and the variable name is b. > Left-to-right would end up being something more like this: > > a *int; > > or maybe > > *int a; > > The D syntax for static array sizes just underlines the fact that declarations > are generally read right-to-left because in that particular case, it's not > what people expect. I don't read them that way. Perhaps we should say that the English speakers may read right-to-left? Perhaps only when they need to understand a very complicated declaration? > Herb Sutter is positing that the syntax would be easier to > grok and result in fewer errors if it were all left-to-right instead of right- > to-left. D has left-to-right: Type on the left, variable on the right. Consistent. > Yes, there are a few cases where you end up with left-to-right in C- > based languages, because declarations are typically read outward from the > variable name, and if that includes stuff to the right of the variable name, > then that part is read left-to-right, but that's the exception. I can't remember such exceptions in D? (Well, 'alias this' comes to mind.) Multi-dimensional array declarations and function pointer declarations are corrected in D. That is consistent. > > - Jonathan M Davis Ali | |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 2011-06-08 00:54, Ali Çehreli wrote:
> On 06/07/2011 06:30 PM, Jonathan M Davis wrote:
> > On 2011-06-07 17:53, Andrej Mitrovic wrote:
> >> I'm not sure what he means when he says that D doesn't simplify syntax.
> >
> > He talked just before that about simplifying declaration syntax so
>
> that it
>
> > reads left-to-right instead of right-to-left, and D didn't do that.
>
> I don't think D could use right-to-left. Like this?:
>
> a int;
> p *int;
>
> That would be too strange for its heritage.
>
> > For
> > instance,
> >
> > int[4][3] a;
> >
> > declares a static array of length three where each element of that
>
> array is a
>
> > static array of length 4 where each of those arrays holds an integer.
>
> It's
>
> > read right-to-left
>
> Note that D's syntax fixes the horribly broken one of C. And contrary to popular belief, only some of C's syntax is right-to-left; notably, pointers to arrays and pointers to functions are outside-to-inside.
>
> I never read declarations from right to left. I doubt that anybody does that. "Code is not Literature". (I stole the title of tomorrow's Silicon Valley ACCU talk: http://accu.org/index.php/accu_branches/accu_usa/upcoming) Reading declarations from right-to-left is cute but there is no value in doing so. Besides, there are no "array of"s in that declaration at all. It is a coincidence that the C syntax can be read that way with the added "is a"s and "of"s.
>
> In D, type is on the left and the variable name is on the right:
>
> int i;
> int[4] array;
> int[4][3] array_of_array;
>
> That is consistent.
>
> > and throws people off at least some of the time.
>
> It must have thrown only the people who could bend their minds to somehow accept C's array syntax.
>
> > Because,
> > when you go to index it, it's used left-to-right
>
> What is left-to-right? Indexing does one thing: it provides access to the element with the given number. There is no left nor right in array indexing.
>
> > auto a = i[3]; //out-of-bounds
>
> i[3] accesses the element number 3 of i (yes, with the indicated bug). There is nothing else. The type of that element is int[4] as it has been declared. This has nothing to do with left and right.
>
> > D stayed closer to C and C++
> > and kept the right-to-left declaration synax. That's what he was
>
> referring to.
>
> I agree. I can't understand how D's array syntax is not seen as fixing C's broken one.
No, people don't normally look at declarations such as
int* a;
as being right to left. But from the compiler's perspective, they are. The compiler doesn't look at the type of a as being an int pointer. It looks at it as being a pointer to an int. The * comes first and then the int. Understanding how the compiler does it helps with reading stuff like complicated function pointers in C, but particularly with simple declarations, people just don't look at it that way. However, the compiler itself is deciphering the type outward from the variable name, and that's almost always from right to left. The exceptions are when declaring static arrays (which go on the right and thus read left-to-right) and when declaring C-style function pointers, where it ends up going from _both_ right-to-left and left-to-right, because the name is in the middle. So, in both C and D, variable declarations almost always read right-to-left.
As for static arrays in D, the problem is the disjoint between declarations and indexing. They're flipped between the two. Most people expect that the dimensions read left to right for both the declaration and the indexing, but they don't. They think that
int[4][3] a;
auto b = a[3][2];
is legal, because they view the left dimension in the declaration as being the left when indexing. But it's not. If you used the C syntax,
int a[4][3];
auto b = a[3][2];
then the dimensions _do_ match. Quite a few people in the past have requested that
int[4][3] a;
and
int a[4][3];
be the same in D. But because the compiler reads types outward from the variable, that doesn't work. So, D's syntax fixes the broken C syntax in the sense that the dimensions go with the type instead of the variable name (as they should), but it makes it worse in the sense that it means that the dimensions are in the opposite order of what most people expect. But fixing the dimensions so that they're in the order that most people expect wouldhmnv
- Jonathan M Davis
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Am 08.06.2011, 08:59 Uhr, schrieb Jonathan M Davis <jmdavisProg@gmx.com>:
> Left-to-right would end up being something more like this:
>
> a *int;
>
> or maybe
>
> *int a;
Yeah, like that improved anything. People who want the type to be to the right of the variable name should go use Pascal.
Really, one of the first things I read when I learned D was that declarations are read right-to-left and I immediately started to think that way. I'd even say it was intuitive to me.
It's consistent and fixes C's crappy behavior of splitting the type around the variable name.
And if you keep breaking down the type in your mind like "a is an array of 3 elements being arrays of 5 ints" even the indexing discrepancy isn't a problem anymore.
Add qualifiers like const, maybe mix pointers, arrays etc. and C declarations become an even bigger mess while D ones are still consistent and easily readable cause of right-to-left.
A real problem might be the syntax for creating dynamic arrays:
auto arr = new int[][](4,5)
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis wrote:
> ...
> No, people don't normally look at declarations such as
>
> int* a;
>
> as being right to left. But from the compiler's perspective, they are. The
>
> compiler doesn't look at the type of a as being an int pointer. It looks at it
> as being a pointer to an int. The * comes first and then the int.
> [snip.]
It is more convenient for the compiler to read the declaration left to right to construct the type. (just like for people)
Timon
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2011-06-08 08:38, Timon Gehr wrote:
> Jonathan M Davis wrote:
> > ...
> > No, people don't normally look at declarations such as
> >
> > int* a;
> >
> > as being right to left. But from the compiler's perspective, they are. The
> >
> > compiler doesn't look at the type of a as being an int pointer. It looks at it as being a pointer to an int. The * comes first and then the int. [snip.]
>
> It is more convenient for the compiler to read the declaration left to right to construct the type. (just like for people)
I'm sorry, but no. Yes, the compiler lexes/scans the code left-to-right, but in terms of how the type gets deciphered when parsing and using the resulting abstract syntax tree, the compiler is effectively processing the type outward from the variable, which almost always means right-to-left. The compiler has no concept of stuff like int pointer or int pointer pointer. It knows about pointer to int and pointer to pointer to int. And when you start looking at it that way, it's clearly right-to-left. The compiler is _not_ looking at it the way that a human normally does.
- Jonathan M Davis
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis wrote: > On 2011-06-08 08:38, Timon Gehr wrote: > > Jonathan M Davis wrote: > > > ... > > > No, people don't normally look at declarations such as > > > > > > int* a; > > > > > > as being right to left. But from the compiler's perspective, they are. The > > > > > > compiler doesn't look at the type of a as being an int pointer. It looks at it as being a pointer to an int. The * comes first and then the int. [snip.] > > > > It is more convenient for the compiler to read the declaration left to right to construct the type. (just like for people) > > I'm sorry, but no. Yes, the compiler lexes/scans the code left-to-right, but in terms of how the type gets deciphered when parsing and using the resulting abstract syntax tree, the compiler is effectively processing the type outward from the variable, which almost always means right-to-left. The compiler has no concept of stuff like int pointer or int pointer pointer. It knows about pointer to int and pointer to pointer to int. And when you start looking at it that way, it's clearly right-to-left. The compiler is _not_ looking at it the way that a human normally does. > > - Jonathan M Davis I'm sorry but yes. You are free to lay out your AST in any way you may please, but when the compiler has to parse and build a type involving pointers, it will proceed left-to-right. (and naturally so) Walter Bright wrote: > Type *Parser::parseBasicType2(Type *t) > { > //printf("parseBasicType2()\n"); > while (1) > { > switch (token.value) > { > case TOKmul: > t = new TypePointer(t); > nextToken(); > continue; > .... > } > ... > } Of course, afterwards the compiler reasons from right to left. But parsing left to right _is_ more convenient. Timon | |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
On 2011-06-08 08:57, Jonathan M Davis wrote:
> On 2011-06-08 08:38, Timon Gehr wrote:
> > Jonathan M Davis wrote:
> > > ...
> > > No, people don't normally look at declarations such as
> > >
> > > int* a;
> > >
> > > as being right to left. But from the compiler's perspective, they are. The
> > >
> > > compiler doesn't look at the type of a as being an int pointer. It looks at it as being a pointer to an int. The * comes first and then the int. [snip.]
> >
> > It is more convenient for the compiler to read the declaration left to right to construct the type. (just like for people)
>
> I'm sorry, but no. Yes, the compiler lexes/scans the code left-to-right, but in terms of how the type gets deciphered when parsing and using the resulting abstract syntax tree, the compiler is effectively processing the type outward from the variable, which almost always means right-to-left. The compiler has no concept of stuff like int pointer or int pointer pointer. It knows about pointer to int and pointer to pointer to int. And when you start looking at it that way, it's clearly right-to-left. The compiler is _not_ looking at it the way that a human normally does.
Sight correction (I was in too much of a hurry when I typed that). The parsing is done left-to-right just like the lexing/scanning is (it has to be). However, the processing of the AST is effectively done outward from the variable name. That is, the semantic analysis of the type is done outward from the variable name and thus left-to-right. So, as far as the compiler getting any meaning out of the type and figuring out what to do with it goes, it reads right-to-left, _not_ left-to-right. And if you try and read it like a compiler does - e.g. pointer to pointer to int, not int pointer pointer - then you'll end up reading it right-to-left too.
- Jonathan M Davis
| ||||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | I don't read the declaration right to left or left to right so much as inside out, ie. (int[4])[3]
Sent from my iPhone
On Jun 8, 2011, at 8:38 AM, Timon Gehr <timon.gehr@gmx.ch> wrote:
> Jonathan M Davis wrote:
>> ...
>> No, people don't normally look at declarations such as
>>
>> int* a;
>>
>> as being right to left. But from the compiler's perspective, they are. The
>>
>> compiler doesn't look at the type of a as being an int pointer. It looks at it
>> as being a pointer to an int. The * comes first and then the int.
>> [snip.]
>
> It is more convenient for the compiler to read the declaration left to right to construct the type. (just like for people)
>
>
> Timon
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis wrote:
> Sight correction (I was in too much of a hurry when I typed that). The parsing is done left-to-right just like the lexing/scanning is (it has to be). However, the processing of the AST is effectively done outward from the variable name. That is, the semantic analysis of the type is done outward from the variable name and thus left-to-right. So, as far as the compiler getting any meaning out of the type and figuring out what to do with it goes, it reads right-to-left, _not_ left-to-right. And if you try and read it like a compiler does - e.g. pointer to pointer to int, not int pointer pointer - then you'll end up reading it right-to-left too.
>
> - Jonathan M Davis
Seems like we are agreeing perfectly. As to pointer to pointer to int vs int pointer pointer, the only difference is:
pointer to pointer to int
<=>
pointer -> pointer -> int
int pointer pointer
<=>
int <- pointer <- pointer
Both describe the same AST. Therefore both describe the way the compiler handles it. I prefer int pointer pointer for the same reason the compiler prefers it.
Timon
| |||
June 08, 2011 Re: Herb Sutter briefly discusses D during interview | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2011-06-08 09:33, Timon Gehr wrote:
> Jonathan M Davis wrote:
> > Sight correction (I was in too much of a hurry when I typed that). The parsing is done left-to-right just like the lexing/scanning is (it has to be). However, the processing of the AST is effectively done outward from the variable name. That is, the semantic analysis of the type is done outward from the variable name and thus left-to-right. So, as far as the compiler getting any meaning out of the type and figuring out what to do with it goes, it reads right-to-left, _not_ left-to-right. And if you try and read it like a compiler does - e.g. pointer to pointer to int, not int pointer pointer - then you'll end up reading it right-to-left too.
> >
> > - Jonathan M Davis
>
> Seems like we are agreeing perfectly. As to pointer to pointer to int vs int pointer pointer, the only difference is:
>
> pointer to pointer to int
> <=>
> pointer -> pointer -> int
>
> int pointer pointer
> <=>
> int <- pointer <- pointer
>
> Both describe the same AST. Therefore both describe the way the compiler handles it. I prefer int pointer pointer for the same reason the compiler prefers it.
Except that it _does_ matter. The compiler _must_ look at types in a particular way to decipher the correctly. For instance, it's why
int[10][3] a;
can't be indexed with a[9][2]. That's why
int[10][3] a;
and
int a[3][10] a;
are equivalent. It has a huge impact on understanding C-style function pointers. It is _not_ interchangeable. The compiler must read types in a specific way to decipher them correctly, and that's outward from the variable name, which generally means right-to-left.
- Jonathan M Davis
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply