<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><meta name="description" content='Several ggdist functions support 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:
The point_interval() family, such as median_qi(), mean_qi(),
mode_hdi(), etc.
The smooth_ family, such as smooth_bounded(), smooth_unbounded(),
smooth_discrete(), and smooth_bar().
The density_ family, such as density_bounded(), density_unbounded() and
density_histogram().
The align family.
The breaks family.
The bandwidth family.
The 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 geom_dots() can be supplied in one of three
ways:
as a suffix: geom_dots(smooth = "bounded")
as a function: geom_dots(smooth = smooth_bounded)
as a partially-applied function with options:
geom_dots(smooth = smooth_bounded(kernel = "cosine"))


Many other common arguments for ggdist functions work similarly; e.g.
density, align, breaks, bandwidth, and point_interval arguments.
These function families (except point_interval()) also support passing
waivers to their optional arguments: if waiver() is passed to any
of these arguments, their default value (or the most
recently-partially-applied non-waiver value) is used instead.
Use the auto_partial() function to create new functions that support
automatic partial application.'><title>Automatic partial function application in ggdist — auto_partial • ggdist</title><!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png"><link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png"><link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png"><link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png"><link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png"><script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="../deps/bootstrap-5.3.1/bootstrap.min.css" rel="stylesheet"><script src="../deps/bootstrap-5.3.1/bootstrap.bundle.min.js"></script><link href="../deps/Source_Sans_Pro-0.4.8/font.css" rel="stylesheet"><link href="../deps/Source_Code_Pro-0.4.8/font.css" rel="stylesheet"><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous"><!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><meta property="og:title" content="Automatic partial function application in ggdist — auto_partial"><meta property="og:description" content='Several ggdist functions support 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:
The point_interval() family, such as median_qi(), mean_qi(),
mode_hdi(), etc.
The smooth_ family, such as smooth_bounded(), smooth_unbounded(),
smooth_discrete(), and smooth_bar().
The density_ family, such as density_bounded(), density_unbounded() and
density_histogram().
The align family.
The breaks family.
The bandwidth family.
The 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 geom_dots() can be supplied in one of three
ways:
as a suffix: geom_dots(smooth = "bounded")
as a function: geom_dots(smooth = smooth_bounded)
as a partially-applied function with options:
geom_dots(smooth = smooth_bounded(kernel = "cosine"))


Many other common arguments for ggdist functions work similarly; e.g.
density, align, breaks, bandwidth, and point_interval arguments.
These function families (except point_interval()) also support passing
waivers to their optional arguments: if waiver() is passed to any
of these arguments, their default value (or the most
recently-partially-applied non-waiver value) is used instead.
Use the auto_partial() function to create new functions that support
automatic partial application.'><meta property="og:image" content="http://mjskay.github.io/ggdist/logo.svg"><!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]--><!-- Global site tag (gtag.js) - Google Analytics --><script async src="https://www.googletagmanager.com/gtag/js?id=UA-93322-5"></script><script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-93322-5');
</script></head><body>
    <a href="#main" class="visually-hidden-focusable">Skip to contents</a>
    

    <nav class="navbar fixed-top navbar-light navbar-expand-lg bg-light"><div class="container">
    
    <a class="navbar-brand me-2" href="../index.html">ggdist</a>

    <small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.3.2</small>

    
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div id="navbar" class="collapse navbar-collapse ms-3">
      <ul class="navbar-nav me-auto"><li class="active nav-item">
  <a class="nav-link" href="../reference/index.html">Reference</a>
</li>
<li class="nav-item dropdown">
  <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown-articles">Articles</a>
  <div class="dropdown-menu" aria-labelledby="dropdown-articles">
    <a class="dropdown-item" href="../articles/dotsinterval.html">Dots + interval stats and geoms</a>
    <a class="dropdown-item" href="../articles/freq-uncertainty-vis.html">Frequentist uncertainty visualization</a>
    <a class="dropdown-item" href="../articles/lineribbon.html">Lineribbon stats and geoms</a>
    <a class="dropdown-item" href="../articles/slabinterval.html">Slab + interval stats and geoms</a>
    <a class="dropdown-item" href="../articles/thickness.html">Thickness scale</a>
  </div>
</li>
<li class="nav-item">
  <a class="nav-link" href="../news/index.html">Changelog</a>
</li>
      </ul><form class="form-inline my-2 my-lg-0" role="search">
        <input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off"></form>

      <ul class="navbar-nav"><li class="nav-item">
  <a class="external-link nav-link" href="https://github.com/mjskay/ggdist/" aria-label="github">
    <span class="fab fa fab fa-github fa-lg"></span>
     
  </a>
</li>
      </ul></div>

    
  </div>
</nav><div class="container template-reference-topic">
<div class="row">
  <main id="main" class="col-md-9"><div class="page-header">
      <img src="../logo.svg" class="logo" alt=""><h1>Automatic partial function application in ggdist</h1>
      <small class="dont-index">Source: <a href="https://github.com/mjskay/ggdist/blob/HEAD/R/auto_partial.R" class="external-link"><code>R/auto_partial.R</code></a></small>
      <div class="d-none name"><code>auto_partial.Rd</code></div>
    </div>

    <div class="ref-description section level2">
    <p>Several <span class="pkg">ggdist</span> functions support <em>automatic partial application</em>: 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.</p>
<p>Functions supporting automatic partial application include:</p><ul><li><p>The <code><a href="point_interval.html">point_interval()</a></code> family, such as <code><a href="point_interval.html">median_qi()</a></code>, <code><a href="point_interval.html">mean_qi()</a></code>,
<code><a href="point_interval.html">mode_hdi()</a></code>, etc.</p></li>
<li><p>The <code>smooth_</code> family, such as <code><a href="smooth_density.html">smooth_bounded()</a></code>, <code><a href="smooth_density.html">smooth_unbounded()</a></code>,
<code><a href="smooth_discrete.html">smooth_discrete()</a></code>, and <code><a href="smooth_discrete.html">smooth_bar()</a></code>.</p></li>
<li><p>The <code>density_</code> family, such as <code><a href="density_bounded.html">density_bounded()</a></code>, <code><a href="density_unbounded.html">density_unbounded()</a></code> and
<code><a href="density_histogram.html">density_histogram()</a></code>.</p></li>
<li><p>The <a href="align.html">align</a> family.</p></li>
<li><p>The <a href="breaks.html">breaks</a> family.</p></li>
<li><p>The <a href="bandwidth.html">bandwidth</a> family.</p></li>
<li><p>The <a href="blur.html">blur</a> family.</p></li>
</ul><p>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><a href="geom_dots.html">geom_dots()</a></code> can be supplied in one of three
ways:</p><ul><li><p>as a suffix: <code>geom_dots(smooth = "bounded")</code></p></li>
<li><p>as a function: <code>geom_dots(smooth = smooth_bounded)</code></p></li>
<li><p>as a partially-applied function with options:
<code>geom_dots(smooth = smooth_bounded(kernel = "cosine"))</code></p></li>
</ul><p>Many other common arguments for <span class="pkg">ggdist</span> functions work similarly; e.g.
<code>density</code>, <code>align</code>, <code>breaks</code>, <code>bandwidth</code>, and <code>point_interval</code> arguments.</p>
<p>These function families (except <code><a href="point_interval.html">point_interval()</a></code>) also support passing
<a href="https://ggplot2.tidyverse.org/reference/waiver.html" class="external-link">waiver</a>s to their optional arguments: if <code><a href="https://ggplot2.tidyverse.org/reference/waiver.html" class="external-link">waiver()</a></code> is passed to any
of these arguments, their default value (or the most
recently-partially-applied non-<code>waiver</code> value) is used instead.</p>
<p>Use the <code>auto_partial()</code> function to create new functions that support
automatic partial application.</p>
    </div>

    <div class="section level2">
    <h2 id="ref-usage">Usage<a class="anchor" aria-label="anchor" href="#ref-usage"></a></h2>
    <div class="sourceCode"><pre class="sourceCode r"><code><span><span class="fu">auto_partial</span><span class="op">(</span><span class="va">f</span>, name <span class="op">=</span> <span class="cn">NULL</span>, waivable <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></code></pre></div>
    </div>

    <div class="section level2">
    <h2 id="arguments">Arguments<a class="anchor" aria-label="anchor" href="#arguments"></a></h2>
    <dl><dt>f</dt>
<dd><p>A function</p></dd>


<dt>name</dt>
<dd><p>A character string giving the name of the function, to be used
when printing.</p></dd>


<dt>waivable</dt>
<dd><p>logical: if <code>TRUE</code>, optional arguments that get
passed a <code><a href="https://ggplot2.tidyverse.org/reference/waiver.html" class="external-link">waiver()</a></code> will keep their default value (or whatever
non-<code>waiver</code> value has been most recently partially applied for that
argument).</p></dd>

</dl></div>
    <div class="section level2">
    <h2 id="value">Value<a class="anchor" aria-label="anchor" href="#value"></a></h2>
    

<p>A modified version of <code>f</code> that will automatically be partially
applied if all of its required arguments are not given.</p>
    </div>

    <div class="section level2">
    <h2 id="ref-examples">Examples<a class="anchor" aria-label="anchor" href="#ref-examples"></a></h2>
    <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="fu"><a href="https://rdrr.io/r/base/Random.html" class="external-link">set.seed</a></span><span class="op">(</span><span class="fl">1234</span><span class="op">)</span></span></span>
<span class="r-in"><span><span class="va">x</span> <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/stats/Normal.html" class="external-link">rnorm</a></span><span class="op">(</span><span class="fl">100</span><span class="op">)</span></span></span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># the first required argument, `x`, of the density_ family is the vector</span></span></span>
<span class="r-in"><span><span class="co"># to calculate a kernel density estimate from. If it is not provided, the</span></span></span>
<span class="r-in"><span><span class="co"># function is partially applied and returned as-is</span></span></span>
<span class="r-in"><span><span class="fu"><a href="density_unbounded.html">density_unbounded</a></span><span class="op">(</span><span class="op">)</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   density_unbounded()</span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># we could create a new function that uses half the default bandwidth</span></span></span>
<span class="r-in"><span><span class="va">density_half_bw</span> <span class="op">=</span> <span class="fu"><a href="density_unbounded.html">density_unbounded</a></span><span class="op">(</span>adjust <span class="op">=</span> <span class="fl">0.5</span><span class="op">)</span></span></span>
<span class="r-in"><span><span class="va">density_half_bw</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   density_unbounded(adjust = 0.5)</span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># we can overwrite partially-applied arguments</span></span></span>
<span class="r-in"><span><span class="va">density_quarter_bw_trimmed</span> <span class="op">=</span> <span class="fu">density_half_bw</span><span class="op">(</span>adjust <span class="op">=</span> <span class="fl">0.25</span>, trim <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></span>
<span class="r-in"><span><span class="va">density_quarter_bw_trimmed</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   density_unbounded(adjust = 0.25, trim = TRUE)</span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># when we eventually call the function and provide the required argument</span></span></span>
<span class="r-in"><span><span class="co"># `x`, it is applied using the arguments we have "saved up" so far</span></span></span>
<span class="r-in"><span><span class="fu">density_quarter_bw_trimmed</span><span class="op">(</span><span class="va">x</span><span class="op">)</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> </span>
<span class="r-out co"><span class="r-pr">#&gt;</span> Call:</span>
<span class="r-out co"><span class="r-pr">#&gt;</span> 	density_unbounded(x = x, adjust = 0.25, trim = TRUE)</span>
<span class="r-out co"><span class="r-pr">#&gt;</span> </span>
<span class="r-out co"><span class="r-pr">#&gt;</span> Data: x (100 obs.);	Bandwidth 'bw' = 0.08864</span>
<span class="r-out co"><span class="r-pr">#&gt;</span> </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>        x                 y           </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  Min.   :-2.3457   Min.   :0.009921  </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  1st Qu.:-1.1220   1st Qu.:0.062906  </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  Median : 0.1016   Median :0.149478  </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  Mean   : 0.1016   Mean   :0.201970  </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  3rd Qu.: 1.3253   3rd Qu.:0.337508  </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>  Max.   : 2.5490   Max.   :0.673160  </span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># create a custom automatically partially applied function</span></span></span>
<span class="r-in"><span><span class="va">f</span> <span class="op">=</span> <span class="fu">auto_partial</span><span class="op">(</span><span class="kw">function</span><span class="op">(</span><span class="va">x</span>, <span class="va">y</span>, <span class="va">z</span> <span class="op">=</span> <span class="fl">3</span><span class="op">)</span> <span class="op">(</span><span class="va">x</span> <span class="op">+</span> <span class="va">y</span><span class="op">)</span> <span class="op">*</span> <span class="va">z</span><span class="op">)</span></span></span>
<span class="r-in"><span><span class="fu">f</span><span class="op">(</span><span class="op">)</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   f()</span>
<span class="r-in"><span><span class="fu">f</span><span class="op">(</span><span class="fl">1</span><span class="op">)</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   f(x = 1)</span>
<span class="r-in"><span><span class="va">g</span> <span class="op">=</span> <span class="fu">f</span><span class="op">(</span>y <span class="op">=</span> <span class="fl">2</span><span class="op">)</span><span class="op">(</span>z <span class="op">=</span> <span class="fl">4</span><span class="op">)</span></span></span>
<span class="r-in"><span><span class="va">g</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> &lt;partial_function&gt;: </span>
<span class="r-out co"><span class="r-pr">#&gt;</span>   f(y = 2, z = 4)</span>
<span class="r-in"><span><span class="fu">g</span><span class="op">(</span><span class="fl">1</span><span class="op">)</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> [1] 12</span>
<span class="r-in"><span></span></span>
<span class="r-in"><span><span class="co"># pass waiver() to optional arguments to use existing values</span></span></span>
<span class="r-in"><span><span class="fu">f</span><span class="op">(</span>z <span class="op">=</span> <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/waiver.html" class="external-link">waiver</a></span><span class="op">(</span><span class="op">)</span><span class="op">)</span><span class="op">(</span><span class="fl">1</span>, <span class="fl">2</span><span class="op">)</span>  <span class="co"># uses default z = 3</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> [1] 9</span>
<span class="r-in"><span><span class="fu">f</span><span class="op">(</span>z <span class="op">=</span> <span class="fl">4</span><span class="op">)</span><span class="op">(</span>z <span class="op">=</span> <span class="fu"><a href="https://ggplot2.tidyverse.org/reference/waiver.html" class="external-link">waiver</a></span><span class="op">(</span><span class="op">)</span><span class="op">)</span><span class="op">(</span><span class="fl">1</span>, <span class="fl">2</span><span class="op">)</span>  <span class="co"># uses z = 4</span></span></span>
<span class="r-out co"><span class="r-pr">#&gt;</span> [1] 12</span>
</code></pre></div>
    </div>
  </main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
    </nav></aside></div>


    <footer><div class="pkgdown-footer-left">
  <p></p><p>Developed by <a href="https://www.mjskay.com" class="external-link">Matthew Kay</a>.</p>
</div>

<div class="pkgdown-footer-right">
  <p></p><p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.0.7.</p>
</div>

    </footer></div>

  

  

  </body></html>

