Thanks, all, for the nice words! 😉
Sektor / Iulian: Yes, this is indeed different from C#, which (as far as I know - probably not very far) uses multiple-pass compilation. T-SQL uses single-pass, and has very different scoping rules. As far as I know, that is indeed by design, though badly documented.
Hugo, I thought the reason why the answer is null is because the evaluation of IF 1 < 0 get returned as false
That is part of the explanation. Because 1 < 0 evaluates as false, the (implied) SET statement that gives @j-2 its value is never executed. (And neither is the SET that changes the value of @i, though that becomes irrelevant for the question once you realize why @j-2 is not initialized at all).