     return @tab + code if @ctor
     if @front or (o.level >= LEVEL_ACCESS) then "(#{code})" else code
 
-  # A list of parameter names, excluding those generated by the compiler.
-  paramNames: ->
-    names = []
-    names.push param.names()... for param in @params
-    names
+  eachParamName: (iterator) ->
+    param.eachName iterator for param in @params
 
   # Short-circuit `traverseChildren` method to prevent it from crossing scope boundaries
   # unless `crossScope` is `true`.

    @body.expressions.unshift exprs... if exprs.length
    o.scope.parameter params[i] = p.compile o for p, i in params
    uniqs = []
    for name in @paramNames()
      # TODO Neither @paramNames nor `name` are proper AST nodes from which to
      # throw the error. Using `@` as the context for this error is too broad.
      # We should use the Param corresponding to `name` instead.
      @error "multiple parameters named '#{name}'" if name in uniqs
      uniqs.push name
    @body.makeReturn() unless wasEmpty or @noReturn
    if @bound

  isComplex: ->
    @name.isComplex()

  # Iterates the name or names of a `Param`.
  # In a sense, a destructured parameter represents multiple JS parameters. This
  # method allows to iterate them all.
  # The `iterator` function will be called as `iterator(name, node)` where
  # `name` is the name of the parameter and `node` is the AST node corresponding
  # to that name.
  eachName: (iterator, name = @name)->
    atParam = (obj) ->
      node = obj.properties[0].name
      iterator node.value, node unless node.value.reserved
    # * simple literals `foo`
    return iterator name.value, name if name instanceof Literal
    # * at-params `@foo`
    return atParam name if name instanceof Value
    for obj in name.objects
      # * assignments within destructured parameters `{foo:bar}`
      if obj instanceof Assign
        @eachName iterator, obj.value.unwrap()
      # * splats within destructured parameters `[xs...]`
      else if obj instanceof Splat
        node = obj.name.unwrap()
        iterator node.value, node
      else if obj instanceof Value
        # * destructured parameters within destructured parameters `[{a}]`
        if obj.isArray() or obj.isObject()
          @eachName iterator, obj.base
        # * at-params within destructured parameters `{@foo}`
        else if obj.this
          atParam obj
        # * simple destructured parameters {foo}
        else iterator obj.base.value, obj.base
      else
        obj.error "illegal parameter #{obj.compile()}"
    return

#### Splat

