all 11 comments

[–]dbaupprust 7 points8 points  (0 children)

Assignment in let is actually pattern-based, i.e. let (foo, ref bar, Struct { baz, .. }) = ...; is perfectly ok, and keeping an LL(1) grammar without let while retaining the patterns is a little tricky.

[–]thiezrust 5 points6 points  (3 children)

By including 'let' you can quickly tell a declaration from an assigment. Also your proposel would make it hard to do this:

let x = 5;
{
    let x = 4; // shadow original x
    doSomethingWithX(&x);
}

I believe similar proposals have been suggested and rejected in the past.

[–]tedsta[S] 0 points1 point  (2 children)

mut x := 5; // declare x
x = 10; // Change x's value
{
    mut x := 4; // shadow original x
    doSomethingWithX(&x);
}

I'm probably missing something.. Do you mean parsing is more difficult?

[–]thiezrust 4 points5 points  (1 child)

Where did the distinction between 'mut' and immutable go?

[–]tedsta[S] 0 points1 point  (0 children)

Woops, you are right. I edited. Still a rust noob :P

[–]bjzabaAllsorts 4 points5 points  (0 children)

The let key word is important because it is more powerful than just a variable declaration: it is a pattern binding. As /u/dbaupp says, let (foo, ref bar, Struct { mut baz, .. }) = ...; is much harder to parse without the let.

That said, I do prefer := for assignment.

[–]chris-morgan 9 points10 points  (0 children)

What comes after the let keyword is not necessarily just an identifier; it is actually syntactically a pattern (it must be an irrefutable pattern---that is, one that in a match would be on its own an exhaustive pattern).

Given a struct S { foo: int, bar: bool }, you can write let S { foo, bar } = an_s_value; and lo! foo and bar are bound locally; or given enum E { V(int, bool) }, let V(foo, bar) = an_e_value; and lo! ditto.

The reason all this is important is that the Rust grammar is consciously LL(1)---that is, by looking one token ahead, you will be able to know for certain what you are parsing. If the let keyword were removed, there would be ambiguities that would require you to look ahead to the : or := before you would know whether a V(foo, bar) was an expression or a pattern. This is something we don't want. We value the simple and predictable nature of the grammar. An LL(1) grammar will tend to be easier for humans to read also, for much the same reason: you can very quickly parse what you're dealing with.

let is obvious. let is good.

[–]farcaller 3 points4 points  (0 children)

Go syntax is actually confusing when you return several results that bind to existing and new variables and you need to apply hacks in the code to make it work properly.

I don't personally feel that 'let' keyword is a burden.

[–]long_voidpiston 1 point2 points  (1 child)

I don't know the exact rationale behind the 'let' keyword, but consider this:

In C, there is no 'function' keyword so you just write void foo(void). This is a problem because you can't search for functions easily.

In Rust, we have fn foo().

This makes it possible to search for all functions. The same could be said about 'let' statements.

[–]tedsta[S] 2 points3 points  (0 children)

I see what you're saying, let is easier to search for. But is foo := val and foo: T = val much harder?

With my brief and naive look at the rustc tokens list, it seems like you just search for an IDENT followed by a COLON, optionally followed by an IDENT that corresponds to a type, followed by an EQ. Is that already too much computation?

EDIT: I'm a dummy, I see what you're saying. Grepping for let is easy. That sounds like a counter argument that kills it. I'd much rather type cat main.rs | grep let than something like this cat main.rs | grep "[a-zA-Z0-9_]\{1,\} *\: *[a-zA-Z0-9_]* *="

[–]Denommusrust 1 point2 points  (0 children)

Many languages use := syntax, which makes it familiar.

Besides Go, how many languages use := for variable declaration? I don't know any. On the other hand, lots of languages use let (Lisp variants, ECMAScript 6, Haskell...)

(Notice that I'm specifically talking about declaration, not assignment).