def flatten
      raise Erlang::ImproperListError if improper?
      return self if empty?
      out = tail = Erlang::Cons.allocate
      list = self
      until list.empty?
        if list.head.is_a?(Erlang::Cons)
          list = list.head.append(list.tail)
        elsif Erlang::Nil.equal?(list.head)
          list = list.tail
        else
          new_node = Erlang::Cons.allocate
          new_node.instance_variable_set(:@head, list.head)
          new_node.instance_variable_set(:@improper, false)
          tail.instance_variable_set(:@tail, new_node)
          tail.immutable!
          list = list.tail
          tail = new_node
        end
      end
      if not tail.immutable?
        tail.instance_variable_set(:@tail, Erlang::Nil)
        tail.immutable!
      end
      return out.tail
    end
def flatten
      raise Erlang::ImproperListError if improper?
      return self if empty?
      out = tail = Erlang::Cons.allocate
      list = self
      until list.empty?
        if list.head.is_a?(Erlang::Cons)
          list = list.head.append(list.tail)
        elsif Erlang::Nil.equal?(list.head)
          list = list.tail
        else
          new_node = Erlang::Cons.allocate
          new_node.instance_variable_set(:@head, list.head)
          new_node.instance_variable_set(:@improper, false)
          tail.instance_variable_set(:@tail, new_node)
          tail.immutable!
          list = list.tail
          tail = new_node
        end
      end
      if not tail.immutable?
        tail.instance_variable_set(:@tail, Erlang::Nil)
        tail.immutable!
      end
      return out.tail
    end
Return a new `List` with all nested lists recursively "flattened out",
 that is, their elements inserted into the new `List` in the place where
 the nested list originally was.

 @example
   Erlang::List[Erlang::List[1, 2], Erlang::List[3, 4]].flatten
   # => Erlang::List[1, 2, 3, 4]

 @return [List]