Live data from Hacker News

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

soc.me

41–50 of 192 posts

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

#41

It is presented here that name before type is easier to read as a matter of fact. I’m not so sure. In math or languages where type info is optional, we often write “x = 5”. When type info is required, it is natural to evolve to “int x = 5”. Readers would naturally focus on the latter part. When we write “x: int = 5”, the type info is in the middle. We cannot skip it even when we just want to focus on the name and val…

Many languages allow you to elide the type, which is another nice thing about the type following the identifier. In Scala, in particular, types are not the assigned type like in C (where they also serve as the storage specification) -- they are assertions, that the compiler will check are compatible with the code. So `val x: int = "hello"` is no good and the compiler can cut it short right there; this is especially u…

Conversely, a lot of languages will infer type from first assignment, so in e.g. TypeScript "let x = 5", x is inferentially typed as 'number' and the type checker will throw if the implicit constraint is later violated. This reduces the need for explicit type annotations, clearing up a lot of the visual and cognitive noise.

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

#42

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…

Arguably a programming language is ultimately a user interface, and the more intuitive the interface, the better.

In 2020, not sure we should care that much about how hard compilers have to work to achieve this. Computers and software are here to support us--we're not here to support them.

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

#43

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 missed your mention of the 'most vexing parse' before writing this up, but for those not in the know, here's another fun quirk of C++ syntax:

Declare a local named neko of type Kitten, passing a value to its constructor:

    Kitten neko(42);
Declare a local named neko of type Kitten, without passing a value to its constructor:

    Kitten neko;
Declare a function named neko with zero parameters and with return type Kitten:

    Kitten neko();
https://en.wikipedia.org/wiki/Most_vexing_parse , https://stackoverflow.com/a/620149/

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

#44

It is presented here that name before type is easier to read as a matter of fact. I’m not so sure. In math or languages where type info is optional, we often write “x = 5”. When type info is required, it is natural to evolve to “int x = 5”. Readers would naturally focus on the latter part. When we write “x: int = 5”, the type info is in the middle. We cannot skip it even when we just want to focus on the name and val…

Many languages allow you to elide the type, which is another nice thing about the type following the identifier. In Scala, in particular, types are not the assigned type like in C (where they also serve as the storage specification) -- they are assertions, that the compiler will check are compatible with the code. So `val x: int = "hello"` is no good and the compiler can cut it short right there; this is especially u…

There is still a distinction between primitives and object types in Scala, so it's not correct to say that types in Scala aren't used for storage specification.

It's also the case that there are plenty of languages where all types imply storage specification and they support plenty of type elision.

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

#45
post #34

I disagree. The syntax design should flow from the design of the language itself and whether or not you use prefix or postfix notation for type annotations depends heavily on what makes sense within the semantics of the type system. Design a language before you design a syntax.

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.

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

#46
post #12

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…

It's a historical problem in C. Originally, C had only built-in types. Structs were declared with struct foo { int x; int y; }; which is easy to parse. Then came typedef. With user-defined types, foo*bar; isn't parseable with a LALR(1) parser until you've seen the definition of "foo". Even the ordinary case foo bar; needs more than one lookahead to parse. This is a headache for compilers, and a huge headache for anyt…

> 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.)

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

#48
post #25

Earlier quoted context omitted.

>Syntax isn't unimportant #104#101#108#108#111,[Space]world![Space][Space][Tab][Space][Space][Tab][Space][Space][Space][LF] [Tab][LF][Space][Space] [Space][Space][Space][Tab][Tab][Space][Space][Tab][Space][Tab][LF] [Tab][LF][Space][Space] [Space][Space][Space][Tab][Tab][Space][Tab][Tab][Space][Space][LF] [Tab][LF][Space][Space] [Space][Space][Space][Tab][Tab][Space][Tab][Tab][Space][Space][LF] [Tab][LF][Space][Space]…

I didn't say "syntax doesn't matter, pick any ridiculous thing you want". That's what I mean by "not unimportant", though I admit it's not exactly clear that's what I meant. My point is that within the space of reasonable, comprehensible syntaxes, there are no demonstrable differences worth arguing about.

>there are no demonstrable differences worth arguing about.

That is a big claim. Is very easy to believe (I do it before, when my knowledge of programming languages was about just 3 or 4. Now is more than 12). :

But is clearly false, and is easy to prove:

   async/await
   go chan
   fn sort(of:list...)
   try/catch
   match
All the above are just small things that have a HUGE impact in how develop programs. Also, in matter of "small" stuff that could look insignificant:

   [1, 2, 3] + 1 = [2, 3, 4]
this one is a huge deal in certain niches, also, another "small" and insignificant thing:

    SELECT ... FROM source
    source SELECT ...
All this are just small things. Not all that obvious at the time. Remember how before the times of GOTO the idea of more specialized control flow was unthinkable in the minds of many.

Syntax MATTER MOST. Because, is OUR interface. The space of improvement is not super-big, truth, but it impact hugely.

Also, when done correctly, it make the semantics fit like a glove or not.

Another obvious example: Do concurrency whithout syntax help (just using threads). Or performant, safe, concurrency friendly, zero-gc, system-programming, etc without what rust and other langs have bridged.

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

#49
> This means that the vertical offset of names stays consistent

This is also an argument for using keywords of the same length for introducing a variable and a constant. If that’s desirable, it rules out the obvious choices `var` and `const`.

Possibilities include `var` and `val`, which may be too similar-looking, and `var` and `let` - but are people used to (from JavaScript) `let` being mutable? Any other options?

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

#50

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't give a crap, but the human mind does. If you think it doesn't, that's only because you've internalized the various cases.

It should be this:

    int* a;
The type we're talking about is a pointer to a variable of type int: in other words, "a" is an int-pointer. If you were to create a macro, you'd do something like this:

    #define int_ptr int*
Do you see what I'm getting at? The star in this case is a suffix, equivalent (in our minds) to "_ptr". Conceptually, it doesn't belong anywhere else than attached to the type. It's a compound type, conceptually.

Now, take the star being used in a different context:

    int b = 10;
    int* a = &b;
    printf("%d\n", *a);
There, though we see the same character, it's a completely different thing. It's a dereference operator. Conceptually, it belongs attached to the pointer variable it is dereferencing; and since the star is already used in one context as a suffix, here it should be used as a prefix.

This is no good:

    printf("%d\n", * a);
It doesn't matter that "this compiles." That's not what this is about.

Many C programmers (and programmers in other languages, even Python) are used to writing things like this:

    int c = x*y;
That's wrong. Sure, the lexer and parser don't care. But that makes the language worse, for the human operator. "But it saves space!" Spare me.

The thing with this one example, using the star, is that what we have is the equivalent of a homonym. We have one sign that is actually three different words. Mandating spacing removes the ambiguity you're complaining about.

C is what it is, but if we imagine someone were going to write it today, they should incorporate the above and mandate spacing. For the sake of the humans. "ident type" is not the only solution.

Post reply on HN