value of "Type(Prototype)" not as expected

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
20170201225639
Posts: 144
Joined: 01 Feb 2017, 22:57

value of "Type(Prototype)" not as expected

24 Aug 2023, 02:19

[Moderator's note: Topic moved from Bug Reports.]

1. Type(Array.Prototype) evalutes to the string "Prototype"

2. According to the doc, Type(...) "Returns the class name of a value." It follows that "Prototype" must be a class name, and Prototype must be a class.

3. So Type(Prototype) should evalute to "Class". But it doesn't. Instead, an error is thrown ("This variable (=Prototype) has not been assigned a value")


(In all the other cases I've tested, if X is a possible output of Type(), then feeding %X% as input to Type() should evaluate to "Class". The first 6 msgboxes below all say "1", and I expect the 7th to say "1" as well, but it throws an error

Code: Select all

 
	Msgbox(Type(%Type([1,2,3])%)=="Class") ; 1
	Msgbox(Type(%Type("123")%)=="Class") ; 1 
	Msgbox(Type(%Type(56)%)=="Class") ; 1
	Msgbox(Type(%Type(Array)%)=="Class") ; 1
	Msgbox(Type(%Type(Class)%)=="Class") ; 1
	Msgbox(Type(%Type(Type)%)=="Class") ; 1
	
	Msgbox(Type(%Type(Array.Prototype)%)=="Class") ; error
)

(by the way I was surprised to find out Type(Array.Prototype) doesn't simply evaluate to "Array". I thought a class X's prototype property refers to the "prototypical" or "original" X so to speak, which would be a very special X because all other instances of X are based on it, but not *so* special that it wouldn't even be considered an instance of X (analogy: Adam and Eve are very special instances of Human, but not *so* special that they wouldn't even be instances of Human at all). However on reading the doc more carefully I saw that the prototype of a class is defined as "the object on which all instances of the class are based", not "... all OTHER instances ...", and after thinking a bit I guess it makes sense that the prototype of a class isn't itself an instance of it.)
lexikos
Posts: 9635
Joined: 30 Sep 2013, 04:07
Contact:

Re: value of "Type(Prototype)" not as expected

24 Aug 2023, 04:19

1. This is as per the implementation shown under "The algorithm for determining a value's class name can be approximated as shown below" in the documentation.

2. That sentence is a simple summary of the function. It is not the place for explaining corner cases. Perhaps the (less meaningful) "type name" should be used instead of "class name".

3.a. A prototype is neither an instance nor a Class. A Prototype cannot be an instance of Prototype. To be an instance of Prototype, it must derive from Prototype.Prototype, but the prototype of a class should be derived from the prototype of the super-class, as stated in the documentation:
A class's Prototype is normally based on the Prototype of its base class, so ClassObj.Prototype.base == ClassObj.base.Prototype.
Source: Class Object - Methods & Properties | AutoHotkey v2
Each class's Prototype is based on the Prototype of its base class, so x.HasBase(Object.Prototype) is also true.
Source: Objects - Definition & Usage | AutoHotkey v2
IIRC, "normally" was meaning "if you haven't changed it".

3.b. Your inference is based on the false assumption that for any "class name", there must exist a class in the global namespace. Where is this written in the documentation?

Code: Select all

x := {base: {__class: "There is no global."}}
MsgBox Type(x)

MsgBox Type(%Type(Gui().AddText())%)

If Prototype was a Class, x is Prototype should mean that x has all of the properties of Prototype.Prototype. It can't, because it inherits properties only from the Prototype of the base class.

If each Prototype was based on Prototype.Prototype, that would mean that all values would be based on Prototype.Prototype, because all values are based on a Prototype. That would make x is Prototype true for every value.

by the way I was surprised to find out Type(Array.Prototype) doesn't simply evaluate to "Array"
Array.Prototype is not an Array. None of the Array methods or properties will work on it. This is generally true for all prototypes. The constructors (__init and __new) are never called for a prototype, so the prototype cannot be a valid instance. (The built-in constructors can't be called for a Prototype because it simply doesn't have the right structure. All Prototypes must be able to have own properties, whereas not all values which inherit these properties can have properties of their own.)

If you want the class name of a value or prototype, you can just get value.__Class.
by the way I was surprised [...] However on reading the doc more carefully I saw [...]
So in short, you learned that some of your assumptions were mistaken. Perhaps you should learn from that, and question your assumptions more before posting a bug report.
20170201225639
Posts: 144
Joined: 01 Feb 2017, 22:57

Re: value of "Type(Prototype)" not as expected

25 Aug 2023, 21:59

Thanks, your explanation makes perfect sense.

1. Not only is Prototype not a class, but it could't possible be one, given how the class system is set up. I originally thought otherwise because (apart from "Prototype" being a possible value of Type()) the prototype is said in the doc to be an "object" (on which instances of the class are based), and I thought an object must be an instance of a class. However, I guess 'object' has both a wider sense (those for which IsObject(o) yields true) and a narrower sense (those for which (o is Object) yields true), and I was assuming incorrectly that it must be the narrower sense that's intended.

2. I guess a prototype of a class is more like an "incomplete" instance of it, that is completed to construct an instance of class each time the constructor is called. So Array.Prototype is not an Array, but more like a proto-Array.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: akirofe and 32 guests