       iex> Enum.slice(1..10, 5..20)
       [6, 7, 8, 9, 10]
 
+      # last five elements (negative positions)
+      iex> Enum.slice(1..30, -5..-1)
+      [26, 27, 28, 29, 30]
+
+      # last five elements (mixed positive and negative positions)
+      iex> Enum.slice(1..30, 25..-1)
+      [26, 27, 28, 29, 30]
+
+      # out of bounds
       iex> Enum.slice(1..10, 11..20)
       []
 
+      # range.first is greater than range.last
       iex> Enum.slice(1..10, 6..5)
       []
 

  end

  @doc """
  Returns a subset list of the given enumerable. Drops elements
  until element position `start`, then takes `n` elements.

  If `n` is greater than `enumerable` length, it returns as
  many as possible. If zero, then it returns `[]`.

  ## Examples

      iex> Enum.slice(1..100, 5, 10)
      [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

      iex> Enum.slice(1..10, 5, 100)
      [6, 7, 8, 9, 10]

      iex> Enum.slice(1..10, 5, 0)
      []

  """
  @spec slice(t, integer, non_neg_integer) :: list
  def slice(enumerable, start, n)

  def slice(enumerable, start, n) when is_integer(start) and is_integer(n) and n >= 0,

  end

  @doc """
  Returns a subset list of the given enumerable, from `range.first` to `range.last` positions.

  Given `enumerable`, it drops elements until element position `range.first`,
  then takes elements until element position `range.last` (inclusive).

  Positions are normalized, meaning that negative positions will be counted from the end
  (e.g. `-1` means the last element of the enumerable).
  If `range.last` is out of bounds, then it is assigned as the position of the last element.

  If the normalized `range.first` position is out of bounds of the given enumerable,
  or this one is greater than the normalized `range.last` position, then `[]` is returned.

  ## Examples

