Hacker News new | ask | show | jobs
by andrepd 1175 days ago
Well why not with the same type? Sounds like an arbitrary restriction: you can use this idiom, but only sometimes.
2 comments

There is no such restriction, it's just much less common to want that.

  let x: u32 = 5;
  let x: u32 = 10; // You can write this, but why?
  let x: u32 = 20; // I really feel like you should re-consider
If you end up shadowing this way in a long function it more likely means the function got too long. On the other hand, I certainly have had cause to shadow variables in inner scopes e.g.

  let x = some_complicate_stuff();
  for dx in [-1, 0, 1] {
    let x = x + dx;
    // Do stuff with x very naturally here, rather than keep saying "x + dx" everywhere
  }
  // But outside the loop x is just x, it's not x + dx
Why would you do that with the same type instead of just making the variable mutable? And you can do it, I just don't think it's a good idea as you now effectively have a mutable variable without it being marked as such.
No, it's still better than a mutable variable. Because it's not a mutable variable, just a series of variables that happen to have the same name.

Mutable state is 'evil' and makes your program harder to reason about on a semantic level. Shadowing is merely a syntactic choice with pros and cons.

I like shadowing in Rust, it works well there. In eg Python or Haskell, it works less well, but for different reasons. (In Haskell it's because of laziness and definitions being co-recursive by default. In Python it's because the language doesn't give you any tools to tell apart assignment to an existing variable from creation of a new variable.)

> it's not a mutable variable, just a series of variables that happen to have the same name.

Fair point, though in that case I'd be more comfortable separating those variables into scopes.

> Mutable state is 'evil' and makes your program harder to reason about on a semantic level. Shadowing is merely a syntactic choice with pros and cons.

Both result in multiple states of the same identifier, so I don't quite see the big difference here. In Rust I already have the clearly visible "mut" keyword telling me that it'll be overwritten.

> Both result in multiple states of the same identifier, so I don't quite see the big difference here.

Shadowing is something you can figure out purely on the syntactic level.

Figuring out mutable state requires solving the halting problem.

> Fair point, though in that case I'd be more comfortable separating those variables into scopes.

Well, they effectively have different scopes. The scope is just not delimited with curly braces.

It's similar to how eg Haskell's variable binding in do-notation extent to the rest of the do-block. Each line introduces a new scope.

However, I can re-interpret your comment as saying that you want a more explicit syntactic marker for a new scope. And that's a fair enough request.