Reclaiming memory is a visible side effect. If you don't do it, your program leaks memory and dies. Very visible. It's just a resource like any other.

I'm not being deliberately obtuse; I'm just recognizing that RAII and garbage collection are mutually exclusive. You're telling me that memory is special because it's managed by GC, but that's a little unfair, because assuming GC renders the entire discussion moot! If you assume garbage collection, then you've ruled out RAII, and there's no point in discussing the suitability of RAII for any resource. You simply can't combine RAII with garbage collection (at least pending some linguistic innovation that involved, say, reference-counting objects only for the purpose of destruction and not for the purpose of freeing memory. Which sounds silly to me.)

The reason is that RAII ties resource management to object lifetime, and with GC, there is no deterministic destruction of heap objects, and therefore no such thing as reliable RAII. Without deterministic object destruction, you end up relying on the programmer to manually ensure the destruction of the resource-managing objects. The best you can do in the presence of GC is "with" constructs (such as CL's "with-open-file") which do not give you as strong a guarantee as RAII does, because even with well-designed resource management objects they rely on the programmer to know which types manage resources and to never accidentally use them outside an appropriate "with" construct. Also, there are inevitably times when a resource must outlive the scope of any "with" construct. In the end you are much more reliant on programmer discipline than with RAII.

So the question is not whether RAII is suitable for some resources but not for memory, because that is a contradiction given current technology, but rather whether you 1) use RAII both for memory and for whatever additional resources you like, or 2) use GC for memory and use more manual and error-prone (in my opinion) methods for handling other resources.

rayiner's objection to RAII is twofold, first that it is simple to manage non-memory resources and second that functional programming style results in a very large number of short-lived objects which are more efficiently handled via GC. To the first I say that managing file handles and database connections may be easy for him, but it certainly hasn't been easy for all the programmers I've worked with. When resource leaks stop being a problem, we'll stop looking for solutions. To the second I say that you can't choose between GC and reference counting on the basis of performance without considering a concrete situation. In many situations it's better to have a program that is consistently slower than one that is much faster on average but intermittently unavailable. In other cases you only care about throughput and will therefore prefer GC.

Personally, I prefer to choose on the basis of programmer convenience rather than performance. If resource management is important, that tilts the scales in favor of RAII. If your program naturally lends itself to object graphs with cycles, that points strongly towards a garbage collected language. (Though personally I have never found that reference counting versus garbage collection has been the most important difference between two languages anyway, and the only language I'm aware of that really supports RAII is C++, so it's not like you'll ever make a straight-up decision between RAII and garbage collection without a ton of other very strong factors in play.)

That's why GC is not acceptable for these resources that are not buffers of memory.

Not to be pedantic... okay, I'm being pedantic ;-) but GC can be used for any set of resources that are linked the way objects in memory are. For example, the database guys at my last job wrote an ad-hoc garbage collector when they realized that buggy triggers had left a ton of orphaned rows in our database.