We'll call the library types, not type.

This commit is contained in:
aaron 2024-08-14 15:02:31 -07:00 committed by GitHub
parent 935d592aca
commit ee944a6117
Signed by: DevComp
GPG key ID: B5690EEEBB952194

View file

@ -54,7 +54,7 @@ To understand how type functions behave, we have to consider a split between sta
The key to making this type runtime work is the introduction of a `type` userdata that Luau's types can be serialized into. For clarity in this RFC, `type` (in code block) always refers to the userdata and type (the unadorned string) refers to the ordinary meaning of the word in the context of Luau (i.e. the static type of a binding). An instance of the `type` userdata is a type runtime representation of a type within the program, and it provides a set of API calls that can be used to inspect and manipulate the type. As part of the _type runtime_, they are *only accessible within type functions* and are *not available during ordinary function runtimes*. Each type function can take an arbitrary number of `type` arguments, and can return exactly one `type` as a successful result during evaluation. Returning additional results will signal an error to the user for now, but a future RFC may revisit this to support user-defined type pack functions as well. We are currently excluding them since the scope of this RFC is already very large as-is, and even the built-in type function system has yet to find a compelling use for type pack functions.
Because the name `type` clashes with the global function `type(...)`, the `type` userdata will set the `__call` metamethod will to the original `type(...)` function. This allows us to gracefully preserve the behavior of the built-in `type` function if it is necessary for developers, while still choosing the best possible name for the datatype itself. We considered alternative names like `luautype` `typelib` or `ltype`, but alternatives seemed to feel broadly worse when used in speech and writing.
Because the name `type` clashes with the global function `type(...)`, unlike `string` (whose library is named `string`), the name of the library for constructing `type`s will be `types`. So, a programmer will be able to access the boolean type by writing `types.boolean` or the number type by writing `types.number`. Evaluating `typeof(...)` on a `type` userdata will give the string `"type"`, and any possible extensions to support typechecking will likely name the type of types `type` as well. We considered an alternative where we used the name `type` and set the `__call` metamethod will to the original `type(...)` function. This would allow us to gracefully preserve the behavior of the built-in `type` function if it is necessary for developers, while still choosing the best possible name for the datatype itself, but it would also require the type runtime to provide a duplicate implementation of the `type(...)` function which would have to be maintained separately. We also considered alternative names like `luautype` `typelib` or `ltype`, but they seem to feel broadly worse when used in speech and writing, and have a similar disadvantage of being dissimilar from the existing library names in Luau.
Beyond `type`s, type functions will also reify any runtime errors that result from running their body into a type analysis error to report to the user. This means that developers can use the `error` and `assert` global functions to signal errors to consumers of their type function, and can provide detailed error messages that explain what went wrong. It also means that any "ordinary" runtime errors that arise from bad function calls or stack overflows will also become a user-facing error at the point that that type function is called.