def slice(
    arr: Union[str, Column, Func, Sequence],
    offset: int,
    length: Optional[int] = None,
) -> Func:
    """
    Returns a slice of the array starting from the specified offset.

    Args:
        arr (str | Column | Func | Sequence): Array to slice.
            If a string is provided, it is assumed to be the name of the array column.
            If a Column is provided, it is assumed to be an array column.
            If a Func is provided, it is assumed to be a function returning an array.
            If a sequence is provided, it is assumed to be an array of values.
        offset (int): Starting position of the slice (0-based).
        length (int, optional): Number of elements to include in the slice.
            If not provided, returns all elements from offset to the end.

    Returns:
        Func: A `Func` object that represents the slice function.

    Example:
        ```py
        dc.mutate(
            slice1=func.array.slice("signal.values", 1, 3),
            slice2=func.array.slice(dc.C("signal.values"), 2),
            slice3=func.array.slice([1, 2, 3, 4, 5], 1, 2),
        )
        ```

    Notes:
        - The result column will be of type array with the same element type
            as the input.
    """

    def inner(arg):
        if length is not None:
            return array.slice(arg, offset, length)
        return array.slice(arg, offset)

    def element_type(el):
        if isinstance(el, list):
            try:
                return list[element_type(el[0])]
            except IndexError:
                # if the array is empty, return list[str] as default type
                return list[str]
        return type(el)

    def type_from_args(arr, *_):
        if isinstance(arr, list):
            try:
                return list[element_type(arr[0])]
            except IndexError:
                pass
        # if not an array or array is empty, return list[str] as default type
        return list[str]

    if isinstance(arr, (str, Column, Func)):
        cols = [arr]
        args = None
    else:
        cols = None
        args = [arr]

    return Func(
        "slice",
        inner=inner,
        cols=cols,
        args=args,
        from_array=True,
        is_array=True,
        type_from_args=type_from_args,
    )

    Returns a slice of the array starting from the specified offset.

    Args:
        arr (str | Column | Func | Sequence): Array to slice.
            If a string is provided, it is assumed to be the name of the array column.
            If a Column is provided, it is assumed to be an array column.
            If a Func is provided, it is assumed to be a function returning an array.
            If a sequence is provided, it is assumed to be an array of values.
        offset (int): Starting position of the slice (0-based).
        length (int, optional): Number of elements to include in the slice.
            If not provided, returns all elements from offset to the end.

    Returns:
        Func: A `Func` object that represents the slice function.

    Example:
        ```py
        dc.mutate(
            slice1=func.array.slice("signal.values", 1, 3),
            slice2=func.array.slice(dc.C("signal.values"), 2),
            slice3=func.array.slice([1, 2, 3, 4, 5], 1, 2),
        )
        ```

    Notes:
        - The result column will be of type array with the same element type
            as the input.
    
src/datachain/func/array.py