1. Syntax symbols numbers conses and vectors comments special prefix tokens: ' ` , ,@ ,. other read macros: #. #' #\ #< #n= #n# #: #ctor builtins 2. Data and execution models 3. Primitive functions eq atom not set prog1 progn symbolp numberp builtinp consp vectorp boundp + - * / < apply eval 4. Special forms quote if lambda macro while label cond and or 5. Data structures cons car cdr rplaca rplacd list alloc vector aref aset length 6. Other functions read, print, princ, load, exit equal, compare gensym 7. Exceptions trycatch raise 8. Cvalues introduction type representations constructors access memory management concerns ccall If deliberate 50% heap utilization seems wasteful, consider: - malloc has per-object overhead. for small allocations you might use much more space than you think. - any non-moving memory manager (whether malloc or a collector) can waste arbitrary amounts of memory through fragmentation. With a copying collector, you agree to give up 50% of your memory up front, in exchange for significant benefits: - really fast allocation - heap compaction, improving locality and possibly speeding up computation - collector performance O(1) in number of dead objects, essential for maximal performance on generational workloads