A cat is just an untyped group of data objects. Structurally, a cat is a chunk with chunk id "cat " containing a "contents type" ID followed by the nested objects. The ckSize of each contained chunk is essentially a relative pointer to the next one. CAT ::= "CAT " #{ ContentsType (FORM | LIST | CAT)* } ContentsType ::= ID - a hint or an "abstract data type" ID In reading a cat , like any other chunk, programs must respect its cksize as a virtual end-of-file for reading the nested objects even if they're malformed or truncated. The "contents type" following the cat 's cksize indicates what kind of forms are inside. so a cat of ilbms would store "ilbm" there. it's just a hint. It may be used to store an "abstract data type". A CAT could just have blank contents ID (" ") if it contains more than one kind of form. cat defines only the format of the group. the group's meaning is open to interpretation. This is like a list in LISP: the structure of cells is predefined but the meaning of the contents as, say, an association list depends on use. If you need a group with an enforced meaning (an "abstract datatype" or Smalltalk "subclass"), some consistency constraints, or additional data chunks, use a composite form instead (cf. Composite FORMs). Since a cat just means a concatenation of objects, cats are rarely nested. Programs should really merge CATs rather than nest them.