As Symfony grows, we do our best to formalize and document our processes to give a strong and clear promise to our users. One of them is our well-known Backwards Compatibility Promise.

This is great as it gives developers the confidence to upgrade to new versions safely and more often. It also acts as a great guideline for contributors and a safeguard when the core team reviews pull requests.

But sometimes, we want to introduce new features, and are not sure yet about their implementation. A no BC-break approach in this case can be dangerous, as we could be stuck with a bad API for years. In the early days, real-world usage is a great way to get feedback and possibly adapt the API. But since people won't test something that is not released yet, we're stuck.

For the LDAP component, we decided to mark it as experimental for the first minor version where it was introduced. And it was a great idea! We weren't sure about the API, and based on user feedback, we made quite a few changes for the next minor version and removed its experimental status.

After discussing the matter with some other core team members, we decided to officially add the notion of experimental features. The goal is not to mark all new features as being experimental. Instead, we will use it only for specific situations when it makes sense. For example, when a feature is big enough or when we are not sure of its API, we will use this new possibility. Another example would be when we are not sure if a feature would be widely useful (getter injection is one such example). Marking such a feature as being experimental would allow us to remove it in the next minor version. Any feature that is experimental will be clearly marked in the documentation, and its classes and methods will be tagged with @experimental.

To sum up, experimental features are for specific cases. Breaking backward compatibility is possible for them from one minor to the next. But as always, breaking changes should be handled with care and ample documentation should be added in the changelog.

I've also submitted a pull request on the docs about this.