I know it’s called a type alias, but the type statement was presented as a replacement for the old type aliases, and there’s no language actually constraining it to only describing types. There is language that explicitly allows a lot of things you seem to want to be disallowed. If anything, it’s more accurately an annotation alias, with a couple caveats (mixing use of new and old type variables) in current specification language.
I’m not sure I agree with it remaining that way, the implications are different and I personally prefer the ones that only care about the type. Real world pragmatism here favors treating it almost as if it’s just templating the annotation where used, because people were already using it that way before the dedicated syntax. It also reduces the complexity of explaining how it works, and doesn’t require people try and figure out “what could annotated metadata bind to here”, it isn’t, it’s just being replaced in elsewhere in the program.
No, type aliases don’t allow arbitrary annotation expressions. The chapter on type expressions makes this clear. It specifies where type expressions are used, including:
The definition of a type alias (whether created through the type statement, the old assignment syntax, or the TypeAliasType constructor)
The TypeAlias special form and the type keyword were created as a way to define aliases for types. The resulting alias composes with other types, can be used in any type expression, and has a well-defined and unambiguous meaning wherever it’s used.
If we use the example @mikeshardmind provided above, the type alias Int64 has a clear and well-defined meaning in these cases.
@mikeshardmind, I think you’re arguing that there’s a need for more generalized aliasing mechanism — one that is not limited to types. Obviously, the runtime supports variables as the most general aliasing mechanism since a variable can represent any object. Are you looking for something that’s less restricted than type aliases but more constrained than variables? If so, what constraints would you want to place on these aliases?
In any case, there’s a good reason why type aliases are restricted to describing types.
Essentially, the argument is that this is an artificial limitation that doesn’t actually improve developer experience or reduce ambiguity.
I can agree on a matter of theory that field specifiers technically refer to a specific field and not a specific type, but I can’t agree that it’s useful to constrain type statements to disallow reusability. In many apis, fields have a reused behavior in many places, and are declared by annotation. I think as a matter of reducing complexity and improving developer experience, uses of Annotated values that refer to a variable and not a type should be assumed as an intentional reuse of the type and the value information, and an error should only be raised if that alias is used in a location that the attached information is known to be invalid.
Anything allowed in an annotation is allowed. Any use of the alias that results in the annotation being used as a value expression must be type-aware and access .__value__, anything that uses it as a type expression should use only the type information. (the gap here is already being bridged, The TypeForm pep should assist with the few places where there is a value expression accepting a typeform (such as type=... construction in validation libraries)
Can you elaborate on this? I don’t see the utility in this restriction if it is unambiguous. Warning on ambiguous use makes sense, but I can’t reconcile needing to repeat information that’s shared across uses and not ambiguous. There’s not even a way to compose the two that’s reusable:
type AGeneric[T] = Type1[T] | Type2[T]
ReusableYourWay = Annotated[AGeneric, ValueOrFieldData] # access to the generic has vanished
I think what @mikeshardmind said before about just allowing anything that’s allowed in an annotation is too much, but allowing all non-ambiguous use that is clear in what refers to a type and what refers to a field seems both acceptable and neccessary for ergonomic reuse.