DeepEvaluated = int | float | str | "String" | None | dict[string, "Evaluated"] | list["Evaluated"] | Function
Evaluated = int | float | "String" | None | dict[string, "Value"] | list["Value"] | "Function"

T = TypeVar('T', bound=Evaluated)

class Value:
    def __init__(self, x: Value | Evaluated | DeepEvaluated):
        """
        Make a new Value from python
        """
        ...
    def force(typeCheck=Evaluated: Literal[T]) -> T:
        """
        Force this value into the specified type (default Evaluated).
        Throws TypeError if this is impossible.
        """
        ...
    def forceDeep(self) -> DeepEvaluated:
        ...
    def __call__(self, *arg, **kwarg) -> Value:
        return self.force(Function)(*arg, **kwarg)
    def __int__(self) -> int:
        return self.force(int)
    def __str__(self) -> str:
        return str(self.force(str))
    def __float__(self) -> float:
        return self.force(float)
    def __len__(self) -> int:
        return len(self.force(dict[string, Value] | list[Value]))
    def __getitem__(self, i: int) -> Value:
        return self.force(list[Value])[i]
    def __getitem__(self, i: string) -> Value:
        return self.force(dict[string, Value])[i]
    def is_evaluated(self) -> bool:
        ...

class Function(Value):
    def __call__(self, arg: Value | Evaluated | DeepEvaluated) -> Value:
        pass

class String(Value):
    def __str__(self) -> str:
        ...
    @property
    def context(self) -> List[str]:
        ...

def evalString(x: string) -> Value:
    ...
    
 # TODO:
 # - attribute positions
 # - distinction between primops and functions
 # - paths vs strings vs contextful strings
 # - external types
 # - lambdas from python