Is there any particular reason you can't do LISP in 18-bits?
No, as already commented, LISP can of course be done with any machine word size. It's just that a 36 bit word could hold all elements of a "CONS" (aka a pair), the core management object of LISP, on the computer LISP was developed for (*1).
On a 36 bit machine, any access to a list will always retrieve a CONS at once, whereas on an 18 bit machine two fetches are necessary. More so, a 36 bit register always holds a complete CONS, making a CONS atomic within the underlying hardware, all without further ado.
The address space was still 18-bits, so it's not memory size.
It's not about address length but encoding. In fact, the usable address space for 36 bit Lisp implementations was only 15 bits, good for 32 KiWords. This was quite fine in 1958 where even a top-end computer like the IBM 704 maxed out at 32 KiWords (*2).
A basic element of a list, a CONS, consists of two pointers:
- CAR - pointing to the list item and
- CDR - pointing to the next list entry
A pointer needs to be qualified, as it may point to another list (CONS), or a leaf (ATOM). A few bits are needed to be added to each pointer.
Now, the original LISP was developed on an IBM 704, a computer with 36 bit word size and 15 bit address size, which not only gave room nicely to hold two 15 bit address pointers plus the needed qualifiers, but also had instructions for easy access of these fields.
- 3 bits Prefix qualifier (CPR)
- 15 bits Decrement address (CDR)
- 3 bits Tag qualifier (CTR)
- 15 bits Address address (CAR)
In fact, LISP is much more tied to the 704 machine structure than one may expect, as these 4 fields are what a type A instruction looks like:
- 3 bit Prefix, the instruction
- 15 bit Decrement, an index to be used (*3)
- 3 bit Tag, selecting one or more index registers to be used
- 15 bit Address
This looks quite like a CONS, doesn't it? This was noted by the developers of the first implementation. More so as the 704 offered instructions to directly read or write (*4) each of these fields within a register. Almost as if the 704 was purposely constructed to support Lisp (*5).
Lisp was implemented using a set of Assembly language macros (*6) to access the fields within a CONS element: CPR, CDR, CTR and CAR. The macro to create a CONS-word from its fields was called CONS (*7). Everything else was constructed from there. CAR and CDR survived into later Lisp lingo as shorthand for the elements of a CONS.
_Update: When looking for some links to improve this, I found that the Wiki article about CAR and CDR offers a pretty detailed explanation of the origin.
Using this structure made CONS atomic machine words and not only allowed easy access and use of both pointers, but was also quite compact and performant. Later, non 704/709x based, 36 bit implementations had to use shift and masking operations to do the same. This lost the performance advantage, but still kept the atomic nature of a CONS.
And yes, all of this can be of course be done on an 18 bit machine. Except now a CONS will cover two (18 bit) words, effectively halving the available memory as now only even addresses are valid - or each and every access will need to include a shift operation to turn a CONS address into a memory address (*8).
Like so often it's not about an implementation being impossible, or the difference being huge, but the little advantage that will pay out big when done often enough - like with every access or iteration.
*1 - And was still good for quite some time after.
*2 - 32 KiWords may seem not much today, but it was exceptional at the time. For the 704, magnetic core memory was built from one or more 737 Magnetic Core Storage Unit, each delivering a whopping 4096 Words in a shell roughly the size of one of today's 19" racks (plus two racks for the controller). It would take 8 such units to populate a 15 bit address range. Not sure how many users/universities could have afforded such a large configuration.
Very early computing had much more in common with micro pioneers and their single boarders than one often imagines - high flying ideas, like Lisp, and puny hardware barely able to implement the basic version of that idea :)
*3 - Called Decrement as index values would be subtracted from a base address
*4 - Tag write was never implemented
*5 - Which may as well be part of the impression that Lisp is especially good on 36 bit (704) type machines.
*6 - The first implementation was in Assembly, what else?
*7 - Assembly can mimic other high level languages quite closely ... accepting a somewhat bent syntax might help :=).
*8 - Which might be not as much of an additional burden as the address had to extracted by masking anyway.