Hacker News new | past | comments | ask | show | jobs | submit login

Contrast the first example with Golang:

  str [10]*byte
which reads exactly as it is declared: "str is an array of length 10 of pointers to byte" (byte is Go equivalent of C char (mostly)).



Or Rust:

    let string: [&u8; 10];
string is an array of references to unsigned integers of 8 bits of length ten


Actually it's a semicolon.


Whoops, fixed


It can also be simpler if you use idiomatic modern C++ with std::array<T, n> and std::function<R(T1, T2)>.


Looking at "idiomatic modern C++", I am often at a loss for words at what lengths they've gone to in order to reinvent things while greatly obfuscating them in the process. Is there a std::pointer_to<T> too? I don't know, but something like this

    std::array<std::pointer_to<byte>, 10> str;
certainly does not look any more readable to me than

    byte *str[10];
. (Disclaimer: I mainly work with C, but find some C++ features genuinely useful, although the majority of the time they seem more like absurd complexity for the sake of complexity.)


I've never seen nor heard of pointer_to ever being used to declare a pointer to something. I believe t's used inside of custom allocators for a generic type that might not use a normal pointer as the pointer type, but would never be used for normal declarations like this.

std::array is useful for letting the compiler avoid array-to-pointer decaying, value semantics, and also actually putting array length type info in a function parameter.


std::array does not exist because it is easier to read. It exists because C arrays behave strangely. Two examples: decay to pointer and no value semantics.


Or Nim:

    var str: array[10, ptr byte]
(and much richer types)

Edit: and while I'm here, Nim has other sensible syntax for this low level stuff...

    var b: byte = 10
    str[0] = addr b
    echo $str[0][]


I am not familiar with Go, and have heard many praises of its declaration syntax, but is its dereference operator postfix? That would make sense in such a case.

On the other hand, IMHO the whole "make declarations read left-to-right" idea is misguided --- plenty of other constructs exist in programming languages which simply can't be read left-to-right, but are nested according to precedence. I mean, you might as well make 3+4*3 evaluate to 21 if you want to try making everything consistently left-to-right, but I don't really see anyone complaining about not being able to understand operator precedence...


Go's defererence operator `*` is prefix, like in C.

The point here is that type declarations are regular to read, and those tend to be the tricky ones. Expressions tend not to be so difficult, and are more commonly factored if they become complex. For various reason, type declarations are not so practically factorable.


When I came to Go, I hadn't used C or C++ for over a decade, only Java and C# in between. Using explicitly written pointers came flooding back, but the new "C for expressions, Pascal for declarations" syntax still takes getting used to.

Declaring `v * T` means we can write `* v` as an expression, so the use of token * is synchronized for both these uses, but I must vocalize the * in my head differently:

  `*T` vocalizes as "pointer to something of type T"
  `*v` vocalizes as "that pointed to by variable v"
  `&v` vocalizes as "pointer to variable v"
So my thought process when I see * goes: If it's in a type, say "pointer to", otherwise say the opposite of "pointer to", i.e. "that pointed to by". It feels like an inconsistent use of * whenever I'm writing Go code -- even though I know it's a natural result of Go using Pascal-style declaration syntax but C-style tokens.


But then you lose C's nice property that declaration and use are the same syntax.

For example, D also uses a similar type syntax, so in D if you declare:

  int[10][20] x;
  x[19][9] // is legal
In C:

  int x[10][20];
  x[9][19] // is legal
I think the correct solution would have been to make pointer syntax post-fix like the arrays and functions, so that you get the best of both worlds. Go-like declarations and C-like matchup between use and declarations.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: