% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/auto_partial.R
\name{auto_partial}
\alias{auto_partial}
\alias{automatic-partial-functions}
\title{Automatic partial function application in ggdist}
\usage{
auto_partial(f, name = NULL, waivable = TRUE)
}
\arguments{
\item{f}{<\link{function}> Function to automatically partially-apply.}

\item{name}{<\link[=character]{string}> Name of the function, to be used
when printing.}

\item{waivable}{<scalar \link{logical}> If \code{TRUE}, optional arguments that get
passed a \code{\link[=waiver]{waiver()}} will keep their default value (or whatever
non-\code{waiver} value has been most recently partially applied for that
argument).}
}
\value{
A modified version of \code{f} that will automatically be partially
applied if all of its required arguments are not given.
}
\description{
Several \pkg{ggdist} functions support \emph{automatic partial application}: when called,
if all of their required arguments have not been provided, the function returns a
modified version of itself that uses the arguments passed to it so far as defaults.
Technically speaking, these functions are essentially "Curried" with respect to
their required arguments, but I think "automatic partial application" gets
the idea across more clearly.

Functions supporting automatic partial application include:
\itemize{
\item The \code{\link[=point_interval]{point_interval()}} family, such as \code{\link[=median_qi]{median_qi()}}, \code{\link[=mean_qi]{mean_qi()}},
\code{\link[=mode_hdi]{mode_hdi()}}, etc.
\item The \code{smooth_} family, such as \code{\link[=smooth_bounded]{smooth_bounded()}}, \code{\link[=smooth_unbounded]{smooth_unbounded()}},
\code{\link[=smooth_discrete]{smooth_discrete()}}, and \code{\link[=smooth_bar]{smooth_bar()}}.
\item The \code{density_} family, such as \code{\link[=density_bounded]{density_bounded()}}, \code{\link[=density_unbounded]{density_unbounded()}} and
\code{\link[=density_histogram]{density_histogram()}}.
\item The \link{align} family.
\item The \link{breaks} family.
\item The \link{bandwidth} family.
\item The \link{blur} family.
}

Partial application makes it easier to supply custom parameters to these
functions when using them inside other functions, such as geoms and stats.
For example, smoothers for \code{\link[=geom_dots]{geom_dots()}} can be supplied in one of three
ways:
\itemize{
\item as a suffix: \code{geom_dots(smooth = "bounded")}
\item as a function: \code{geom_dots(smooth = smooth_bounded)}
\item as a partially-applied function with options:
\code{geom_dots(smooth = smooth_bounded(kernel = "cosine"))}
}

Many other common arguments for \pkg{ggdist} functions work similarly; e.g.
\code{density}, \code{align}, \code{breaks}, \code{bandwidth}, and \code{point_interval} arguments.

These function families (except \code{\link[=point_interval]{point_interval()}}) also support passing
\link{waiver}s to their optional arguments: if \code{\link[=waiver]{waiver()}} is passed to any
of these arguments, their default value (or the most
recently-partially-applied non-\link{waiver} value) is used instead.

Use the \code{\link[=auto_partial]{auto_partial()}} function to create new functions that support
automatic partial application.
}
\examples{
set.seed(1234)
x = rnorm(100)

# the first required argument, `x`, of the density_ family is the vector
# to calculate a kernel density estimate from. If it is not provided, the
# function is partially applied and returned as-is
density_unbounded()

# we could create a new function that uses half the default bandwidth
density_half_bw = density_unbounded(adjust = 0.5)
density_half_bw

# we can overwrite partially-applied arguments
density_quarter_bw_trimmed = density_half_bw(adjust = 0.25, trim = TRUE)
density_quarter_bw_trimmed

# when we eventually call the function and provide the required argument
# `x`, it is applied using the arguments we have "saved up" so far
density_quarter_bw_trimmed(x)

# create a custom automatically partially applied function
f = auto_partial(function(x, y, z = 3) (x + y) * z)
f()
f(1)
g = f(y = 2)(z = 4)
g
g(1)

# pass waiver() to optional arguments to use existing values
f(z = waiver())(1, 2)  # uses default z = 3
f(z = 4)(z = waiver())(1, 2)  # uses z = 4
}
