Commit fd777ef8 authored by Tom Niget's avatar Tom Niget

Begin work on new generic system

parent 7198c941
donc en gros soit un type est concret et a des membres
soit un type est générique et contient une fonction qui génère une instance
Type :
- Concrete { members: Type[] }
- UserType
- FunctionType
- Generic { parameters: str[], concrete: str[] -> Concrete }
def f(x): # un type gen par paramètre
return x
Generic { parameters: ["T"], concrete -> FunctionType(... -> ...) }
f(5).bidule => instancier le type de f avec un TypeVar pour chaque paramètre
obtenir un type fonction concret rempli de TypeVar
évaluer et unifier
en fait dès qu'on utilise un type générique implicitement (e.g. appel fonction ou usage sans <> )
on en fait une instance en mettant une TypeVar pour chaque paramètre
def y_to_x(y):
return ...
class Container(Generic[T]):
x: T
def __init__(self, x): # implicitement __init__[S, X](self: S, x: X)
self.x = x
def get_x(self):
return self.x
def set_y(self, y): # implicitement set_y[Y](y: Y)
self.x = y_to_x(y)
Container : Generic {
param: ["T"],
concrete: [T] -> type(
"x": T,
"init": Generic { param: ["X"], concrete: [X] -> (X -> ()) }
"get_x": () -> T,
"set_y": Generic { param: ["Y"], concrete: [Y] -> (Y -> ()) }
)
}
x = Container(4) # ici on instancie Container avec un TypeVar donc on a `x: Container[A]`
# on récupère son __init__ qui est de type <S, X> (S, X) -> ()
# idem on instancie ce type avec deux typevars, B et C, donc init est (B, C) -> ()
# unifie B et type(x) => B=Container[A]
# unifie C et type(4) => C=int
# et on lit le corps de __init__ pour faire le reste de l'unification
# self.x est de type A, via l'assignation on unifie A=C=int
# donc x: Container[int]
from typing import Self, TypeVar, Generic, Protocol, Optional from typing import Self, Generic, Protocol, Optional
class object: class object:
def __eq__(self, other: Self) -> bool: ... def __eq__(self, other: Self) -> bool: ...
...@@ -24,8 +24,6 @@ class float: ...@@ -24,8 +24,6 @@ class float:
def __init__(self, x: object) -> None: ... def __init__(self, x: object) -> None: ...
assert int.__add__ assert int.__add__
U = TypeVar("U")
V = TypeVar("V")
class slice: class slice:
pass pass
...@@ -37,12 +35,12 @@ class HasLen(Protocol): ...@@ -37,12 +35,12 @@ class HasLen(Protocol):
def len(x: HasLen) -> int: def len(x: HasLen) -> int:
... ...
class Iterator(Protocol[U]): class Iterator[U](Protocol):
def __iter__(self) -> Self: ... def __iter__(self) -> Self: ...
def __next__(self) -> U: ... def __next__(self) -> U: ...
class Iterable(Protocol[U]): class Iterable[U](Protocol):
def __iter__(self) -> Iterator[U]: ... def __iter__(self) -> Iterator[U]: ...
class str: class str:
...@@ -63,7 +61,7 @@ class bytes: ...@@ -63,7 +61,7 @@ class bytes:
def decode(self, encoding: str) -> str: ... def decode(self, encoding: str) -> str: ...
def __len__(self) -> int: ... def __len__(self) -> int: ...
class list(Generic[U]): class list[U]:
def __add__(self, other: Self) -> Self: ... def __add__(self, other: Self) -> Self: ...
...@@ -82,7 +80,7 @@ class list(Generic[U]): ...@@ -82,7 +80,7 @@ class list(Generic[U]):
assert [1, 2].__iter__() assert [1, 2].__iter__()
assert list[int].__iter__ assert list[int].__iter__
class dict(Generic[U, V]): class dict[U, V]:
def __getitem__(self, key: U) -> V: ... def __getitem__(self, key: U) -> V: ...
def __setitem__(self, key: U, value: V) -> None: ... def __setitem__(self, key: U, value: V) -> None: ...
def __len__(self) -> int: ... def __len__(self) -> int: ...
...@@ -93,24 +91,24 @@ assert(len(["a"])) ...@@ -93,24 +91,24 @@ assert(len(["a"]))
assert [1, 2, 3][1] assert [1, 2, 3][1]
def iter(x: Iterable[U]) -> Iterator[U]: def iter[U](x: Iterable[U]) -> Iterator[U]:
... ...
assert iter assert iter
def next(it: Iterator[U], default: Optional[U] = None) -> U: def next[U](it: Iterator[U], default: Optional[U] = None) -> U:
... ...
# what happens with multiple functions # what happens with multiple functions
assert iter(["1", "2"]) assert iter(["1", "2"])
def identity(x: U) -> U: def identity[U](x: U) -> U:
... ...
assert identity(1) assert identity(1)
assert identity("a") assert identity("a")
def identity_2(x: U, y: V) -> tuple[U, V]: def identity_2[U, V](x: U, y: V) -> tuple[U, V]:
... ...
assert list.__add__ assert list.__add__
......
# coding: utf-8 # coding: utf-8
from typing import TypeVar def dump[T](obj: T, fp: file) -> Task[str]: ...
\ No newline at end of file
T = TypeVar("T")
def dump(obj: T, fp: file) -> Task[str]: ...
\ No newline at end of file
# coding: utf-8 # coding: utf-8
Generic: BuiltinFeature["Generic"]
TypeVar: BuiltinFeature["TypeVar"]
\ No newline at end of file
from typing import Callable, TypeVar, Generic from typing import Callable
T = TypeVar("T") class Forked[T]:
class Forked(Generic[T]):
def get(self) -> T: ... def get(self) -> T: ...
class Task(Generic[T]): class Task[T]:
pass pass
class Future(Generic[T]): class Future[T]:
def get(self) -> Task[T]: ... def get(self) -> Task[T]: ...
assert Forked[int].get assert Forked[int].get
def fork(f: Callable[[], T]) -> Task[Forked[T]]: def fork[T](f: Callable[[], T]) -> Task[Forked[T]]:
# stub # stub
class Res: class Res:
get = f get = f
...@@ -22,7 +20,7 @@ def fork(f: Callable[[], T]) -> Task[Forked[T]]: ...@@ -22,7 +20,7 @@ def fork(f: Callable[[], T]) -> Task[Forked[T]]:
assert fork(lambda: 1).get assert fork(lambda: 1).get
def future(f: Callable[[], T]) -> Task[Future[T]]: def future[T](f: Callable[[], T]) -> Task[Future[T]]:
# stub # stub
class Res: class Res:
get = f get = f
......
...@@ -14,7 +14,6 @@ def get_default_parents(): ...@@ -14,7 +14,6 @@ def get_default_parents():
return [obj] return [obj]
return [] return []
class RuntimeValue: class RuntimeValue:
pass pass
...@@ -24,6 +23,36 @@ class MemberDef: ...@@ -24,6 +23,36 @@ class MemberDef:
val: typing.Any = RuntimeValue() val: typing.Any = RuntimeValue()
in_class_def: bool = True in_class_def: bool = True
@dataclass(eq=False)
class BaseType(ABC):
pass
@dataclass(eq=False)
class TypeVariable(BaseType):
pass
@dataclass
class ConcreteType(BaseType):
fields: Dict[str, "MemberDef"] = field(default_factory=dict, init=False)
@dataclass
class GenericType(BaseType):
parameters: list[str]
def instanciate(self, args: list[BaseType]) -> BaseType:
raise NotImplementedError()
@dataclass @dataclass
class UnifyMode: class UnifyMode:
search_hierarchy: bool = True search_hierarchy: bool = True
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment