Hacker News new | ask | show | jobs
by dexterlemmer 1404 days ago
> While typing is dynamic, I rarely see this being used, perhaps with the exception of identifying empty variables with None. Most identifiers are born and die the same type. It would be interesting to see how much effect dynamic typing has on the rate of programming errors.

Dynamic typing and changing the type of a variable are orthogonal.

You can change a type with casting, coercion, transmutation, dynamic dispatch, downcasting, reflection, monkeypatching (i.e. simultaneosly using dynamic dispatch and downcasting and reflection). All of these methods are available in Rust, which is a statically typed language.

Some things that some people think are changing the type of a variable in Python is not what it seems, for example:

    # Python
    a = 1
    a = ['h','i'] # `a: int` is unchanged but gets implicitly shadowed by `a: list[str]`
    a[1] = "a"    # We're combining shadowing with weird and inconsistent scoping
translates to the following in Rust:

    // Rust
    #[allow(unused_mut, unused_variables)]
    {
        let mut a = 1;
        let mut a = ["h", "i"]; // Explicit shadowing
        a[1] = "a"; // We're simply calling a mutating operator
    }
Furthermore:

    # Python
    lst: Array[Any] = [1, "2", 3.0] # A heterogeneous list
    for elem in lst:
        print(elem);
translates to the following in Rust:

    // Rust
    // Below `dyn` has nothing whatsoever to do with dynamic typing.
    // ... it is just fluff having to do with the requirements of systems programming.
    // ... (Technically it means we're using vtables to do dynamic dispatch.)
    // ... The `Box` nonsense is more systems dev fluff having to do with memory allocation.
    // ... Of course in Rust, App devs often don't need to worry about such fluff because
    // ... lib devs should provide ergonomic API's, but I'm doing as close as
    // ... possible to a direct translation of the Pyhon code.
    #[allow(unused_mut)]
    let mut lst: Vec<Box<dyn Display>> = vec![
        Box::new(1),
        Box::new("1"),
        Box::new(1.0),
    ];
    for elem in lst {
        println!("{elem}");
    }
The one major difference between the Python code and Rust code above is that `Display` in Rust is a Rust trait (i.e. a typeclass) and typeclasses don't exist in Python.