Partial classes support

Propose new features and changes
ThePeter
Posts: 49
Joined: 25 Oct 2022, 05:57

Partial classes support

Post by ThePeter » 29 Nov 2022, 05:28

I have been trying to find earlier discussion on this, but could not find but some very old threads:

https://www.autohotkey.com/board/topic/65475-class-definition-syntax-for-autohotkey/page-2
viewtopic.php?t=2208

As far as I can see, partial classes are not currently supported by AHK. Having partial classes (preferably with an explicit keyword distinguishing them from erroneous naming conflicts) would facilitate splitting large classes into different files. I am aware that it is possible to do it as this:

Code: Select all

class Foo {
    #Include Bar.ahk
    #Include Baz.ahk
}
However, this is not exactly elegant as the included files will in themselves not have any reference to the class they are defining.

Are there any plans or chances that partial classes will be implemented?

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Partial classes support

Post by swagfag » 30 Dec 2022, 18:20

reading up on partial in C#, it seems it has 2 use-cases:
  1. separate codegenerated code - this maybe needed in C#, but isnt in ahk since #Include exists
  2. facilitate splitting large classes into different files - or u can just refactor the class to not be as big in the first place, into other smaller classes. arguably the better design choice anyway
and there was also one guy alleging it was to aid in resolving merge conflicts in a since discontinued, abysmally performing sourcecontrol tool microsoft were developing at the time(which sounds plausible enough, but im not counting this in)

so whats the point of developing, documenting, testing and maintaining a feature with such questionable(at best and downright antipatterns at worst) benefits?

lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Partial classes support

Post by lexikos » 30 Dec 2022, 19:19

I hadn't posted or done anything about partial class support because it just doesn't seem useful enough.

I personally don't like the keywords partial class, because to be semantically correct, the parser must require that there is more than one partial class. Other ideas like extends class x or class x extended imply that the parts must be defined in a specific order. This restrictions would add to code and documentation size while providing little or no benefit. The alternative is to not enforce restrictions based on correct English, and deal with the consequences. (Arguments about #IncludeAgain come to mind.)

In C#, partial is required to appear on all parts of the class. Ruby has the concept of "open classes", which, for instance, could allow you to define extensions to the built-in classes directly using class syntax instead of assignments/DefineProp. (I think the concept is basically that all classes are open, or that class x "opens" a class, not necessarily defining a new one.)
However, this is not exactly elegant as the included files will in themselves not have any reference to the class they are defining.
I think it is elegant to use a simple language feature for the purpose it was intended; splitting a large script into a set of smaller files.

The code within the class has the same behaviour regardless of whether it is physically located in the same file or not. I assume that by "reference to the class" you mean that the code will not be enclosed by class ClassName {...}. I don't think I would describe this repetition as being less elegant. If you want the file to show which class the methods belong to, you can simply write a comment, or it can be implied by the filename.

Depending on personal style, enclosing the file's content in partial class ClassName {...} probably also implies an extra level of indentation across the whole file, or a small inconsistency to code style. I would consider that a drawback.

Perhaps more importantly, the use of #Include in a class prevents AutoHotkey2 LSP (and likely similar tools) from correctly deducing scope, providing relevant auto-completion options, identifying methods as methods (not functions), etc.

ThePeter
Posts: 49
Joined: 25 Oct 2022, 05:57

Re: Partial classes support

Post by ThePeter » 31 Dec 2022, 04:20

I understand that code elegance is in the eye of the beholder. I also understand that this feature is not exactly a vital requirement for anything. I would find it useful for maintaining code in a way that I personally would perceive as more elegant. From your answer, @lexikos, it seems that there are no directly detrimental effects of implementing this besides a certain discomfort concerning "correct English" (again, this is in the eye of the beholder; I personally like the C# style in this case).

In the end, it comes down to how much effort this is to implement. If it is a non-trivial operation, then this certainly does not deserve a top spot on the priority list.

lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Partial classes support

Post by lexikos » 31 Dec 2022, 20:26

In the end, it comes down to how much effort this is to implement.
Not at all. It is purely about choosing syntax and exactly what restrictions would be enforced. Additional syntax and restrictions means larger code and documentation, and perhaps more for users to learn. Of all options I have seen or considered, the only one I personally like is to just relax an existing restriction, without adding any new syntax:
Merge classes implicitly if they have the same name. However, it might be more intuitive to detect "duplicate class definitions" as errors.As I mentioned in my example, "class Foo" would actually introduce a variable "Foo" and store a prototype object inside it. (When I say "prototype object", I mean an ordinary object which will be used as the base/prototype of another object.) Each var or method declaration would store a value (the var's initial value or a reference to a function) in the object. (Actually, I mentioned that in the example.) Thus, classes wouldn't be "merged" so much as the second "class Foo" would simply resolve to the same variable and continue to store values in the original prototype object.
Source: Class definition syntax for AutoHotkey - Page 2 - Offtopic - AutoHotkey Community
That would most likely require just a couple of minor changes in Script::DefineClass. Actually, it looks like I already considered that and left comments at the appropriate places:
source/script.cpp#L6009-L6012
source/script.cpp#L6038-L6044

There are multiple options, and each one theoretically has drawbacks. When I say "it just doesn't seem useful enough", I suppose what I mean is that I care too little about either the benefits or the drawbacks to choose any option other than the one already implemented.

ThePeter
Posts: 49
Joined: 25 Oct 2022, 05:57

Re: Partial classes support

Post by ThePeter » 01 Jan 2023, 14:43

I am conflicted about this. For me personally, it would indeed be the nicest solution to just relax the restriction. Undoubtedly, however, this increases the danger of accidental duplicates. I do not dislike the variant in your old comment "Class Foo continued".

Post Reply

Return to “Wish List”