Skip to content

Commit 0a98cde

Browse files
authored
feat: local vars section (#148)
* feat: local vars section * Update caveats.md * Update caveats.md * Update caveats.md * fix: prettier * fix: prettier * fix: wording
1 parent 4c4df25 commit 0a98cde

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

docs/caveats.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,71 @@ Even though iterating over object keys with `for ... in` does not guarantee orde
8282
### Iterating an array with `for ... in`
8383

8484
Not allowed.
85+
86+
### Local Variable Limit
87+
88+
In most cases, TSTL creates Lua code that declares variables using the `local` keyword, which makes the variables local to the function or block. In other words:
89+
90+
```ts
91+
const foo = 123;
92+
```
93+
94+
Usually gets transpiled to:
95+
96+
```lua
97+
local foo = 123
98+
```
99+
100+
In JavaScript/TypeScript, there is no limit to the amount of variables that you can create. However, in Lua, there is a limit of 200 local variables at any point in time. For big TSTL programs, this can be a problem, causing a run-time error in production that the compiler will not catch!
101+
102+
For example, imagine that a TSTL program consists of 101 individual features that are separated out into different feature classes, each in their own separate file. And upon program startup, all of the classes are instantiated:
103+
104+
```ts title=main.ts
105+
import { Feature1 } from "./features/Feature1";
106+
import { Feature2 } from "./features/Feature2";
107+
import { Feature3 } from "./features/Feature3";
108+
...
109+
import { Feature101 } from "./features/Feature101";
110+
111+
const FEATURE_CLASSES = [
112+
Feature1,
113+
Feature2,
114+
Feature3,
115+
...,
116+
Feature101,
117+
];
118+
119+
for (const featureClass of FEATURE_CLASSES) {
120+
new featureClass();
121+
}
122+
```
123+
124+
Since each transpiled import statement creates two separate local variables, this would create 202 local variables, and the program would immediately crash upon first being loaded.
125+
126+
You can solve this problem in a few different ways. For this specific pattern, we recommend using a [barrel file](https://basarat.gitbook.io/typescript/main-1/barrel), which is a file that contains only imports and exports. Specifically, our fixed program would look like this:
127+
128+
```ts title=featureClasses.ts
129+
export { Feature1 } from "./features/Feature1";
130+
export { Feature2 } from "./features/Feature1";
131+
export { Feature3 } from "./features/Feature1";
132+
...
133+
export { Feature101 } from "./features/Feature101";
134+
```
135+
136+
```ts title=main.ts
137+
import * as fc from "./featureClasses.ts";
138+
139+
const FEATURE_CLASSES = [
140+
fc.Feature1,
141+
fc.Feature2,
142+
fc.Feature3,
143+
...,
144+
fc.Feature101,
145+
];
146+
147+
for (const featureClass of FEATURE_CLASSES) {
148+
new featureClass();
149+
}
150+
```
151+
152+
Importatly, once we have a barrel file, we do not have to artificially split up the number of classes. This is because TSTL does not transpile exports with any local variables at all. Thus, we can have an unlimited number of exports inside of the barrel file without ever hitting the Lua local variable limit.

0 commit comments

Comments
 (0)