On Sun, May 19, 2024 at 10:52 AM Andreas Heigl <andr...@heigl.org> wrote:
>
> Hey Robert.
>
> Am 19.05.24 um 09:38 schrieb Robert Landers:
> > On Sat, May 18, 2024 at 9:11 PM Andreas Heigl <andr...@heigl.org> wrote:
> >>
> >>
> >>
> >> Am 18.05.24 um 19:46 schrieb Robert Landers:
> >>> On Sat, May 18, 2024 at 7:38 PM Andreas Heigl <andr...@heigl.org> wrote:
> >>>>
> >>>> Hey all.
> >>>>
> >>>> Am 18.05.24 um 16:00 schrieb Robert Landers:
> [snip]
> >>> I guess that depends on what you mean by "break the code." Many people
> >>> turn warnings into exceptions, and for those people this will
> >>> effectively break their code. Some people may choose to ignore it one
> >>> way or another, but that would be up to them. The idea isn't to break
> >>> people's code though, it's to provide a way to mark very-malleable
> >>> APIs in libraries. Maybe, "Internal" is a bad name for this, but it's
> >>> the most logical.
> >>
> >> The trouble I see is that there are two kind of people: Those that care
> >> about such things and those that don't.
> >>
> >> Those that care about such things will already find these issues during
> >> static analysis.
> >>
> >> Those that don't care will not turn errors into exceptions but instead
> >> have error-reporting set to 0
> >>
> >> That's why I am hesitant in adding this to the engine but instead would
> >> love to see this as part of userland maintained static analyzers.
> >>
> [snip]
> > Hey Andreas,
> >
> > I don't think this is a useful way to look at it. Otherwise, what is
> > the point of making any error or warning? Static analysis is useful,
> > but there's a lot of things it misses, especially when dynamic calls
> > start happening.
>
> Probably the most interesting question is about our and the users
> expectation when declaring respectively using an internal entity.
>
> Is it's use something that should just pop up in the logs? And if so:
> What does it mean? Is using an internal entity outside it's expected
> usage actually an error? After all an error should be used when the
> application hits an issue preventing one or more functionalities from
> properly functioning. We can not really say that is happening just
> because someone uses a function in a place we do not expect it to be
> used. It might still work.

Indeed! The issue isn't that it works, it's knowing what to check very
carefully when updating vendored code. It also sets a reasonable
expectation that I can't complain that a maintainer broke something in
my code because I was doing something unsupported.

When it is only used in static analysis, it won't be noticed by people
not using static analysis.

>
> But from the point of view of the person declaring that internal entity
> muich more should happen. The code shouldn't work AT ALL any more.
> Someone is using my code in a way that I did not intend it to be used,
> so the whole application should break.
>
> But we can not assert that.

I disagree with this stance for many principled reasons.

If someone finds a class/method in library code useful, they should be
able to use it. Code reuse is important, and since the library code
could be licensed under the GPL while the main code is MIT or
unlicensed, the developer cannot simply copy the routine into the main
code. Further, they can't simply implement themselves now either,
because they've seen the licensed code.

Another issue I have with this stance is that if there is a major bug
in a library, I should be free to work around the issue by calling
"internal" code to ensure the state doesn't cause a crash in
production.

And yet another issue I have is that as a library author, I don't
really care how people use my code. It's none of my business. If it
works for them, great! I just want to be able to easily communicate
that some code may change unexpectedly between library versions.
Having something like this can be the difference between making huge
refactorings and improvements a patch release or a major release.

Code exists to solve problems, not create new ones and artificial
barriers because of ego.

Having this as part of the engine means that I know it is communicated
even if someone isn't using static analysis.

>
> So by having a look at the expectations of the different parties we can
> calibrate our intentions and then see how we can provide the best solution.
>
> And to me in that case the best solution would not be to enforce this on
> the language level but to leave it to static analysis. Because I know
> how inventive people can get to use things in ways they are not supposed
> to be used. Search for `composer unfinalize`...

Off-topic, but sharing this just to show my stance on this:

Final is an evil in library code, so I'm not surprised to see people
doing something like that, especially if final classes are used as
arguments to core library functions. It prevents authors from
attaching important metadata to objects, injecting failures during
tests, and ensuring application/business behavior is used -- and no,
composition cannot always solve this problem. I tend to find
alternatives if final gets in my way, or implement an alternative
myself.

>
> Cheers
>
> Andreas
>
>
>
> --
>                                                                ,,,
>                                                               (o o)
> +---------------------------------------------------------ooO-(_)-Ooo-+
> | Andreas Heigl                                                       |
> | mailto:andr...@heigl.org                  N 50°22'59.5" E 08°23'58" |
> | https://andreas.heigl.org                                           |
> +---------------------------------------------------------------------+
> | https://hei.gl/appointmentwithandreas                               |
> +---------------------------------------------------------------------+
> | GPG-Key: https://hei.gl/keyandreasheiglorg                          |
> +---------------------------------------------------------------------+

Reply via email to