News for hackers. Stuff that matters.
Re:Grain: A strongly-typed functional programming language f... by KingOfCoders on Sunday April 25, 2021 @11:15AM (#26933356)
That answer is technically correct but too shallow.

I could then call

  a = "hallo"
  // can call String methods, runtime checked
  a = 3
  // can call int methods, runtime checked
in Python also variable shadowing. But in this case you assume a is the same but the type changes, and call it dynamic typing, while in the Rust example you assume the two a's are not the same variable:

    let a = String::from("Hallo");
    // can call String methods, compiler checked
    let a = 3
    // can call i methods, compiler checked
One could argue there is a difference with method signatures

    def f( a )
 
    a = "hallo"
    f(a)
    a = 3 
    f(a)
which does work in Python ("dynamic") but not in Rust ("static").

But then the actual usage of "a" in the method effectively puts it on the same level as interfaces in Rust and blurs further with static languages like Typescript without nominal types.

Re:Grain: A strongly-typed functional programming language f... by tom_mellior on Sunday April 25, 2021 @07:36PM (#26937782)
> I could then call <variable reassignment> in Python also variable shadowing

You could, but you would be wrong. Shadowing is associated with opening a new scope. Reassignment modifies a location in an existing scope. Python does the latter.

Re:Grain: A strongly-typed functional programming language f... by KingOfCoders on Sunday April 25, 2021 @11:58PM (#26939122)
What does that mean? Wouldn't scope only come into play with e.g.

  a = "hello"
   { 
     // new scope
     a = 3
   }
  // a == "hello"
and is there a difference between Rust and Python?
Re:Grain: A strongly-typed functional programming language f... by gopiandcode on Monday April 26, 2021 @06:52AM (#26941200)
Here's an example of how the behaviour between Rust and Python differ because of scoping:

in Rust:

  fn main() {
    let a = 3;
    let f = | | { a };
    let a = "b";
    println!("{}, {}", f(), a);
  }
in Python:

  a = 3
  def f ():
      return a
  a = "b"
  print("{}, {}".format(f(), a))

The rust code outputs "3, b" while the python code outputs "b, b". The python code _assigns_ to the variable a, whereas the rust code creates a new scope and redefines a, shadowing it in the parent scope.
Re:Grain: A strongly-typed functional programming language f... by KingOfCoders on Monday April 26, 2021 @07:10AM (#26941297)
Yes you're right, I also would think closures would be impacted by scope.
Re:Grain: A strongly-typed functional programming language f... by valenterry on Monday April 26, 2021 @12:33AM (#26939258)
I believe the difference is that Rust implicitly creates a new scope when a variable of type X is (re)assigned with a different type. So you in rust you can write (python syntax)

    a = 3
    a = "x"
and both of these variables will exist at the same time with different times and potentially referable to from the outside. In python that cannot work, because there are no types. That's why in python the behavior is to always overwrite the existing variable, or create a new one in a local scope _if and only if_ this scope is somehow specified, i.e. by declaring a function.