#parse("relnotes.vm")
#stdHeader("0.4", 9)

* Recommendation and Prediction API

  To support more types of recommenders easily, we have changed the
  way the dynamic recommendation and prediction components and their
  APIs work (#issue(109), #issue(110)).  These changes are
  backwards-incompatible; client code and implementations need to be
  updated for 0.4.

  * Introduced <<<ItemScorer>>>, an generalization of prediction that
    scores items for users.

  * Made <<<RatingPredictor>>> an <<<ItemScorer>>>, and deleted its
    <<<predict(...)>>> methods in favor of the item scorer methods.
    It now serves as a type-level indicator that a scorer returns
    predicted preferences as scores.

  * Removed dynamic interfaces in favor of putting the history-based
    methods directly in the <<<ItemScorer>>> and <<<ItemRecommender>>>
    interfaces.  An added <<<canUseHistory()>>> method on each
    interface indicates whether the history will be used or ignored.
    This greatly simplifies the inheritence hierarchy for recommender
    components.

  * Changed the behavior of item recommenders when a <<<null>>>
    exclude set is provided.  Previously, this was equivalent to the
    empty set.  It is now equivalent to a default exclude set which
    will be recommender-specific but generally a set of items the user
    is unlikely to need recommended (such as all items they have
    rated).  All recommenders have been updated with this change.

    The old design was easier to slightly implement but made less
    sense from a client API perspective.  The new design, where
    <<<null>>> is the default exclude set, makes the API cleaner (the
    fully-general method can use default exclude sets).  The loosened
    specification of default exclude sets also gives us greater
    flexbility for LensKit to be used as a basis for novel
    recommendation approaches.

  []

* Incompatible data structure changes

  To clean up APIs, we made a couple notable incompatible changes to
  layout and data structures.  These are all compile errors; no subtle
  behavior changes that the compiler won't catch here.

  * Moved <<<UserHistory>>> and related classes to the
    <<<org.grouplens.lenskit.data.history>>> package.

  * Removed <<<ItemRatingVector>>> and <<<UserRatingVector>>>, as they
    type distinction severely complicates configuration for
    generalized model builders.  The upside: types remain sane and
    configuring basket recommenders will be feasible.  Downside: the
    type system doensn't indicate whether a user vector contains
    ratings or some other data.

  []

* Other Changes

  * Changed <<<DynamicRatingPredictor.predict(long, Collection,
    Collection)>>> to take a <<<UserHistory>>> of events rather than a
    collection of ratings.

  * Made abstract recommenders and predictors uniformly expose the DAO
    as a protected final field.

  * Added methods to <<<DataAccessObject>>>, with default
    implementations in the abstract implementation, to allow user
    history objects to be directly retrieved for given users.

  * Added snapshotting as an explicit concept to the data layer.
    <<<DAOFactory>>> now has a <<<snapshot()>>> method, which is
    supposed to return an immutable snapshot of the data for
    test/build purposes.  Iterative algorithms still use rating
    snapshots, as they're faster and provide indexing, but this allows
    us to be more flexible in what kinds of data access recommender
    component builders can perform.  Factory implementations now need
    to provide a snapshot method; this can be done by simply creating
    an event collection DAO from the events.  Users with large data
    sets may want to use more exotic methods like database replication
    or transactions.

    The <<<JDBCRatingDAO>>> factory makes snapshotting configurable.
    By default, it assumes the database is unchanging; it can be
    configured to take an in-memory snapshot and return an
    <<<EventCollectionDAO>>>.

  []
