Open alfonsogarciacaro opened 5 years ago
@MangelMaxime You should start watching the repo ;)
Done ;)
I think we could mangle name at scope level. Because I don't think we will include inlining
feature for now or even later. Not all language have it and they are fine without it.
What is the problem with creating a scope at the binding level?
Look at this sample:
type Foo =
| Foo of int
| Bar of int
let square i = i * 2
let test x =
let x =
try
match x with
| Foo x -> x + 5
| Bar x -> x * 2
|> square
with _ -> 5
x + 3
The last function is translated by Fable as:
export function test(x) {
var x$$2, x$$1;
let x$$3;
try {
x$$3 = square(x.tag === 1 ? (x$$2 = x.fields[0] | 0, x$$2 * 2) : (x$$1 = x.fields[0] | 0, x$$1 + 5));
} catch (matchValue) {
x$$3 = 5;
}
return x$$3 + 3 | 0;
}
Note that, to avoid having to wrap the pattern matching in an iife to pass it as argument to square
, Fable is hoisting the x
variables of each branch. Because of this the variables end up in the top scope of the function, so we need to mangle the names to avoid conflicts with other values.
maybe we can keep variable shadowing and only do mangling in the function scope.
Let's try this as this is the simpler solution if I understood correctly.
In #2 I wrote that bindings shouldn't create scopes and shadowing shouldn't be allowed in the same scope. I thought that to avoid name mangling. However, after having a look this is not going to be so easy:
If some constructs can create scope (like
if .. else
,try .. catch
) we need to have a way to distinguish them for other cases where we can have multiple lines (e.g. collection items, tuple/call arguments, operators) but we don't define a new scope. Maybe we could follow Python rules which seems to use:
for that, but it won't be very obvious at first.If the language is primarily expression based, there may be situations where we need to put statements in places where JS only accepts expressions. To avoid too many iifes, Fable usually does variable hoisting in these cases (example). But this may cause conflicts if the variables don't have unique names.
I know that in Fable we've ended up creating unique names for each variable in the whole file. This causes a lot of mangling (e.g.
x
will be mangled if another function contains anx
variable) I don't remember exactly the reason, but I think it was due to inlining and/or the fact that you can import values from other files in the local scope too. If we don't do inlining (for now) and keep JS import rules, maybe we can keep variable shadowing and only do mangling in the function scope.