

Donald Trump will either still be President, or be dead.
Donald Trump will either still be President, or be dead.
I’m gonna hazard a guess, just cause I’m curious, that you’re coming from JavaScript.
Regardless, the answer’s basically the same across all similar languages where this question makes sense. That is, languages that are largely, if not completely, object-oriented, where memory is managed for you.
Bottom line, object allocation is VERY expensive. Generally, objects are allocated on a heap, so the allocation process itself, in its most basic form, involves walking some portion of a linked list to find an available heap block, updating a header or other info block to track that the block is now in use, maybe sub-dividing the block to avoid wasting space, any making any updates that might be necessary to nodes of the linked list that we traversed.
THEN, we have to run similar operations later for de-allocation. And if we’re talking about a memory-managed language, well, that means running a garbage collector algorithm, periodically, that needs to somehow inspect blocks that are in use to see if they’re still in use, or can be automatically de-allocated. The most common garbage-collector I know of involves tagging all references within other objects, so that the GC can start at the “root” objects and walk the entire tree of references within references, in order to find any that are orphaned, and identify them as collectable.
My bread and butter is C#, so let’s look at an actual example.
public class MyMutableObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
}
public record MyImmutableObject
{
public required ulong Id { get; init; }
public required string Name { get; init; }
}
_immutableInstance = new()
{
Id = 1,
Name = "First"
};
_mutableInstance = new()
{
Id = 1,
Name = "First"
};
[Benchmark(Baseline = true)]
public MyMutableObject MutableEdit()
{
_mutableInstance.Name = "Second";
return _mutableInstance;
}
[Benchmark]
public MyImmutableObject ImmutableEdit()
=> _immutableInstance with
{
Name = "Second"
};
Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|
MutableEdit | 1.080 ns | 0.0876 ns | 0.1439 ns | 1.02 | 0.19 | - | - | NA |
ImmutableEdit | 8.282 ns | 0.2287 ns | 0.3353 ns | 7.79 | 1.03 | 0.0076 | 32 B | NA |
Even for the most basic edit operation, immutable copying is slower by more than 7 times, and (obviously) allocates more memory, which translates to more cost to be spent on garbage collection later.
Let’s scale it up to a slightly-more realistic immutable data structure.
public class MyMutableParentObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
public required MyMutableChildObject Child { get; set; }
}
public class MyMutableChildObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
public required MyMutableGrandchildObject FirstGrandchild { get; set; }
public required MyMutableGrandchildObject SecondGrandchild { get; set; }
public required MyMutableGrandchildObject ThirdGrandchild { get; set; }
}
public class MyMutableGrandchildObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
}
public record MyImmutableParentObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
public required MyImmutableChildObject Child { get; set; }
}
public record MyImmutableChildObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
public required MyImmutableGrandchildObject FirstGrandchild { get; set; }
public required MyImmutableGrandchildObject SecondGrandchild { get; set; }
public required MyImmutableGrandchildObject ThirdGrandchild { get; set; }
}
public record MyImmutableGrandchildObject
{
public required ulong Id { get; set; }
public required string Name { get; set; }
}
_immutableTree = new()
{
Id = 1,
Name = "Parent",
Child = new()
{
Id = 2,
Name = "Child",
FirstGrandchild = new()
{
Id = 3,
Name = "First Grandchild"
},
SecondGrandchild = new()
{
Id = 4,
Name = "Second Grandchild"
},
ThirdGrandchild = new()
{
Id = 5,
Name = "Third Grandchild"
},
}
};
_mutableTree = new()
{
Id = 1,
Name = "Parent",
Child = new()
{
Id = 2,
Name = "Child",
FirstGrandchild = new()
{
Id = 3,
Name = "First Grandchild"
},
SecondGrandchild = new()
{
Id = 4,
Name = "Second Grandchild"
},
ThirdGrandchild = new()
{
Id = 5,
Name = "Third Grandchild"
},
}
};
[Benchmark(Baseline = true)]
public MyMutableParentObject MutableEdit()
{
_mutableTree.Child.SecondGrandchild.Name = "Second Grandchild Edited";
return _mutableTree;
}
[Benchmark]
public MyImmutableParentObject ImmutableEdit()
=> _immutableTree with
{
Child = _immutableTree.Child with
{
SecondGrandchild = _immutableTree.Child.SecondGrandchild with
{
Name = "Second Grandchild Edited"
}
}
};
Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|
MutableEdit | 1.129 ns | 0.0840 ns | 0.0825 ns | 1.00 | 0.10 | - | - | NA |
ImmutableEdit | 32.685 ns | 0.8503 ns | 2.4534 ns | 29.09 | 2.95 | 0.0306 | 128 B | NA |
Not only is performance worse, but it drops off exponentially, as you scale out the size of your immutable structures.
Now, all this being said, I myself use the immutable object pattern FREQUENTLY, in both C# and JavaScript. There’s a lot of problems you encounter in business logic that it solves really well, and it’s basically the ideal type of data structure for use in reactive programming, which is extremely effective for building GUIs. In other words, I use immutable objects a ton when I’m building out the business layer of a UI, where data is king. If I were writing code within any of the frameworks I use to BUILD those UIs (.NET, WPF, ReactiveExtensions) you can bet I’d be using immutable objects way more sparingly.
A very large portion (maybe not quite a majority) of software developers are not very good at their jobs. Just good enough to get by.
And that is entirely okay! Applies to most jobs, honestly. But there is really NO appropriate way to express that to a coworker.
I’ve seen way too much “just keep trying random things without really knowing what you’re doing, and hope you eventually stumble into something that works” attitude from coworkers.
Did you like the subplot about how slaves who are freed against their will turn to alcoholism?
Yeah, I thought it was really interesting how there were two characters who gained freedom and handled it in completely opposite ways. I thought it was a great way to highlight that simply ending an injustice often isn’t enough. It takes effort beyond that to truly reach justice/equity.
Or how when they celebrated Christmas at Grimmauld place, they put little santa hats and beards on the severed slave heads?
The severed heads themselves were clearly established as one of many things that made everyone being forced to live there uncomfortable. So, yes, I liked the touch of the characters decorating them, and the rest of the house, to try and make it less of a reminder of the shitstain of a family that it used to belong to. The characters make quite a few such attempts, throughout the book, often unsuccessfully.
Did you like the HIV allegory character who deliberately tries to infect young boys with his disease?
Yeah, it’s a pretty terrifying concept, and a great lesson about how being a victim doesn’t make someone good. Anyone can be evil. In fact, victimization often becomes the SEED of future evil.
What about the constant descriptions of “mannish hands” and general authorial misogyny against women who the reader isn’t supposed to like?
I don’t see how one instance of the phrase “mannish hands” across seven books equates to “constant descriptions”. I can’t say that I liked it or disliked it, because I don’t ever remember reading it. It wasn’t a significant enough detail to remember, just descriptive flavor of what the author was picturing. In retrospect today, yeah, that seems like anti-trans bias subconsciously leaking out, to have a “bad” woman character have masculine qualities. But it definitely doesn’t read that way, on its own.
Did you like how Harry was supposed to be the saviour of magical england from a fascist movement, and yet he’s a moderate liberal who never makes an effort to fundamentally change any of the systems of the world, and who wants Hermione to stop campaigning against slavery because it’s annoying?
Given that the books actually give zero picture of how much magical society has changed, after Voldemort’s death, I don’t see how I can answer that. The only thing we know for sure about the world is that Hogwarts and Platform 9 3/4 still exist. I could give a fuck about what Rowling’s expanded on in interviews and musings on Twitter.
I don’t recall Harry ever once being against SPEW, that was pretty much all Ron, who does eventually change his mind. What Harry DOES have is the fantastic story arc with Kreacher, where he explicitly recognizes how wrong he was to not see the barbarity of the system sooner.
I came into this thread thinking I’d just post “Uhh, it was pretty nice?”
Then I read the post text. Jesus fuck.
The other comments are probably right, no real point in doing anything but ignoring them. But goddamn, my first instinct would be to try and call them out on that bullshit attitude. No way am I clever enough to do it effectively, though.