5 ms·
In further reflection, it is perhaps only because I am so used to TS that I try to make as intense of refactorings as I do. A programmer who does not have prior
by basil-rash 8y ago
In further reflection, it is perhaps only because I am so used to TS that I try to make as intense of refactorings as I do. A programmer who does not have prior experience working with as well tooled of a language would not be attempting the kinds of transformations I do, and thus may not experience as many issues.
- jnwatson 8y agoYou need `import typing`, and an editor with integrated mypy (e.g. vim). It is almost as good as static typing.
- basil-rash 8y agoInitial thoughts from looking through https://docs.python.org/3/library/typing.html# https://docs.python.org/3/library/typing.html#: 1. Love that it doesn't use structural typing, NewType seems great. 2. The syntax is bad. Maybe this is a "it just takes getting used to" thing, but I actually find it really bad. In TS, the syntax for typing almost always directly matches the syntax for the rest of the language. In Python, its a weird sort of LISPy DSL think that they made... compare: Py: Callable[[List[Tuple[int, string]], Dict[string, string]], int] TS: ([number, string][], { [key: string]: string }) => int This only gets worse as you chain callables together, whereas in TS everything left-associates as you'd expect and it all works out nicely. 3. Admittedly, the TS dict syntax isn't beautiful, but it becomes very helpful for things like `{ [K in keyof T]: K extends number ? T[K] : never }`, which does not seem to be possible in Py. 4. Related to 3, but no never type? I see NoReturn, but it does not seem to actually cause any errors when you try to assign it to a variable. See below. 5. Type narrowing... does it exist? Seemingly not, see below. 6. Literals as types (enums)? 7. Generics, do I really need to pass in the internal representation of the type I'd like to use? That seems absurd. Will bad things happen if these internal identifiers collide? (Reference: `T = Generic('T')` creates a generic type) Demo code that should throw an error at the assertUnreachable and nowhere else, but actually throws errors everywhere but the assert unreachable (types seemingly aren't narrowed by `type() == ...` checks): def foo(x: Union[str, int, float]): if (type(x) == int): return x / 3 if (type(x) == str): return x.upper() return assertUnreachable() def assertUnreachable() -> NoReturn: raise RuntimeError('no way') (this is all checked using mypy, v. 0.641)
- a1369209993 8y agoRegarding #2, the python code has the arguable advantage that (with appropriate variables in scope) it's valid standard python code[0] that could evaluate to (a representation of) the desired type, whereas the typescript isn't valid javascript code, and I don't think it's a valid (value-level) typescript expression either. 3 and 4 are disappointing though. 0: I'm assuming the extra [ after Callable is a typo.
- basil-rash 8y agoIs there a utility to having your types and your values in the same namespace? The extra [ is not a typo, the syntax is: `Callable[[Arg1Type, Arg2Type], ReturnType]`. Or, if the arguments don't matter, `Callable[..., ReturnType]`, but this does not mean that the type is not a valid expression. Edit: I was missing a ] actually, separating the arguments from the return value.
- a1369209993 8y ago> Is there a utility to having your types and your values in the same namespace? Well somewhat[0], but the main putative benefit would be having types be valid expressions in the target language, since you can do type-checking with function decorators, and generally interact with types useing the normal language mechanism for interacting with values, rather than some horrid bolted-on piece of crap like C++ templates. Server = Tuple[Address,ConnectionOptions] # array subscipt might not the best choice here, but it works UserId = NewType('UserId',int) # ordinary function call Scalar = int | str # could be equivalent to Union[int,str] with appropriate value of Type.__or__ 0: for example: def intBit(N): if N==0: return type(None) if N==1: return Bool if N>INT_WIDTH: return long return int
- basil-rash 8y agomypy's response to that code: error:invalid type comment or annotation note:Suggestion: use intBit[...] instead of intBit(...) So what's really happening is the type expressions are pretending to be "just everyday python", but actually they have arbitrary restrictions (cannot be functions? need to work via overriding `__getitem__`?) that neither you nor I were aware of. This is probably the least "pythonic" implementation possible. And even if the code were valid, it's relying on N being a statically known value, which is a bit off because sure, you could have N be some global const config variable, but it would be very weird for configuring the value of the variable to require you to also go into the code and change things around to work with bool's or None's instead of int's.
- talltimtom 8y agoIt sounds like you should invest some time in learning to program python in a pythonic way. If you are trying to build stuff using tons of design patterns factory patterns, you are doing it wrong. Most of those where made to work around limitations of type-systems which aren’t there in python, and naturally you end up having issues solving things like that when you don’t have typing. (Which you do still have with mypy, but as you say you’re not using that). At the end of the day you are using python and there must be a better way! though just like anything else you need to dedicate time to lean not just the syntax but also how to effectively use the language without needlessly over complicating things.
- basil-rash 8y agoI'm not trying to build using tons of factory patterns or the like, quite the opposite actually. I try to code as close to the bare language as possible, and work under the assumption that if I at some point would like to pivot my reasoning or approach to a program, the language and the tooling available will help me do so. This is simply not true without types. I'm not alone in thinking that, the creator of Python himself has devoted his recent work to adding types to Python. Is that just because he doesn't write his code "the correct way"? Does he simply know the syntax but not hoe to effectively use the language? I don't think so.