Thank you for your charitable assumptions. You might be even more charitable and state what's wrong with what I said.
My understanding is, 1, that every newly-created cons pair requires an allocation, 2, that every new list entry is a new cons pair, and 3, that you can avoid creating them but you have to keep a very careful eye on your code in order to do so - the normal way of writing code will cons frequently.
Which, of those statements, do you consider to be wrong, and why?
Every one of them. You do not understand the difference between what the program code does and what the programming language implementation does, and your underlying assumption is that there is a difference in how a Lisp runtime without garbage collection would manage memory allocation and how the C standard library manages memory allocation.
I am going to assume you need a stdlib.h refresher:
void *malloc(size_t size);
void free(void *ptr);
How do you think free works? How would you write a linked list implementation in C?I just happened to have done some software archaeology on a Lisp implementation without a garbage collector a while ago (https://github.com/vsedach/Thinlisp-1.1), and the memory allocation and lifetime management is exactly the same there as in C++ - manual management and dynamic extent regions (RAII).
Now I really want to get pedantic with each of your points, because individually each is wrong in interesting ways:
> 1, that every newly-created cons pair requires an allocation
This statement is a redundant tautology ("every new allocation requires an allocation"), but even the correctly phrased assertion that "CONS always allocates" is not always true:
https://en.wikipedia.org/wiki/Hash_consing
http://3e8.org/pub/scheme/doc/lisp-pointers/v1i3/p17-white.p...
> 2, that every new list entry is a new cons pair
Again, redundant, and again, not always true, because of hash consing and CDR coding:
https://en.wikipedia.org/wiki/CDR_coding
> 3, that you can avoid creating them but you have to keep a very careful eye on your code in order to do so - the normal way of writing code will cons frequently.
If you do not need to allocate lists, do not allocate lists. There is no "normal" way of writing code that exists outside of what your performance requirements are, what the language semantics are, and what the language implementation provides in terms of those semantics. The only situation where you cannot avoid frequent allocations is when all the data structures are immutable.
AnimalMuppet is basically right. Normal, everyday Lisp code does quite casually allocate memory: more or less of it depending on circumstances.
Implicit dynamic memory allocation occurs in places where in the analogous circumstances in C it wouldn't occur.
The abstract semantics of Lisp (such as ANSI CL) call for dynamic allocation of all lexical variable bindings, because in the abstract semantics, these have indefinite extent.
Each time a lexical scope with variables is entered, dynamic allocation takes place to create the fresh bindings, which enables continued access to these bindings after that scope's evaluation terminates.
Such allocation is only avoided as a matter of optimization: the Lisp compiler analyzes the scope to determine that no escaping closures are created in it and then the bindings can be allocated stackwise (dynamic extent) similarly to C's automatic storage.
Nothing in ANSI CL guarantees to you that (let (x)) will not allocate a piece of memory for x which endures after the form terminates, and has to be reclaimed.
> You do not understand the difference between what the program code does and what the programming language implementation does
False.
> I am going to assume you need a stdlib.h refresher
False, and even if I did, that wasn't much of one.
> How do you think free works?
I've seen an implementation.
> How would you write a linked list implementation in C?
I've had the pleasure (?) of doing so.
On to the meat of your reply: I was not aware of any non-garbage-collected Lisps. Still, isn't it fair to say that such Lisps are by far the exception?
I was under the impression that immutable was the normal way to write Lisp. ("Normal" here not meaning "the one right way" or "the way the language tries to make you write" - Lisp doesn't do that - but more "the way the majority of people write it".)
And even if you're going to not write it that way, if you really want to avoid allocations, don't you have to also be careful what library functions you call, since many of them cons?
The evidence is that you insist on posting a bunch of "I was under the impression" bullshit instead of spending a few minutes using a search engine. That is what is really annoying. Why do you think that your basic thesis that programs written under the assumption that there is garbage collection will not work well when there is no garbage collection is a novel or insightful contribution to the discussion about the original post?
Recently while reading, Appel's Compiling with Continuations, I read some mistaken claims about Lisp and scope, one doesn't have to be a troll, which requires intent, to make ignorant claims about Lisp, parsing or any subject. Although the amount of ridiculous arguments from people who clearly haven't used it (or at most used it very briefly) does make one's blood boil at times.
Here is another one I found looking for the quote I was remembering.
> "It has higher-order functions, meaning that a function can be passed as an argument and return as the result of another function – as in Scheme, C and Haskell, but not Pascal and Lisp.
I was not around but from the literature it seems Lisp trolls existed even back then - for example Ted Nelson's Computer Lib / Dream Machines contains some very negative and very mistaken statements about Lisp, and it was published in 1974.
> Lisp allocates all the time. You have to work hard if you want it not to. So if you want explicit allocation, you'd have to invoke it all the time, and it would really get in the way - far more than it does in C. (Far more things are allocated in Lisp than in C... Lisp, to my (very limited) knowledge, doesn't have a way to treat an allocated block of memory as anything other than a cons pair.
Between this comment and your ignorance of the difference between a PDP-10 and a PDP-11 I get the impression that you do not know anything about computer history or about Lisp or about what constitutes memory allocation. Please stop trolling.