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:
def __eq__(self, other: Self) -> bool: ...
......@@ -24,8 +24,6 @@ class float:
def __init__(self, x: object) -> None: ...
assert int.__add__
U = TypeVar("U")
V = TypeVar("V")
class slice:
pass
......@@ -37,12 +35,12 @@ class HasLen(Protocol):
def len(x: HasLen) -> int:
...
class Iterator(Protocol[U]):
class Iterator[U](Protocol):
def __iter__(self) -> Self: ...
def __next__(self) -> U: ...
class Iterable(Protocol[U]):
class Iterable[U](Protocol):
def __iter__(self) -> Iterator[U]: ...
class str:
......@@ -63,7 +61,7 @@ class bytes:
def decode(self, encoding: str) -> str: ...
def __len__(self) -> int: ...
class list(Generic[U]):
class list[U]:
def __add__(self, other: Self) -> Self: ...
......@@ -82,7 +80,7 @@ class list(Generic[U]):
assert [1, 2].__iter__()
assert list[int].__iter__
class dict(Generic[U, V]):
class dict[U, V]:
def __getitem__(self, key: U) -> V: ...
def __setitem__(self, key: U, value: V) -> None: ...
def __len__(self) -> int: ...
......@@ -93,24 +91,24 @@ assert(len(["a"]))
assert [1, 2, 3][1]
def iter(x: Iterable[U]) -> Iterator[U]:
def iter[U](x: Iterable[U]) -> Iterator[U]:
...
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
assert iter(["1", "2"])
def identity(x: U) -> U:
def identity[U](x: U) -> U:
...
assert identity(1)
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__
......
# coding: utf-8
from typing import TypeVar
T = TypeVar("T")
def dump(obj: T, fp: file) -> Task[str]: ...
\ No newline at end of file
def dump[T](obj: T, fp: file) -> Task[str]: ...
\ No newline at end of file
# 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(Generic[T]):
class Forked[T]:
def get(self) -> T: ...
class Task(Generic[T]):
class Task[T]:
pass
class Future(Generic[T]):
class Future[T]:
def get(self) -> Task[T]: ...
assert Forked[int].get
def fork(f: Callable[[], T]) -> Task[Forked[T]]:
def fork[T](f: Callable[[], T]) -> Task[Forked[T]]:
# stub
class Res:
get = f
......@@ -22,7 +20,7 @@ def fork(f: Callable[[], T]) -> Task[Forked[T]]:
assert fork(lambda: 1).get
def future(f: Callable[[], T]) -> Task[Future[T]]:
def future[T](f: Callable[[], T]) -> Task[Future[T]]:
# stub
class Res:
get = f
......
......@@ -14,7 +14,6 @@ def get_default_parents():
return [obj]
return []
class RuntimeValue:
pass
......@@ -24,6 +23,36 @@ class MemberDef:
val: typing.Any = RuntimeValue()
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
class UnifyMode:
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