Live data from Hacker News

Language Design: Use 'ident: Type' not 'Type ident'

soc.me

71–80 of 192 posts

Re: Language Design: Use 'ident: Type' not 'Type ident'

#71
post #46

Earlier quoted context omitted.

> Not sure about Rust Rust has made a point of being parser-friendly, to support tooling. The entire reason the turbofish :: exists is to avoid ambiguous grammar. (This operator seems to vex people, I don't get the hate.)

Being parser-friendly is not at all the same thing as being user-friendly. The difficulty of writing parsers is way overblown. One thing to avoid is depending on the existence of the symbol table to parse correctly. (C++ has this problem.) Needing a symbol table makes it hard for parsers like source code formatting and syntax highlighting. Another is to avoid raw string literals that reach back and try to unwind the…

Agree with a caveat; if the syntax has many ambiguities, with resolution solved by a clever parser, it'll be confusing for users, especially newbies, because they'll tend to get errors unrelated to what they were trying to achive.

Redundancy in syntax can be a bonus.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#72
post #39

A more practical reason as a language designer is that C and C++-style type-before-name syntax is a nightmare to lex and parse, as you can't tell whether A * B; is a multiplication or a variable declaration, or whether A D; is a two comparisons with a comma operator or a templated variable declaration, without first knowing the names of all declared types. This means in practice that you have to declare types before…

`int * A` and `A * int` both seem ambiguous unless a) you require "int-pointer" naming instead of "pointer-int", and/or b) you have a separator (like the title uses) so this becomes `A * B` vs `A: * B` which is indeed unambiguous but in a very different way. i.e. without extra rules you can't tell either way, so it comes down to the extra rules. `A * B` is unambiguous for type-before-name if you require "pointer-int"…

D resolves the:

    A * B; // declaration or multiplication?
in an unusual way. If it was a multiplication, the result would be thrown away and be pointless. Hence, it is a declaration.

But what if A overloads the * operator and the side effects are desired rather than the result? D has a philosophy that arithmetic overloads should be for arithmetic-like operations, not I/O, template metaprogramming, or other nonsense. Hence if you try it like that, too bad, so sad, it'll be treated as a declaration.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#73
post #71

Earlier quoted context omitted.

Being parser-friendly is not at all the same thing as being user-friendly. The difficulty of writing parsers is way overblown. One thing to avoid is depending on the existence of the symbol table to parse correctly. (C++ has this problem.) Needing a symbol table makes it hard for parsers like source code formatting and syntax highlighting. Another is to avoid raw string literals that reach back and try to unwind the…

Agree with a caveat; if the syntax has many ambiguities, with resolution solved by a clever parser, it'll be confusing for users, especially newbies, because they'll tend to get errors unrelated to what they were trying to achive. Redundancy in syntax can be a bonus.

> Redundancy in syntax can be a bonus.

I agree. I even wrote an article about that:

https://www.digitalmars.com/articles/b05.html

Re: Language Design: Use 'ident: Type' not 'Type ident'

#74
post #36

Earlier quoted context omitted.

It's possible to argue here that the problem is not so much the order of type-then-name but the overloaded meanings of * and < at the grammar level.

More generally this falls into a discussion of context-specific vs context-free grammars. Of which C++ falls into the former, Java falls into the latter.

https://stackoverflow.com/questions/14589346/is-c-context-fr...

Context free means something different to what you're saying here. This is a good discussion of this topic, I never knew C++ was so irregular and informal.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#75
post #39

Earlier quoted context omitted.

`int * A` and `A * int` both seem ambiguous unless a) you require "int-pointer" naming instead of "pointer-int", and/or b) you have a separator (like the title uses) so this becomes `A * B` vs `A: * B` which is indeed unambiguous but in a very different way. i.e. without extra rules you can't tell either way, so it comes down to the extra rules. `A * B` is unambiguous for type-before-name if you require "pointer-int"…

D resolves the: A * B; // declaration or multiplication? in an unusual way. If it was a multiplication, the result would be thrown away and be pointless. Hence, it is a declaration. But what if A overloads the * operator and the side effects are desired rather than the result? D has a philosophy that arithmetic overloads should be for arithmetic-like operations, not I/O, template metaprogramming, or other nonsense. H…

I wouldn’t mind if such a statement in isolation would be a compiler error and if languages in general were much stricter. So far all languages I have seen that are very forgiving in terms of syntax (PHP comes to mind) seem to breed sloppy programmers and software written in these often have stupid little bugs caused by typos.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#76

Earlier quoted context omitted.

I think mariodiana is describing a hypothetical language where a and b would both be int-pointers in this case.

To declare two pointers to int in C: int *a, *b; In D: int* a, b; The use of whitespace makes the distinction clear, although the parser doesn't care.

C is just riddled with mistakes and this one finally gelled with me. Python taught me that whitespace is great for syntax and, in this case, I'm quite convinced that it should be used more firmly in most languages.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#77
post #52

Earlier quoted context omitted.

Granted that the pathological case of the error you warn against is Perl, and that should be enough of a cautionary tale for anyone. But a language is a user interface for programmers, too. Some affordance is merited, especially in a case like this where prefix vs. postfix may affect ease of parsing, but seems most unlikely to influence how the type system actually behaves.

You're right, I just don't care for the author's notes on language design because they're all on syntax design, which is an impossible task to do in morsels without knowing anything about the rest of the language or how it is supposed to work. I do prefer postfix because I think it flows very nicely "this is-a thing assigned-to that" is nicer than "thing called this assigned-to that." In terms of the impact on the la…

What are examples of language semantics which are better served by pre/postfix type annotations? Also, what exactly do you mean by making the identifier optional?

Re: Language Design: Use 'ident: Type' not 'Type ident'

#78
post #40

Strong disagreement here. "type ident" flows with the data during assignment, doesn't confuse the infix operators, and doesn't misuse ":" from a human-language standpoint. For example: val x: String = "hello" The type interrupts the flow of data from "hello" to x, so one thing that pops into mind is that this is typecasting the value to a string before storing it. Nope. Another possibility I instinctively see this as…

I agree, though I could see the merit for a standalone declaration:

  val x: String
  x = "hello"
The type at this point is almost like a comment.

For declaration and assignment though, I agree that reading "ident: Type" is harder for me.

Perhaps an interesting idea would be to have the type at the end of the expression. Like so:

  val x = "hello": String
Essentially, you're making a type assertion on an expression. Since it's an assignment expression (the value of which would be the assigned variable) then it also type checks the variable.

Re: Language Design: Use 'ident: Type' not 'Type ident'

#79

Earlier quoted context omitted.

D resolves the: A * B; // declaration or multiplication? in an unusual way. If it was a multiplication, the result would be thrown away and be pointless. Hence, it is a declaration. But what if A overloads the * operator and the side effects are desired rather than the result? D has a philosophy that arithmetic overloads should be for arithmetic-like operations, not I/O, template metaprogramming, or other nonsense. H…

I wouldn’t mind if such a statement in isolation would be a compiler error and if languages in general were much stricter. So far all languages I have seen that are very forgiving in terms of syntax (PHP comes to mind) seem to breed sloppy programmers and software written in these often have stupid little bugs caused by typos.

This particular issue has not caused any "silly typo disease" problems that I'm aware of in D. In fact, pretty much nobody notices it, it just works the way people expect it to.

(There are some other things in D that are designed to discourage trying to overload arithmetic operators for non-arithmetic purposes. For example, >= cannot be overloaded individually, only as a group.)

Re: Language Design: Use 'ident: Type' not 'Type ident'

#80

A more practical reason as a language designer is that C and C++-style type-before-name syntax is a nightmare to lex and parse, as you can't tell whether A * B; is a multiplication or a variable declaration, or whether A D; is a two comparisons with a comma operator or a templated variable declaration, without first knowing the names of all declared types. This means in practice that you have to declare types before…

I was just thinking about pointer syntax today, and if you ask me, there are a lot of problems that could be avoided if language designers took a page out of Guido van Rossum's book and extend his idea of forced spacing. Take the first example you've given, and let's just talk about variable declaration: int* a; int * a; int *a; That's all the same. That's wrong. Obviously, you can write a lexer and parser that doesn…

The problem in C is more than just the `*`. Consider arrays, where C uses `int xs[];` instead of `int[] xs;`. There is no way to use define to declare an int_array type like you did with int_ptr. (Function types also exibit a similar problem)
Post reply on HN