RFC: Formal Type System #5438
Replies: 12 comments 3 replies
-
AFAIK, we don't have a mechanism to list overloads of a function. The argument types are checked(even optionally) with some hard coded rules when instantiating the Do you have any idea about this? |
Beta Was this translation helpful? Give feedback.
-
I prefer to add an additional method in In the future, we may automatically generate the signature. |
Beta Was this translation helpful? Give feedback.
-
An extra method to list the function signatures is a good idea. But some aggregate/scalar functions support variadic arguments, eg: StarRocks used a python config file to save the signatures, but I think it's not a good idea to save it in other lang. |
Beta Was this translation helpful? Give feedback.
-
can variadic arguments be treated as |
Beta Was this translation helpful? Give feedback.
-
I'm afraid not. Variadic arguments may not be the same type. Even they are same type T, Maybe we can ignore these variadic cases and just throw the hard code error message to users if type mismatch. |
Beta Was this translation helpful? Give feedback.
-
In addition to |
Beta Was this translation helpful? Give feedback.
-
Is it |
Beta Was this translation helpful? Give feedback.
-
yes, we can treat it as |
Beta Was this translation helpful? Give feedback.
-
Added |
Beta Was this translation helpful? Give feedback.
-
Convert this RFC to discussions for better communication. @andylokandy We can create a tracking issue if we have tasks to track. In which, we can refer to this RFC. |
Beta Was this translation helpful? Give feedback.
-
Will we have |
Beta Was this translation helpful? Give feedback.
-
No overlap seems like a very strong restriction. |
Beta Was this translation helpful? Give feedback.
-
RFC: Formal Type System
Motivation
Type Definition
Except for the obvious primitives and generic container types, there are a special
Any
, which is the supertype of all other types, and aHole
, which is the subtype of all other types and has no instance value (void type).Variadic
type is similar toArray<Any>
and only used in variadic functions.Boolean
Array<T>
Any
Hole
String
Nullable<T>
Date
Timestamp
Object
Variant
Variadic
UInt8
UInt16
UInt32
UInt64
Int8
Int16
Int32
Int64
Float32
Float64
Type Check Mechanism
The type information that helps detect type errors is mostly from function signature. Let's consider the following expression:
The type checker will firstly desugar it into a function call:
and the type checker can easily infer that:
also, the function
plus
has some overloads:we can easily find that
plus(Int8, String)
doesn't unify with any of the overloads, so the type check can raise an error stating that:On the other hand, a function can accept a more general type as an argument, and the type checker can check if the argument upcasts to the function's parameter type.
Consider the following definition of function
is_null
:The type checker should proof that
String
can be upcast toNullable<Any>
, and thus the following expression should be valid:The detailed upcast rule will be explained in the following section.
Upcast Rule
There are only a few rules necessary to define sound and complete subtype relations ('
A
is a subtype ofB
' is equivalent to 'A
upcasts toB
'):Self Reflexity
All types are subtype of itself:
Top Type
All types can be upcast to
Any
:Bottom Type
Hole
can be upcast to any type:Introduce Nullable
Type can be wrapped by nullable (which means to drop the guarantee that the type is not null):
Covariant
Nullable<T>
upcasts toNullable<U>
if and only ifT
upcasts toU
. Same asArray<T>
.Transitivity
If
T
upcasts toS
andS
upcasts toU
, we infer thatT
upcasts toU
.Number coercion
Special literal type
number literals use the fittest type:
Example
Given a function definition of
is_all_null
:then check the following expression:
and because we know the type of literal
['foobar']
:now we can start trying to prove that
Array<String>
upcasts toArray<Nullable<Any>>
:Function Overload
A function can have multiple overloads. The type checker will try to find the most specific overload to check the function call.
Function overloads must not be ambiguous, which formally speaking is that there must be at most one overload that can be used to check the function call for every possible input type.
We have an exception rule about allowing ambiguous overloads. Consider the following example:
It's obvious that the latter overload is more specific than the former overload, which means for a function call
foo(TRUE, 'abc')
the type checker can use the latter overload. So ambiguity is allowed in this case.In general, there are two forms of forbidden ambiguous overload:
Unrelated overlap
Since
Array<Int8>
upcasts to bothNullable<Array<Int8>>
andArray<Any>
, for an input value with typeArray<Int8>
the type checker can't decide which overload to use. So an error will be raised.Unordered overlap
For a function call
foo(TRUE, TRUE)
, the type checker can not decide which overload to use. So an error will be raised.Checking ambiguity
Ambiguity is checked once the function overloads are registered. To check ambiguity, the type checker will compare the overlap of parameters.
The following cases are allowed:
and the following cases are forbidden:
To test overlap, we use the following rules:
T
andU
.T
andU
, by reversely applying the upcast rule, but don't use the rule oftop-type
,bottom-type
, andself-reflexity
.T
upcast toU
,T
overlap withU
, and vice versa.Example
Let's think of the example we've seen before:
To see if they are ambiguous, we need to test if
Nullable<Array<Int8>>
andArray<Any>
overlap. And at first, we generate their subtypes:since
Array<Int8>
upcasts toArray<Any>
, we proved they overlap.And since
Nullable<Array<Int8>>
andArray<Any>
aren't subtypes of each other, it's a forbidden case.Runtime Types
The types described above all have related runtime types (physical type). For example,
Boolean
is related to runtime typeBoolScalar
,BoolArray
.If
T
upcasts toU
, it's guaranteed thatimpl From<T::RuntimeType> for U::RuntimeType
.Detailed designs are still under investigation. So currently the type checker is only a linter.
Beta Was this translation helpful? Give feedback.
All reactions