ikigai-go / compiler

Ikigai compiler
MIT License
0 stars 0 forks source link

To scope or not to scope #4

Open alfonsogarciacaro opened 5 years ago

alfonsogarciacaro commented 5 years ago

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:

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 an x 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.

@MangelMaxime You should start watching the repo ;)

MangelMaxime commented 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?

alfonsogarciacaro commented 5 years ago

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.

MangelMaxime commented 5 years ago

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.