Estrita
Paradigm(s) | imperative |
---|---|
Designed by | User:Aadenboy |
Appeared in | 2024 |
Computational class | Turing complete |
Major implementations | None |
Influenced by | Lua, TypeScript |
Influenced | None |
File extension(s) | .est |
Estrita (Portugese for Strict) is a parody of TypeScript, being a superset of Lua 5.4 with very strict typing, something Lua is known for not having. Estrita programs are transpiled into Lua programs, but only in a way such that it is unnecessarily obfuscated and unmaintainable, forcing you to continue using Estrita instead of switching over to the new Lua program.
Variable Typing
All newly declared variables require that you provide a valid type after the type declaration operator and before the value assignment operator.
local a = 5 -- Compiler Error: Missing type declaration
local a: number = 5 -- Valid
The variable must then adhere to its declared type for its lifespan. The type may not be redeclared.
a = 7 -- Valid a = "Hello, World!" -- Compiler Error: Cannot assign type 'string' to type 'number'
The only type that you may not use is nil
. Instead, you must declare the type to be optional with a question mark. This is the only way to have the type of a variable be of two options, any other combination is not allowed (i.e. no string or number
).
local b -- Compiler Error: Nil declaration is not allowed local b: nil -- Compiler Error: Nil declaration is not allowed local b: boolean? -- Valid -- All valid b = true b = false b = nil
any
is not a valid type. There is no way to give a variable an any
-like type.
Tables and Schemas
Tables are defined separately from other types. Instead of simply using table
, you must define a schema (and no, an empty schema is not allowed). Like with type declarations, table schemas cannot be redeclared. If no index is provided, it is assumed to be the first available numerical index. You can use existing values as indexes as well.
local account = {name = "John", balance = 500, id = 1} -- Compiler Error: Missing table schema
local account: table = {name = "John", balance = 500, id = 1} -- Compiler Error: Schema provided is invalid
local account: {name = string, balance = number, id = number} = {name = "John", balance = 500, id = 1} -- Valid
local inverse: {[true] = boolean, [false] = boolean} = {[true] = false, [false] = true} -- Not practical, but valid
local checklist: {boolean, boolean, boolean, boolean} = {false, false, true, false} -- Valid
Variable length tables are declared by placing a type in place of the index. You can also use ...
for arrays.
local record: {[string] = boolean} = {jan1 = true, mar4 = true}
local array: {number, ...} = {1, 2, 3, 4, 6}
Note that for arrays, every value sequentially is expected to match the type. This accounts for nil
.
local array2: {number, ...} = {1, nil, 3} -- Compiler Error: Table provided does not follow schema local array2: {number?, ...} = {1, nil, 3} -- Valid
...
can also be a fixed length.
local array3: {[-5] = number?, ..., [0] = number?, ..., [5] = number?} = {[-1] = 1, [0] = 0, [1] = -1} local array4: {..., [1] = boolean?} = {[-5] = true, [-3] = true, [1] = true}
Schemas can be reused from a previous table simply by referencing the table. This also works when nesting.
local becky: account = {name = "Becky", balance = -10, id = 2}
local accounts: {account, ...} = {account, becky, {name = "Gerald", balance = 0, id = 3}}
Functions
Functions follow similar structure, where its inputs have type declarations and the output has its own type declaration.
function foo(x: number, y: number): number return x^y end
Unlike variables and schemas, functions are allowed to declare their output as nil
.
function log(message: string): nil print("Log @"..tostring(os.time())..": "..message) end
There is also a new never
data type for functions that signifies that the program will never halt, or will never continue execution after the function (i.e if os.exit()
is called). This data type is however only available to those who have the balls to solve the Halting problem.
function forever(): never while true do end end -- Compiler Error: type 'never' is not implemented in this compiler
Tuples are declared with commas. A semicolon is required at the end.
function baz(message: string): number, ...; local set: {number, ...} for i: number = 1, #message do table.insert(set, message:sub(i, i)) end return table.unpack(set) end
Global Scope
Global scope variables are illegal—new variables MUST be declared as local
. If you really need to declare a global variable, it must be explicitly declared in _G
.
_G
uses the schema _G: {[string] = table, _VERSION = number, arg = {string, ...}, (and so on)}
. All previous values that aren't a table are granted an exemption in the schema. If you wish to add new values, it must be done so within a table as you cannot modify the schema.