diff --git a/code_obj.lua b/code_obj.lua
index dbc1d65..7b730de 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -201,7 +201,7 @@ do
   local _class_0
   local _parent_0 = Code
   local _base_0 = {
-    add_free_vars = function(self, ...)
+    add_free_vars = function(self, vars)
       local seen
       do
         local _tbl_0 = { }
@@ -215,13 +215,14 @@ do
         end
         seen = _tbl_0
       end
-      for i = 1, select("#", ...) do
-        local var = select(i, ...)
+      for _index_0 = 1, #vars do
+        local var = vars[_index_0]
         if type(var) == 'userdata' and var.type == "Var" then
           var = tostring(var:as_lua())
         elseif type(var) ~= 'string' then
           var = tostring(var)
         end
+        assert(var:match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
         if not (seen[var]) then
           self.free_vars[#self.free_vars + 1] = var
           seen[var] = true
@@ -229,15 +230,16 @@ do
       end
       self.__str = nil
     end,
-    remove_free_vars = function(self, ...)
+    remove_free_vars = function(self, vars)
       local removals = { }
-      for i = 1, select("#", ...) do
-        local var = select(i, ...)
+      for _index_0 = 1, #vars do
+        local var = vars[_index_0]
         if type(var) == 'userdata' and var.type == "Var" then
           var = tostring(var:as_lua())
         elseif type(var) ~= 'string' then
           var = tostring(var)
         end
+        assert(var:match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
         removals[var] = true
       end
       local stack = {
@@ -292,6 +294,7 @@ do
             local var = _list_0[_index_0]
             if not (seen[var]) then
               seen[var] = true
+              assert(var:match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
               to_declare[#to_declare + 1] = var
             end
           end
@@ -306,9 +309,10 @@ do
         gather_from(self)
       end
       if #to_declare > 0 then
-        self:remove_free_vars(unpack(to_declare))
-        return self:prepend("local " .. tostring(concat(to_declare, ", ")) .. ";\n")
+        self:remove_free_vars(to_declare)
+        self:prepend("local " .. tostring(concat(to_declare, ", ")) .. ";\n")
       end
+      return to_declare
     end,
     __tostring = function(self)
       if self.__str == nil then
diff --git a/code_obj.moon b/code_obj.moon
index dbb0211..d038cc8 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -134,27 +134,27 @@ class Lua extends Code
         lua.is_value = true
         return lua
 
-    add_free_vars: (...)=>
+    add_free_vars: (vars)=>
         seen = {[v]:true for v in *@free_vars}
-        for i=1,select("#",...)
-            var = select(i, ...)
+        for var in *vars
             if type(var) == 'userdata' and var.type == "Var"
                 var = tostring(var\as_lua!)
             elseif type(var) != 'string'
                 var = tostring(var)
+            assert(var\match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
             unless seen[var]
                 @free_vars[#@free_vars+1] = var
                 seen[var] = true
         @__str = nil
     
-    remove_free_vars: (...)=>
+    remove_free_vars: (vars)=>
         removals = {}
-        for i=1,select("#",...)
-            var = select(i, ...)
+        for var in *vars
             if type(var) == 'userdata' and var.type == "Var"
                 var = tostring(var\as_lua!)
             elseif type(var) != 'string'
                 var = tostring(var)
+            assert(var\match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
             removals[var] = true
         
         stack = {self}
@@ -183,14 +183,16 @@ class Lua extends Code
                 for var in *@free_vars
                     unless seen[var]
                         seen[var] = true
+                        assert(var\match("^[_a-zA-Z][_a-zA-Z0-9]*$"))
                         to_declare[#to_declare+1] = var
                 for bit in *@bits
                     if bit.__class == Lua
                         gather_from bit
             gather_from self
         if #to_declare > 0
-            @remove_free_vars unpack(to_declare)
+            @remove_free_vars to_declare
             @prepend "local #{concat to_declare, ", "};\n"
+        return to_declare
 
     __tostring: =>
         if @__str == nil
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index d4ae624..6d2f764 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -28,7 +28,7 @@ immediately
             end
             local body_lua = \%lua:as_lua(nomsu);
             body_lua:convert_to_statements("return ");
-            body_lua:remove_free_vars(unpack(args));
+            body_lua:remove_free_vars(args);
             body_lua:declare_locals();
             lua:append(")\n    ", body_lua, "\nend);");
             return lua;
@@ -60,7 +60,7 @@ immediately
             end
             local body_lua = \%body:as_lua(nomsu);
             body_lua:convert_to_statements("return ");
-            body_lua:remove_free_vars(unpack(args));
+            body_lua:remove_free_vars(args);
             body_lua:declare_locals();
             lua:append(")\n    ", body_lua, "\nend);")
             return lua;
@@ -127,14 +127,14 @@ immediately
             lua:convert_to_statements();
             return lua;
     
-    compile [declare locals in %tree] to
-        Lua "\(%tree as lua expr):declare_locals();"
+    compile [declare locals in %code] to
+        Lua value "\(%code as lua expr):declare_locals()"
     
-    compile [declare locals %locals in %tree] to
-        Lua "\(%tree as lua expr):declare_locals(\(%locals as lua expr));"
+    compile [declare locals %locals in %code] to
+        Lua value "\(%code as lua expr):declare_locals(\(%locals as lua expr))"
     
-    compile [remove free vars %vars from %tree] to
-        Lua "\(%tree as lua expr):remove_free_vars(unpack(\(%vars as lua expr)));"
+    compile [remove free vars %vars from %code] to
+        Lua "\(%code as lua expr):remove_free_vars(\(%vars as lua expr));"
 
     action [%tree as value]
         =lua "nomsu:tree_to_value(\%tree)"
diff --git a/core/operators.nom b/core/operators.nom
index 6ec6909..88b0374 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -54,7 +54,7 @@ immediately
         lua> ".."
             local lua = Lua(tree.source, \%var_lua, ' = ', \%value_lua, ';');
             if \%var.type == 'Var' then
-                lua:add_free_vars(\%var);
+                lua:add_free_vars({\%var});
             end
             return lua;
 
@@ -72,7 +72,7 @@ immediately
                 local value_lua = value:as_lua(nomsu);
                 if not value_lua.is_value then error("Invalid value for assignment: "..value:get_src()); end
                 if target.type == "Var" then
-                    lhs:add_free_vars(target);
+                    lhs:add_free_vars({target});
                 end
                 if i > 1 then
                     lhs:append(", ");
@@ -93,7 +93,7 @@ immediately
 
     compile [exporting %exported %body] to
         %body_lua <- (%body as lua statements)
-        lua> "\%body_lua:remove_free_vars(unpack(\(%exported.value)));"
+        lua> "\%body_lua:remove_free_vars(\(%exported.value));"
         return %body_lua
 
     compile [with %assignments %body] to
@@ -112,7 +112,7 @@ immediately
                     error("Invalid value for assignment: "..tostring(value.source:get_text()));
                 end
                 if target.type == "Var" then
-                    lhs:add_free_vars(target);
+                    lhs:add_free_vars({target});
                 end
                 if i > 1 then
                     lhs:append(", ");