from functools import reduce


def arr2(value, *forms):
    """
    Clojure's second threading macro implementation.

    The logic is the same as `thread_first`, but puts the value
    at the end of each form.

    See https://clojuredocs.org/clojure.core/->>

    :param value: Initial value to process.
    :type value: any

    :param forms: A tuple of forms.
    :type forms: tuple of func|(func, arg1, arg2, ...)

    :return: A value passed through the all forms.
    :rtype: any

    """

    def reducer(value, form):

        if isinstance(form, (tuple, list)):
            func, args = form[0], form[1:]
        else:
            func, args = form, ()

        all_args = tuple(args) + (value, )
        return func(*all_args)

    return reduce(reducer, forms, value)