Programming languages without garbage collection send us down a long path of design decisions that lead to slow compile times and fragile runtime performance cliffs.
-
Show this thread
-
First is the abandoning of covariance and contravariance, the property which guarantees sensible subtyping: that bytes are also integers, and integers are also objects, extending systematically to container types and functions.
3 replies 3 retweets 44 likesShow this thread -
Without garbage collection, offering an array of bytes where an array of integers is required requires stack-allocating an array of integers and converting each byte to an integer every time a subtype is used in place of an actual type. This is so absurd that it’s not done.
6 replies 4 retweets 38 likesShow this thread -
So now when we want to recover performance, we need to write all containers and their operations using an increasingly elaborate set of templates or generic functions, which the compiler must specialize for each type at significant cost. This is what C++ and Rust do.
4 replies 5 retweets 40 likesShow this thread -
Or we can create a very clunky wrapper like array_of_anything that is used wherever generic types are required, which manually casts and converts values among types dynamically each time it’s accessed. Java generics did this and they were awful.
3 replies 4 retweets 28 likesShow this thread -
But if we have garbage collection, we can store our large data structures once with whatever type is required, then dynamically create wrappers that reinterpret it as any subtype that’s required. We pay the cost of GC and indirect control flow for accessors but that’s all.
7 replies 4 retweets 40 likesShow this thread -
Replying to @TimSweeneyEpic
If you are happy with the cost of the indirect call, what stops you from creating this wrapper in a statically compiled language without GC on stack? I don't think these are related. The big issue *is* the indirect call, which can be prohibitively expensive.
1 reply 0 retweets 2 likes -
Replying to @zeuxcg
If a subtyping relationship is implemented by a conversion like vector<t>(const vector<u>&) that works by holding a reference to its input, then the dangling reference issues will be explosive. This led C++ down the string_view path to distinguish epemeral things.
2 replies 0 retweets 3 likes
And that only works in function call chains. If you're trying to store a vector<byte> in a heap variable of type vector<int>, either you have to convert it all, or reference it and be deeply aware of the lifetime relationships between the two things. Which GC solves.
Loading seems to be taking a while.
Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information.