While types are often used to constrain evolution, Spector's PushGP (Klein and Spector, 2007; Robinson and Spector, 2002; Spector, 2001; Spector, Klein, and Keijzer, 2005a) is a move away from constraining evolution.
Essentially PushGP uses genetic programming to automatically create programs written in the Push programming language. Push is a strongly typed tree based language which does not enforce syntactic constraints. Each of Push's types has its own stack. In addition to stacks for integers, floats, Booleans and so on, there is a stack for objects of type program. Using this code stack, Push naturally supports both recursion and program modules (see Section 6.1.1 ) without human pre-specification. The code stack allows an evolved program to push itself or fragments of itself onto the stack for subsequent manipulation.
PushGP can use the code stack and other operations to allow programs to construct their own crossover and other genetic operations and create their own offspring. Programs are prevented from simply duplicating themselves to deflect catastrophic loss of population diversity.