Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Back to TCP. Earlier for the sake of simplicity I told a little fib, and some of you have steam coming out of your ears by now because this fib is driving you crazy. I said that TCP guarantees that your message will arrive. It doesn’t, actually. If your pet snake has chewed through the network cable leading to your computer, and no IP packets can get through, then TCP can’t do anything about it and your message doesn’t arrive.

The argument is disqualified at this point. The whole world is a leaky abstraction because <freak meteor hit could happen>. At this point your concept is all-encompassing and in turn useless.

There are assumptions: this computation will finish eventually [assuming that no one unplugs the computer itself]. This does not make things leaky.

There are leaky abstractions I guess but not all are. A garbage collector that can cause memory errors would be leaky. I don’t know anything about garbage colletors but in my experience they don’t.

Then someone says that a garbage collector is leaky because of performance concerns (throughput or latency). That’s not a leak: that’s part of the abstracting away part—some concerns are abstracted away. To abstract away means to make it something that you can’t fudge or change. To say that “this is implementation-defined”. An abstract list is an abstraction in the sense that it has some behavior. And also in the sense that it doesn’t say how those behaviors are implemented. That’s both a freedom and a lurking problem (sometimes). Big reallocation because of amortized push? Well you abstracted that away so can you complain about it? Maybe your next step is to move beyond the abstraction and into the more concrete.

What are abstractions without something to abstract away? They are impossible. You have to have the freedom to leave some things blank.

So what Spolsky is effectively saying is that abstractions are abstractions. That looks more like a rhetorical device than a new argument. (Taxes are theft?)

EDIT: Flagged for an opinion? Very well.



> There are leaky abstractions I guess but not all are. A garbage collector that can cause memory errors would be leaky. I don’t know anything about garbage collectors but in my experience they don’t.

Garbage collectors are a rich source of abstraction leaks, depending on what you do with the runtime. If you color within the lines, no surprises, the garbage collector will work. Unless it has a bug, and hundreds of GC bugs, if not thousands, have shipped over the decades; but while a bug is an abstraction leak, it's not a very interesting one.

But go ahead and use the FFI and things aren't so rosy. Usually the GC can cooperate with allocated memory from the other side of the FFI, but this requires care and attention to detail, or you get memory bugs, and just like that, you're manually managing memory in a garbage collected language, and you can segfault on a use-after-free just like a Real Programmer. It's also quite plausible to write a program in a GC language which leaks memory, by accidentally retaining a reference to something which you thought you'd deleted the last reference to. Whether or not you consider this an abstraction leak depends on how you think of the GC abstraction: if you take the high-level approach that "a GC means you don't have to manage memory" (this is frequently touted as the benefit of garbage collection), sooner or later a space leak is going to bite you.

Then there are finalizers. If there's one thing which really punctures a hole in the GC abstraction, it's finalizers.


> But go ahead and use the FFI and things aren't so rosy. Usually the GC can cooperate with allocated memory from the other side of the FFI, but this requires care and attention to detail, or you get memory bugs, and just like that, you're manually managing memory in a garbage collected language, and you can segfault on a use-after-free just like a Real Programmer.

Now you’ve stepped beyond the walled gardens of the managed memory. How is that an abstraction leak?

> It's also quite plausible to write a program in a GC language which leaks memory, by accidentally retaining a reference to something which you thought you'd deleted the last reference to.

That the user just thought they had gotten rid of? If the memory is technically reachable then that doesn’t sound like its fault. I’m reminded of the recent Rust Vec thread on how the so-called space leak of reusing allocated memory lead to unreasonable memory consumption. But to my recollection that wasn’t a leak in the sense of unreachable-but-not-freed. I do agree however (with those that made this point) that the Vec behavior was too clever. Which goes to show that Vec should probably just stick to the front-page abstraction advertised: will amortize allocations, can shrink to fit if you tell it to, nothing much more fancy beyond that.

(The memory leak topic seems very fuzzy in general.)


I tend to agree. "All nontrivial abstractions are leaky" reminds me of other slightly-too-cute rules, such as "full rewrites are a mistake" and "never parse JSON manually".

I wouldn't call TCP leaky because it can't deliver data across a broken network cable, for example. It's abstracting away certain unreliable features of the network, like out of order delivery of packets. It's not abstracting away the fact that networking requires a network.


I suppose it should be considered where the abstraction actually exists. If the abstraction exists in logic or mathematics (ie. a triangle is a 3 sided polygon) it probably doesn't make much sense to consider the ramifications that thought occurs in a physical brain that can fail. On the other hand if the abstraction is physical (ie, hardware), then the fact that it is bound by physical law is obviously implicit. Software encompasses both physical and logical abstractions, so you need to pick a lens or perspective in order to actually view its abstractions.


I don't agree with your opinion, but I see how it can be seen as being perfectly reasonable and there really is no need to flag you (unflagged).


I unflagged you by vouching for you. I found your post difficult to understand and couldn't figure out what you are trying to say, but I agree it was not deserving of a flag.


What was difficult about what I wrote?


Your criticism that a broken wire is outside the scope of the TCP protocol was clear and valid.

The subsequent paragraphs about garage collection are tough to follow. You have multiple parenthetical remarks, a quotation which I think is used as emphasis, italics used as emphasis, compound sentence fragments joined by an em-dash and a colon in the same sentence, rhetorical questions which presumably have obvious answers but not obvious to me, terms that aren't clear (e.g. what is an "amortized push"?), and concepts that don't seem to be related to GC (e.g. an "abstract list" can be implemented without GC, so why is that included in that paragraph?).

I've read those paragraphs 4-5 times now, and I don't think I understand what you are trying to say.


amortized push: a fundamental data structure, the vector, is a growable array of elements. The standard name for the function that appends an element at the end of the array is "push". You push to the array.

A vector points to an allocated portion of memory. When full, a new one; usually double the size; is allocated, everything copied over, and the original allocation is discarded.

Therefore the cost of memory allocation and copy is amortized over many pushs.


I’ll try to do better in the next life.


Seems like you missed the point of the article.

Yes, most of the article is dedicated to describe the “leak”, but there was no call to abolish abstractions. Just the insight that one needs to understand implementation of those.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: