Kotlin / KEEP

Kotlin Evolution and Enhancement Process
Apache License 2.0
3.29k stars 357 forks source link

Split Classes #357

Closed cloewen8 closed 11 months ago

cloewen8 commented 11 months ago

Problem

I have an expect class that is responsible for reading, writing and performing various other tasks with a "receiver". This is defined with a class definition, followed by extensions. Although this functionally works, it makes functionality more difficult to organize.

Solution

I'd like to propose adding partial classes to resolve this, as inspired by C# partial classes. If the class keyword is followed by partial, all other Kotlin classes with the same signature and package should be merged at compile-time.

Most users know partial classes from C# for their use by generated classes to add additional functionality. They inherently have the same benefits as they would in C# by design:

  • When working on large projects, spreading a class over separate files enables multiple programmers to work on it at the same time.
  • When working with automatically generated source, code can be added to the class without having to recreate the source file.
  • When using source generators to generate additional functionality in a class.

- Microsft Learn

In addition for Kotlin:

Traits, Single-Responsibility and Dependency management

Many times it's nothing but an excuse to violate SRP.

For my use-case, reading and writing are the direct responsibility of a receiver. Although partial classes can be used to violate the Single-Responsibility principal, this is the fault of the developer, not partial classes.

Is this not somewhere where you'd use traits? Make your generated code a trait and just mix it into your normal class...

Traits can be used in some cases but they lack statefullness and further pollute the namespace.

adding partial classes REALLLLLLY brings in horrible issues when it comes to modularity/dependency management.

Externally, a partial class is no different from any other class. They can be treated as the same class externally. If a class exists with the same name and they are not to be merged as a partial class, this would be a compile-time error.

Alternatives

For expected classes there are no direct alternatives I am aware of (including traits, which do not have state). All expected methods need to be declared at once. A pseudo alternative I've used is to add extension methods to the expected class (and promise myself I'll use them in the actual class).

Partial classes have been discussed in multiple places:

cloewen8 commented 11 months ago

After further review it appears I missed a required protocol in the README. I'll close this issue for now and reopen it once remedied.