@function __partial-wrapper($arguments...) {
    $partials: __this('partials');
    $func: __this('func');
    $arguments: join($partials, $arguments);

    @return __exec($func, $arguments...);
}


@function __partial($func, $arguments...) {
    $partials: $arguments;
    $_: __scope((
        'partials': $partials,
        'func': $func
    ));
    $partial-wrapper: __bind('__partial-wrapper');
    $_: __scope(false);

    @return $partial-wrapper;
}


@function __partial-right-wrapper($arguments...) {
    $partials: __this('partials');
    $func: __this('func');
    $arguments: join($arguments, $partials);

    @return __exec($func, $arguments...);
}


@function __partial-right($func, $arguments...) {
    $partials: $arguments;
    $_: __scope((
        'partials': $partials,
        'func': $func
    ));
    $partial-wrapper: __bind('__partial-right-wrapper');
    $_: __scope(false);

    @return $partial-wrapper;
}


/// Creates a function that invokes `$function` with `partial` arguments prepended
/// to those provided to the new function. This method is like `_bind` except
/// it does **not** alter the `_this` binding.
///
///
/// @access public
/// @group Function
/// @param {Function} $func The function to partially apply arguments to.
/// @param {Any...} $args... The arguments to be partially applied.
/// @returns {Function} Returns the new partially applied function.
/// @example scss
///     @function greet($greeting, $name) {
///         @return $greeting + ' ' + $name;
///     }
///     
///     $say-hello-to: _partial(greet, 'hello');
///     
///     $foo: _exec($say-hello-to, 'fred');
///     // => 'hello fred'

@function _partial($args...) {
    @return call(get-function('__partial'), $args...);
}


/// This method is like `_partial` except that partially applied arguments
/// are appended to those provided to the new function.
///
///
/// @access public
/// @group Function
/// @param {Function} $func The function to partially apply arguments to.
/// @param {Any...} $args... The arguments to be partially applied.
/// @returns {Function} Returns the new partially applied function.
/// @example scss
///     @function greet($greeting, $name) {
///         @return $greeting + ' ' + $name;
///     }
///     
///     $greet-with: _partial-right(greet, 'fred');
///     
///     $foo: _exec($greet-with, 'hi');
///     // => 'hi fred'

@function _partial-right($args...) {
    @return call(get-function('__partial-right'), $args...);
}
