Separate Type entities and the type information about them #14
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
For each type there will be the explicit conversion method, and the type object itself. These must be different, because generic types are callable as functions:
Complex(BigNumber)
, for example, will produce a high-precision complex number type. This leads to some questions:(A) I am unclear on whether we will need separate methods for type predicates: we will be able to write
math.BigNumber.test(x)
to determine ifx
is a BigNumber, so do we also need something likemath.isBigNumber(x)
?(B) I am pretty sure we want to stick with
number
,boolean
,string
, etc. as the explicit conversion methods. So to keep them closely associated, I was going to call the type objectsNumber
,Boolean
,String
, etc. However, I just had a confusing bug because those names are already used in standard JavaScript (exactly for its explicit conversion operators). So I would like to use different names. What should they be?For now in the prototype I am going to:
(A) assume the answer is no, we don't need type predicates aside from
TheType.test(x)
(B) name type objects corresponding to built-in types (only), where the preferred type object name is already in use, by adding a
T
suffix to that:NumberT
,BooleanT
, etc.However, I would definitely be happy to have feedback on these issues, and it will be no problem to change over to any better system should we come up with one.
(A) I have no strong opinion in this regard. I prefer to have 1 way to do things though.
(B) Is it needed to create type objects on top of the primitive types (which are already built in)? If so, it will be good indeed to give them a different name. Maybe
NumberType
? The abbriviationNumberT
looks a bit "magic".(A) OK, I will leave this aspect as is: to explicitly check if x is of type Foo, call Foo.test(x). It has barely come up so far, so it seems OK.
(B) Well, we record a lot of information about each type: what automatic conversions it supports; its zero, one, and/or nan elements if it has them; whether it is generic or concrete; how to specialize it if it is generic, etc. It seems convenient to keep all of that information on the type entities themselves, but if you prefer, we could keep a Map from the type entities to plain objects with all of that information. Then the test of whether something is a type entity would simply be whether it is a key in that Map, and so we could explicitly use the built-in entities
Number
andBoolean
as the type entities for the number and boolean types.The only slight complication in this alternate plan for (B) is when merging entities into a TypeDispatcher, we would have to institute some new explicit way of flagging that the item being registered is a type: right now since type entities are just instances of class Type, it just checks if the item is such an instance, and if so, registers it as a type. If the test for typehood becomes "has this entity been registered as a type?" then we must directly inform the TypeDispatcher that an entity being registered should be registered as a type rather than a method or property.
Let me know as soon as you have a chance whether you prefer the alternate plan for (B), since if so, I'd like to switch over as the next step. If you prefer to stay with a Type class as things are now, then we face the naming issue. I'd like to keep the names as short as possible, since they are used a lot in the code. So can you think of anything shorter than
NumberType
that's OK with you?TNumber
?Num
? (and in the latter case, thenBool
instead ofBooleanT
?)(A) 👍
(B) I have a strong feeling that it would be better to keep the data type itself and the type information about the data type separate from each other, but I don't have a full picture of the consequences of both ways right now. When keeping the "meta information" separate, we keep the data types clean and standalone, allowing to use both built-in types like
Number
andBigInt
in signatures, but also use 3rd partly libraries in a natural way, libraries like forBigNumber
andFraction
. I think it is quite doable but indeed in the type configuration likeNumberType
needs a way to configure the relation toNumber
because that will be used in type signatures. What do you think?Naming of type objectsto Separate Type entities and the type information about themOK, fine, I will switch to a scheme along the lines of
and just put in the TypeDefinition constructor some special property setting that the TypeDispatcher
merge
function can notice and therefore treat this item specially, registering a new type.👍