Things That Are Commonly Misunderstood in Coding (JS, Python, Rust )

5 min read

1. Mutability vs Immutability

Python:

def mutate_list(l):
    l.append(4)

my_list = [1, 2, 3]
mutate_list(my_list)
print(my_list)  # [1, 2, 3, 4]

Mutable objects like lists or dictionaries change in-place.

JavaScript:

function mutateArray(arr) {
    arr.push(4);
}

const myArray = [1, 2, 3];
mutateArray(myArray);
console.log(myArray); // [1, 2, 3, 4]

Rust:

fn mutate_vec(v: &mut Vec<i32>) {
    v.push(4);
}

fn main() {
    let mut v = vec![1, 2, 3];
    mutate_vec(&mut v);
    println!("{:?}", v); // [1, 2, 3, 4]
}

Mutability isn’t just about being able to change a value — it’s about ownership, borrowing, and responsibility.


2. Pass by Value vs Reference Confusion

Python passes references to objects by value. You’re not passing the object; you’re passing a reference.

def add_item(d):
    d['new'] = 'yes'

data = {}
add_item(data)
print(data)  # {'new': 'yes'}

JavaScript is the same. Object references are passed by value:

function modify(obj) {
    obj.name = "changed";
}

const user = {};
modify(user);
console.log(user); // { name: "changed" }

Rust enforces clarity:

fn take_ownership(v: Vec<i32>) {
    println!("{:?}", v);
}

fn main() {
    let vec = vec![1, 2, 3];
    take_ownership(vec);
    // println!("{:?}", vec); // Error: vec moved
}

Rust forces you to be explicit with ownership. You won’t forget what’s happening.


3. Floating-Point Precision

print(0.1 + 0.2 == 0.3)  # False
console.log(0.1 + 0.2 === 0.3); // false
fn main() {
    println!("{}", 0.1 + 0.2 == 0.3); // false
}

Don’t use floats for precise decimal math. Use Decimal in Python, BigInt in JS (for integers), or crates like rust_decimal in Rust.


4. Async != Efficient

JS:

async function getData() {
    await fetch(url1);
    await fetch(url2); // Waits for url1 to finish first
}

// Better:
await Promise.all([fetch(url1), fetch(url2)]);

Python:

async def main():
    await asyncio.gather(
        fetch(url1),
        fetch(url2)
    )

Rust (with Tokio):

let (a, b) = tokio::join!(task1(), task2());

Async needs parallelism. Not waiting like it’s synchronous.


5. Scope and Closures

JavaScript:

for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100);
} // Prints 3, 3, 3

for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100);
} // Prints 0, 1, 2

Python:

def funcs():
    return [lambda i=i: i for i in range(3)]

for f in funcs():
    print(f())  # 0 1 2

Rust:

let funcs: Vec<_> = (0..3).map(|i| move || println!("{}", i)).collect();
for f in funcs {
    f();
} // 0 1 2

Closures capture variables, not their values — unless you’re deliberate.


6. Null vs Undefined vs None

JavaScript:

let x;        // undefined
let y = null; // null

Python:

x = None

Rust:

let x: Option<i32> = None;

Different semantics. JS has undefined and null. Python has None. Rust has Option and it’s type-safe.


7. Big O Isn’t Optional

Bad complexity = bad performance.

Python:

# O(n^2)
for i in range(n):
    for j in range(n):
        pass

Rust:

for i in 0..n {
    for j in 0..n {
        // do stuff
    }
}

Your language doesn’t save you. Your algorithm does.


8. Boolean Short-Circuiting

JS:

function expensive() { console.log("ran"); return true; }
false && expensive(); // nothing logs

Python:

False and expensive()  # never runs expensive()

Rust:

fn expensive() -> bool {
    println!("ran");
    true
}

fn main() {
    false && expensive(); // does not run
}

Short-circuiting matters in perf and in bugs.


9. Equality vs Identity

JS:

"5" == 5   // true
"5" === 5  // false

Always use ===.

Python:

x = [1, 2]
y = [1, 2]
print(x == y)  # True
print(x is y)  # False

Rust:

let a = vec![1, 2];
let b = vec![1, 2];
println!("{}", a == b); // true

In Rust and Python, == compares content. Identity is a different thing.


10. Dependencies

JavaScript:

npm install left-pad

Do you really need that?

Python:

pip install requests

Useful. But don’t install everything you see on Stack Overflow.

Rust:

[dependencies]
serde = "1.0"

Even Rust has bloat if you let it. Crates aren’t free.

Every new dependency increases build time, audit size, and attack surface.


That’s all. No outro. Just get better at the basics. These aren’t obscure ideas. They’re just things you keep skipping.

See you next time I feel like writing one of these.