The Traits package is at the center of all development we do at Enthought and has changed the mental model we use for programming in the already extremely efficient Python programming language. We encourage everyone to join us in enjoying the productivity gains from using such a powerful approach.

A trait is a type definition that can be used for normal Python object attributes, giving the attributes some additional characteristics:

* Initialization: A trait has a default value, which is automatically set as the initial value of an attribute before its first use in a program. * Validation: A trait attribute's type is explicitly declared . The type is evident in the code, and only values that meet a programmer-specified set of criteria (i.e., the trait definition) can be assigned to that attribute. Note that the default value need not meet the criteria defined for assignment of values. * Delegation: The value of a trait attribute can be contained either in the defining object or in another object delegated to by the trait. * Notification: Setting the value of a trait attribute can notify other parts of the program that the value has changed. * Visualization: User interfaces that allow a user to interactively modify the value of a trait attribute can be automatically constructed using the trait's definition.

Whether it's an application server or a desktop application, any sufficiently complex system is event-driven -- and that usually means callbacks.

Unfortunately, explicit callback management is to event-driven programming what explicit memory management is to most other kinds of programming: a tedious hassle and a significant source of unnecessary bugs.

For example, even in a single-threaded program, callbacks can create race conditions, if the callbacks are fired in an unexpected order. If a piece of code can cause callbacks to be fired "in the middle of something", both that code and the callbacks can get confused.

Of course, that's why most GUI libraries and other large event-driven systems usually have some way for you to temporarily block callbacks from happening. This lets you fix or workaround your callback order dependency bugs... at the cost of adding even more tedious callback management. And it still doesn't fix the problem of forgetting to cancel callbacks... or register needed ones in the first place!

The Trellis solves all of these problems by introducing automatic callbackmanagement, in much the same way that Python does automatic memory management.Instead of worrying about subscribing or "listening" to events and managingthe order of callbacks, you just write rules to compute values. The Trellis"sees" what values your rules access, and thus knows what rules may need to bererun when something changes -- not unlike the operation of a spreadsheet.