Programming, the act of creating and changing software source code, should be a collaborative process between humans and computers. This dissertation shows a general approach and two techniques that bring us closer to this goal. The general approach is inspired by human programmers: they learn how to transform code by looking at similar past transformation instances, then they change new code by stringing together several fine-grained transformations.First, we give a technique for inferring abstract program transformations from concrete code examples. The transformations are expressed as formal rules in a term rewriting language with contexts, and they are inferred from examples via a novel anti-unification algorithm. For evaluation, we use the technique to successfully infer 15 JavaScript linting rules.Second, we give a technique for searching through compositions of program transformations to satisfy a goal. The search is an evolutionary algorithm with the fitness function defined over the code and the code transformations as mutations. For evaluation, we apply the technique to the problem of automatically translating imperative, sequential programs to functional MapReduce programs. The algorithm successfully finds efficient MapReduce implementations for programs with complex indirect accesses, such as WordCount.