1. A method for composing programming abstractions, comprising: defining a composition operation for composing a first abstraction and a second abstraction with a selected composition operator; each abstraction having a form, a prefix, and at least one expression; unfolding the expressions from the first and the second abstractions by: (a) removing the prefix of each abstraction, and (b) substituting formal parameter names in each expression with a common parameter name to define open variables; transforming the unfolded expressions to a reduced expression using a composition pattern that tunes semantics of the selected composition operator; selecting a prefix that depends on the selected composition operator and the form of the first abstraction and the second abstraction; the selected prefix having a formal parameter with a type; and nesting the reduced expression in a third abstraction that composes the first abstraction and the second abstraction by: (i) appending the selected prefix to the reduced expression, (ii) binding the open variables of the reduced expression to the formal parameter of the selected prefix, and (iii) computing the type of the formal parameter of the selected prefix.