On Fri, Apr 14, 2023 at 1:15 PM Kenneth Knowles <k...@apache.org> wrote:

>
> Thanks for the discussion. Many good points. Probably just removing all
> the annotations is a noop to users, and will solve the "afraid to use
> experimental features" problem.
>
> Regarding stability, the capabilities of Java (and Python is much much
> worse) make it infeasible to produce quality software with the rule "once
> it is public it is frozen forever". But on the other hand, there isn't much
> of a practical alternative. Most projects just make breaking changes at
> minor releases quite often, in my experience. I don't want to follow that
> pattern, for sure.
>
> Regarding Danny's comment of not seeing this culture - check out any of
> our more mature IOs, which all have very high cyclomatic complexity due to
> never being significantly refactored. Adhering to in-place state
> compatibility for update instead of focusing on blue/green deployment is
> also a culprit here. I don't have examples to mind, but the point about the
> culture of stagnation came from my recent experiences as code
> reviewer where there was some idea that we couldn't change things even when
> they were plainly wrong and the change was plainly a fix.
>
> Often, it comes from corners like triggered side inputs where we simply
> never had a clear concept and so bringing things into alignment with a spec
> will break someone, by necessity. To be clear: I have not received pushback
> on that one (yet). Some other examples are
> https://s.apache.org/finishing-triggers-drop-data (breaking change
> necessary to eliminate data loss risk)
> https://github.com/apache/beam/issues/20528 (fix was too slow because we
> were hesitant to commit a breaking fix)
> https://github.com/apache/beam/pull/8134#pullrequestreview-218592801
> (left unsafe API in place, applied doc-only fix).
>
> But indeed, of all the issues I raised, the customer concern with
> `@Experimental` was the most important. We have had a few threads about it
> in the past, too, and it hasn't gotten better.
>
>  1. It does not have the intended effect (making users OK with evolving
> APIs and behavior to allow us to reach a high level of quality)
>  2. It has an unintended effect (making users afraid to use things which
> they should be happy to use)
>  3. We don't use it consistently (many less-safe things are not
> experimental, many totally stable things are experimental)
>
> Because of 3, if we don't have a feasible way to move to
> "evolving/unstable by default" in a way that users know and are OK with,
> then 1 is impossible. And so the only way to fix 2 is to just eliminate the
> annotation approach entirely and go with language conventions.
>

+1 to eliminating @Experimental as a Beam level annotation. That is the
simplest approach that will get us to a consistent state, and it will align
the goals and intentions of us with users'.


>
> Kenn
>
> On Wed, Apr 12, 2023 at 5:10 PM Ahmet Altay via dev <dev@beam.apache.org>
> wrote:
>
>> I agree with Alexey and Byron.
>> 1. We do not have any concrete evidence of our users paying attention to
>> any of those annotations. Experimental API that were in that state for a
>> long while are good examples. A possible exception is a deprecated
>> annotation. My preference would be to simplify annotations to nothing
>> (stable enough for use and will evolve backward compatibility), and maybe
>> deprecated annotations.
>> 2. If you all think that Experimental annotation is needed, Byron's
>> suggestion (more or less what we do today) but with some concrete life
>> cycle definitions of those annotations would be useful to our users. (An
>> example could be: experimental APIs either need to graduate or be removed
>> in X releases.)
>>
>>
>>
>> On Tue, Apr 4, 2023 at 9:01 AM Alexey Romanenko <aromanenko....@gmail.com>
>> wrote:
>>
>>> Great and long-to-wait topic to discuss.
>>>
>>> My personal opinion based on what I saw on different open-source
>>> projects is that all such annotations, like @Experimental or @Stable, are
>>> not usefull along the time and even rather useless and misleading. What
>>> actually play roles is artifacts publishing and public API despite how it
>>> was annotated. Once a class/method was published and available for users to
>>> use, it should be considered as “stable" (even if it’s not yet stable from
>>> its developers point of view) and can’t be easily removed/changed in the
>>> next releases.
>>>
>>> At Beam, we have a “good" example with @Experimental that was used to
>>> annotate many parts of code in the beginning of its creation but then
>>> perhaps forgotten to be removed whenever this code is already used by many
>>> users and API can’t be just changed despite of this annotation.
>>>
>>> So, I’m pro to dismiss such annotations and consider all public and
>>> user-available API as “stable”. If it’s needed to change/remove a public
>>> API then we should follow the procedure of API deprecation and final
>>> removing, at least, after 3 major (x.y) Beam releases. It should help to
>>> have the clear rules for API changes and avoiding breaking changes for
>>> users.
>>>
>>> —
>>> Alexey
>>>
>>>
>>> On 3 Apr 2023, at 17:04, Byron Ellis via dev <dev@beam.apache.org>
>>> wrote:
>>>
>>> Honestly, I think APIs could be pretty simply defined if you think of it
>>> in terms of the user:
>>>
>>> @Deprecated = this was either stable or evolve but the
>>> functionality/interface will go away at a future date
>>>
>>> @Stable = the user of this API opting out of changes to functionality
>>> and interface. For example, default options don't change for a transform
>>> annotated this way.
>>>
>>> Evolving (No Annotation) = the user is opting in to changes to
>>> functionality but not to interface. We should generally try to write
>>> backwards compatible code, but on the other hand the release model does not
>>> force users into an upgrade
>>>
>>> @Experimental = this functionality / interface might be a bad idea and
>>> could go away at any time
>>>
>>>
>>> On Mon, Apr 3, 2023 at 7:22 AM Danny McCormick via dev <
>>> dev@beam.apache.org> wrote:
>>>
>>>> *;tldr - I'd like "evolving" to be further defined, specifically around
>>>> how we will make decisions about breaking behavior and API changes*
>>>>
>>>> I don't particularly care what tags we use as long as they're well
>>>> documented. With that said, I think the following framing needs to be
>>>> documented with more definition to flesh out the underlying philosophy:
>>>>
>>>> *>  - new code is changeable/evolving by default (so we don't have to
>>>> always remember to annotate it) but users have confidence they can use it
>>>> in production (because we have good software engineering practices)*
>>>>
>>>> * > - Experimental would be reserved for more risky things*
>>>> * > - after we are confident an API is stable, because it has been the
>>>> same across a couple releases, we mark it*
>>>>
>>>> Here, we have 3 classes of APIs - "experimental", "stable", and
>>>> "evolving" (or alternately "undefined").
>>>>
>>>> "Experimental" seems clear - we can make any changes we want. "Stable"
>>>> is reasonably straightforward as well - we will only make non-breaking
>>>> changes except in exceptional cases (e.g. security hole, total failure of
>>>> functionality, etc...)
>>>>
>>>> With "evolving" is the idea that we can still make any changes we want,
>>>> but we think it's less likely we'll need to? Are silent behavior changes
>>>> acceptable here (my vote would be no)? What about breaking API changes (my
>>>> vote would be rarely)?
>>>>
>>>> I think being able to change our APIs is an ok goal, but outside of a
>>>> true experimental context we should still be weighing the cost of API
>>>> changes against the benefit; we have a problem of people not updating to
>>>> newer SDKs, and introducing more breaking changes will just exacerbate that
>>>> problem. Maybe my concerns are just a consequence of me not really seeing
>>>> the same things that you're seeing, specifically: "*I'm seeing a
>>>> culture of being afraid to change things, even when it would be good for
>>>> users, because our API surface area is far too large and not explicitly
>>>> chosen.*" Mostly what I've seen is a healthy concern about making it
>>>> hard for users to upgrade versions, but my view is probably just limited
>>>> here.
>>>>
>>>> My ideal framing for "evolving" is: an *evolving* API can make
>>>> breaking API changes between versions, but this will be rare and weighed
>>>> against the cost of slowing users' upgrade process. All breaking changes
>>>> will be communicated in our change log. An *evolving* API will not
>>>> make silent behavior changes except in exceptional cases (e.g. patching a
>>>> security gap, fixing total failures of functionality).
>>>>
>>>> Thanks,
>>>> Danny
>>>>
>>>> On Mon, Apr 3, 2023 at 9:02 AM Jan Lukavský <je...@seznam.cz> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> removing @Experimental and adding explicit @Stable annotation makes
>>>>> sense to me. FWIW, when we were designing Euphoria API, we adopted the
>>>>> following convention:
>>>>>
>>>>>   - the default stability of "evolving", @Experimental for really
>>>>> experimental code [1]
>>>>>
>>>>>   - target @Audience of API [2] (pipeline author, runner, internal,
>>>>> test)
>>>>>
>>>>>   - and @StateComplexity of operators (PTransforms) [3]
>>>>>
>>>>> The last part is something that was planned to be used by tools that
>>>>> can
>>>>> analyze the Pipeline for performance or visualize which transform(s)
>>>>> are
>>>>> most state-consuming. But this ended only as plans. :)
>>>>>
>>>>>   Jan
>>>>>
>>>>> [1]
>>>>>
>>>>> https://github.com/apache/beam/blob/master/sdks/java/extensions/euphoria/src/main/java/org/apache/beam/sdk/extensions/euphoria/core/annotation/stability/Experimental.java
>>>>>
>>>>> [2]
>>>>>
>>>>> https://github.com/apache/beam/blob/master/sdks/java/extensions/euphoria/src/main/java/org/apache/beam/sdk/extensions/euphoria/core/annotation/audience/Audience.java
>>>>>
>>>>> [3]
>>>>>
>>>>> https://github.com/apache/beam/blob/master/sdks/java/extensions/euphoria/src/main/java/org/apache/beam/sdk/extensions/euphoria/core/annotation/operator/StateComplexity.java
>>>>>
>>>>>
>>>>> On 3/31/23 23:05, Kenneth Knowles wrote:
>>>>> > Hi all,
>>>>> >
>>>>> > Long ago, we adopted two annotations in Beam to communicate to users:
>>>>> >
>>>>> >  - `@Experimental` indicates that an API might change
>>>>> >  - `@Internal` indicates that an API is not meant for users.
>>>>> >
>>>>> > I've seen some real problems with this approach:
>>>>> >
>>>>> >  - Users are afraid to use `@Experimental` APIs, because they are
>>>>> > worried they are not production-ready. But it really just means they
>>>>> > might change, and has nothing to do with that.
>>>>> >  - People write new code and do not put `@Experimental` annotations
>>>>> on
>>>>> > it, even though it really should be able to change for a while, so
>>>>> we
>>>>> > can do a good job.
>>>>> >  - I'm seeing a culture of being afraid to change things, even when
>>>>> it
>>>>> > would be good for users, because our API surface area is far too
>>>>> large
>>>>> > and not explicitly chosen.
>>>>> >  - `@Internal` is not that well-known. And now we have many target
>>>>> > audiences: Beam devs, PTransform devs, tool devs, pipeline authors.
>>>>> > Some of them probably want to use `@Internal` stuff!
>>>>> >
>>>>> > I looked at a couple sibling projects and what they have
>>>>> >  - Flink:
>>>>> >  - Spark:
>>>>> >
>>>>> > They have many more tags, and some of them seem to have reverse
>>>>> > defaults to Beam.
>>>>> >
>>>>> > Flink:
>>>>> >
>>>>> https://github.com/apache/flink/tree/master/flink-annotations/src/main/java/org/apache/flink/annotation
>>>>> >
>>>>> >  - Experimental
>>>>> >  - Internal.java
>>>>> >  - Public
>>>>> >  - PublicEvolving
>>>>> >  - VisibleForTesting
>>>>> >
>>>>> > Spark:
>>>>> >
>>>>> https://github.com/apache/spark/tree/master/common/tags/src/main/java/org/apache/spark/annotation
>>>>>  and
>>>>>
>>>>> >
>>>>> https://github.com/apache/spark/tree/master/common/tags/src/main/scala/org/apache/spark/annotation
>>>>> >
>>>>> >  - AlphaComponent
>>>>> >  - DeveloperApi
>>>>> >  - Evolving
>>>>> >  - Experimental
>>>>> >  - Private
>>>>> >  - Stable
>>>>> >  - Unstable
>>>>> >  - Since
>>>>> >
>>>>> > I think it would help users to understand Beam with some simple,
>>>>> > though possibly large-scale changes. My goal would be:
>>>>> >
>>>>> >  - new code is changeable/evolving by default (so we don't have to
>>>>> > always remember to annotate it) but users have confidence they can
>>>>> use
>>>>> > it in production (because we have good software engineering
>>>>> practices)
>>>>> >  - Experimental would be reserved for more risky things
>>>>> >  - after we are confident an API is stable, because it has been the
>>>>> > same across a couple releases, we mark it
>>>>> >
>>>>> > A concrete proposal to achieve this would be:
>>>>> >
>>>>> >  - Add a @Stable annotation and use it as appropriate on our primary
>>>>> APIs
>>>>> >  - [Possibly] add an @Evolving annotation that would also be the
>>>>> default.
>>>>> >  - Remove most `@Experimental` annotations or change them to
>>>>> `@Evolving`
>>>>> >  - Communicate about this (somehow). If possible, surface the
>>>>> > `@Evolving` default in documentation.
>>>>> >
>>>>> > The last bit is the hardest.
>>>>> >
>>>>> > Kenn
>>>>>
>>>>
>>>

Reply via email to