 hoistWheres = (possible, assigns) ->
   defined = (n for [n, _] in assigns)
   hoisted = []
-  for [pattern, def, names] in possible
-    canHoist = yes
-    for name in names when name not in defined
-      canHoist = no
-    if canHoist
+  notHoisted = []
+  for [pattern, def, missingNames] in possible
+    stillMissingNames = (name for name in missingNames when name not in defined)
+    if stillMissingNames.length == 0
       hoisted.push [pattern, def]
-  if hoisted.length > 0
-    compileWhereImpl hoisted
-  else
-    ''
+    else
+      notHoisted.push [pattern, def, stillMissingNames]
+  [hoisted, notHoisted]
 
 toJsString = (token) ->
   "'#{token}'"

    throw new Error "Missing definition of a function"
  # Find invalid (hoistable) wheres and let the function body
  # define them
  [readyWheres, hoistableWheres] = wheresWithHoisting wheres
  addToScopeAllNames readyWheres
  wheresDef = (graphToWheres readyWheres).map(compileDef).join '\n'
  bodyDef = compileImpl body, graphToWheres hoistableWheres
  [wheresDef, bodyDef]

addToScopeAllNames = (graph) ->
  for {names, def: [pattern, def]} in graph

  'match': (hoistableWheres, onwhat, cases...) ->
    varNames = []
    if not onwhat
      throw new Error 'match `onwhat:` missing'
    exp = compileImpl onwhat
    if cases.length % 2 != 0
      throw new Error 'match missing result for last pattern'
    compiledCases = (for [pattern, result], i in pairs cases
      control = if i is 0 then 'if' else ' else if'
      {precs, assigns} = patternMatch pattern, exp, mainCache
