3 ms·
Another example why hiding state can be a good thing. Consider following code: void* ptr = malloc( 32 ); No OOP is involved here, yet the malloc function
by Const-me 8y ago
Another example why hiding state can be a good thing. Consider following code:
void* ptr = malloc( 32 );
No OOP is involved here, yet the malloc function operates on a critically important piece of mutable global state. The state is quite complex due to numerous reasons: performance, fragmentation, multithreading & deadlocks, alignment… Just look at ptmalloc (linux) or jemalloc (BSD). I think it’s undocumented on Windows but I’m sure it’s at least as complex, search for “low fragmentation heap” which is the default one since Vista.
I don’t think hiding that state in layers of abstractions is counterproductive, I think it was good, due to the following reasons.
1. In 99% cases makes it easier to write code. Heap state is very complex in practice, and just like file IO, it spawns across user mode state of your process and OS kernel state. Hiding the state all together allows programmers to reason in terms of very simple APIs, it’s just 2 functions malloc/free with very clear purpose each.
2. Hiding that state makes bugs in your code less likely to corrupt it. If you instead have something like void* malloc( size_t bytesCount, struct HeapState *processHeap ) it becomes easier to accidentally corrupt that state.
3. Hiding that state decouples consuming code from implementation. On Linux, that state is hidden deep inside libc library. You can replace the complete implementation of that state, or even eliminate it if you want so, the consuming code will run fine as long as malloc/free API stays stable. Quite often, code that uses explicit state becomes dependent on the particular implementation of that state. Much less likely to happen when the state is hidden behind some API, OOP or not doesn’t matter.
- jstimpfle 8y agoAbsolutely should you wrap malloc in any moderately sized project! But clearly that's not OOP. We need to differentiate between abstract data types (method dispatch, which I would normally count as OOP) and just making functions to "reuse" code. In the latter case, there is only one possible implementation, and the implementation can expose as much or as little implementation details as is appropriate -- and in general, there won't be any abstraction leaks.
- Const-me 8y ago> and in general, there won't be any abstraction leaks. For malloc, address space fragmentation is a common issue for 32-bit processes. Multithreading issues are common, when 2 threads access same cache line, it’s even slower than accessing main RAM. Randomized nature of the allocator causes performance problems. Every time people bother writing custom allocators, they do that because malloc/free abstraction was not good enough for them, i.e. has leaked. All abstractions leak, OOP or not.
- jstimpfle 8y agoIf I make a function called allocate_new_foo() that is not an abstraction (in the sense I mentioned - i.e. method dispatching). It's plain old boring programming - specifying in only one place how foo's should be allocated. And each caller is expected to have a good understanding what kind of allocation to expect - i.e. pool allocation or whatever. I wouldn't consider this an abstraction at all, and it doesn't leak nearly as much as a "streams" abstraction - if at all.