Open Thirumalai-Shaktivel opened 2 weeks ago
Assign: @tanay-man
Let's do this.
from lpython import i32, TypeVar
test = TypeVar("test")
class test:
x: i32 = 0
y: i32 = 0
def __init__(self: test, x: i32, y: i32):
self.x: i32 = x
self.y: i32 = y
# StrucTypeConstrutor(3, 3)
t2: test = test(3, 3)
Another example:
from lpython import i32, TypeVar
test = TypeVar("test")
class test:
kind: str = "abc"
def __init__(self: test, name: str):
self.name = name
t1: test = test("1")
t2: test = test("2")
print(t1.kind)
print(t2.kind)
t2.kind = "d"
print(t1.kind)
print(t2.kind)
print(t1.name)
print(t2.name)
Instead of:
from lpython import i32, TypeVar
test = TypeVar("test")
class test:
x: i32 = 0
y: i32 = 0
def __init__(self: test, x: i32, y: i32):
self.x: i32 = x
self.y: i32 = y
# StrucTypeConstrutor(3, 3)
t2: test = test(3, 3)
I recommend doing this:
from lpython import i32, TypeVar
test = TypeVar("test")
class test:
def __init__(self: test, x: i32, y: i32):
self.x: i32 = x
self.y: i32 = y
# StrucTypeConstrutor(3, 3)
t2: test = test(3, 3)
The first are class variables, the second are instance variables. Let's focus on instance variables first.
The TypeVar
is causing conflicts in the symbol table as both the Struct
and TypeVar
have the same names.
I think we should have just one "test" in the symbol table, which represents the class definition, it will be of type Struct.
And the corresponding StructType will be the type of the first argument self
.
I agree the problem is since TypeVar has the same name, we cannot add Struct (class definition) to the symbol table.
What does LPython currently put into the symbol table for test = TypeVar("test")
?
It seems it should just keep note of this variable internally in AST->ASR, but not expose it in ASR. The test
variable will be only put into the symbol table once the class test
is processed. The test = TypeVar("test")
line is just a crutch that we use to make it work with CPython.
What does LPython currently put into the symbol table for
test = TypeVar("test")
?
ASR before adding the Struct
node :
(TranslationUnit
(SymbolTable
1
{
__main__:
(Module
(SymbolTable
2
{
test:
(Variable
2
test
[]
Local
()
()
Default
(TypeParameter
test
)
()
Source
Public
Required
.false.
)
})
__main__
[]
.false.
.false.
),
main_program:
(Program
(SymbolTable
5
{
})
main_program
[]
[]
)
})
[]
)
I see, the test = TypeVar("test")
is a Variable of type TypeParameter
which is used for templates. Then in CPython this test
gets shadowed. We could shadow it the same way. But why not use the simpler:
class test:
def __init__(self: "test", x: i32, y: i32):
self.x: i32 = x
self.y: i32 = y
self
would of type: TypeParameter
or Class
or Struct
??
Can we treat self
as a special argument? Whenever a function is declared inside a class, it can either have no arguments (if it's a static method) or at least one argument. We can assume the first argument to be a pointer to the object, and therefore, of the type of the class. Can we exempt the first argument from the type annotation requirement? We can treat self
as this
in lfortran.
@tanay-man is suggesting the following example:
class test:
def __init__(self, x: i32, y: i32):
...
I think we can skip the
__init__()
It has to be represented as a StructTypeConstructor, the class_constructor will take care of the rest.