This file is indexed.

/usr/share/doc/mlton/guide/OptionalArguments is in mlton-doc 20100608-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="robots" content="index,nofollow">



<title>OptionalArguments - MLton Standard ML Compiler (SML Compiler)</title>
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css">


<link rel="Start" href="Home">


<link rel="Appendix" title="optionalargs.sml" href="http://mlton.org/pages/OptionalArguments/attachments/optionalargs.sml">
</head>

<body lang="en" dir="ltr">

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-833377-1";
urchinTracker();
</script>
<table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%>
  <tr>
    <td style = "
		border: 0px;
		color: darkblue; 
		font-size: 150%;
		text-align: left;">
      <a class = mltona href="Home">MLton MLTONWIKIVERSION</a>
    <td style = "
		border: 0px;
		font-size: 150%;
		text-align: center;
		width: 50%;">
      OptionalArguments
    <td style = "
		border: 0px;
		text-align: right;">
      <table cellspacing = 0 style = "border: 0px">
        <tr style = "vertical-align: middle;">
      </table>
  <tr style = "background-color: white;">
    <td colspan = 3
	style = "
		border: 0px;
		font-size:70%;
		text-align: right;">
      <a href = "Home">Home</a>
      &nbsp;<a href = "TitleIndex">Index</a>
      &nbsp;
</table>
<div id="content" lang="en" dir="ltr">
<a href="StandardML">Standard ML</a> does not have built-in support for optional arguments.  Nevertheless, using <a href="Fold">Fold</a>, it is easy to define functions that take optional arguments. <p>
For example, suppose that we have the following definition of a function <tt>f</tt>. 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">fun</FONT></B> f (i, r, s) =
   concat [Int.toString i, <B><FONT COLOR="#BC8F8F">&quot;, &quot;</FONT></B>, Real.toString r, <B><FONT COLOR="#BC8F8F">&quot;, &quot;</FONT></B>, s]
</PRE>
<p>
 
</p>
<p>
Using the <tt>OptionalArg</tt> structure described below, we can define a function <tt>f'</tt>, an optionalized version of <tt>f</tt>, that takes 0, 1, 2, or 3 arguments.  Embedded within <tt>f'</tt> will be default values for <tt>i</tt>, <tt>r</tt>, and <tt>s</tt>.  If <tt>f'</tt> gets no arguments, then all the defaults are used.  If <tt>f'</tt> gets one argument, then that will be used for <tt>i</tt>.  Two arguments will be used for <tt>i</tt> and <tt>r</tt> respectively.  Three arguments will override all default values.  Calls to <tt>f'</tt> will look like the following. 
</p>

<pre class=code>
f' $
f' `<B><FONT COLOR="#5F9EA0">2</FONT></B> $
f' `<B><FONT COLOR="#5F9EA0">2</FONT></B> `<B><FONT COLOR="#5F9EA0">3.0</FONT></B> $
f' `<B><FONT COLOR="#5F9EA0">2</FONT></B> `<B><FONT COLOR="#5F9EA0">3.0</FONT></B> `<B><FONT COLOR="#BC8F8F">&quot;four&quot;</FONT></B> $
</PRE>
<p>
 
</p>
<p>
The optional argument indicator, "`", is not special syntax -- it is a normal SML value, defined in the <tt>OptionalArg</tt> structure below. 
</p>
<p>
Here is the definition of <tt>f'</tt> using the <tt>OptionalArg</tt> structure, in particular, <tt>OptionalArg.make</tt> and <tt>OptionalArg.D</tt>. 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> f' =
   <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
   <B><FONT COLOR="#A020F0">let</FONT></B> <B><FONT COLOR="#0000FF">open</FONT></B> OptionalArg <B><FONT COLOR="#A020F0">in</FONT></B>
      make (D <B><FONT COLOR="#5F9EA0">1</FONT></B>) (D <B><FONT COLOR="#5F9EA0">2.0</FONT></B>) (D <B><FONT COLOR="#BC8F8F">&quot;three&quot;</FONT></B>) $
   <B><FONT COLOR="#A020F0">end</FONT></B> (<B><FONT COLOR="#A020F0">fn</FONT></B> i &amp; r &amp; s =&gt; f (i, r, s))
   z
</PRE>
<p>
 
</p>
<p>
The definition of <tt>f'</tt> is eta expanded as with all uses of fold. A call to <tt>OptionalArg.make</tt> is supplied with a variable number of defaults (in this case, three), the end-of-arguments terminator, <tt>$</tt>, and the function to run, taking its arguments as an n-ary <a href="ProductType">product</a>.  In this case, the function simply converts the product to an ordinary tuple and calls <tt>f</tt>.  Often, the function body will simply be written directly. 
</p>
<p>
In general, the definition of an optional-argument function looks like the following. 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> f =
   <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
   <B><FONT COLOR="#A020F0">let</FONT></B> <B><FONT COLOR="#0000FF">open</FONT></B> OptionalArg <B><FONT COLOR="#A020F0">in</FONT></B>
      make (D &lt;default1&gt;) (D &lt;default2&gt;) ... (D &lt;defaultn&gt;) $
   <B><FONT COLOR="#A020F0">end</FONT></B> (<B><FONT COLOR="#A020F0">fn</FONT></B> x1 &amp; x2 &amp; ... &amp; xn =&gt;
        &lt;function code goes here&gt;)
   z
</PRE>
<p>
 
</p>
<p>
Here is the definition of <tt>OptionalArg</tt>. 
</p>

<pre class=code>
<B><FONT COLOR="#0000FF">structure</FONT></B> OptionalArg =
   <B><FONT COLOR="#0000FF">struct</FONT></B>
      <B><FONT COLOR="#A020F0">val</FONT></B> make =
         <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
         Fold.fold
         ((id, <B><FONT COLOR="#A020F0">fn</FONT></B> (f, x) =&gt; f x),
          <B><FONT COLOR="#A020F0">fn</FONT></B> (d, r) =&gt; <B><FONT COLOR="#A020F0">fn</FONT></B> func =&gt;
          Fold.fold ((id, d ()), <B><FONT COLOR="#A020F0">fn</FONT></B> (f, d) =&gt;
                     <B><FONT COLOR="#A020F0">let</FONT></B>
                        <B><FONT COLOR="#A020F0">val</FONT></B> d &amp; () = r (id, f d)
                     <B><FONT COLOR="#A020F0">in</FONT></B>
                        func d
                     <B><FONT COLOR="#A020F0">end</FONT></B>))
         z
         
      <B><FONT COLOR="#A020F0">fun</FONT></B> D d = Fold.step0 (<B><FONT COLOR="#A020F0">fn</FONT></B> (f, r) =&gt;
                            (<B><FONT COLOR="#A020F0">fn</FONT></B> ds =&gt; f (d &amp; ds),
                             <B><FONT COLOR="#A020F0">fn</FONT></B> (f, a &amp; b) =&gt; r (<B><FONT COLOR="#A020F0">fn</FONT></B> x =&gt; f a &amp; x, b)))

      <B><FONT COLOR="#A020F0">val</FONT></B> ` =
         <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
         Fold.step1 (<B><FONT COLOR="#A020F0">fn</FONT></B> (x, (f, _ &amp; d)) =&gt; (<B><FONT COLOR="#A020F0">fn</FONT></B> d =&gt; f (x &amp; d), d))
         z
   <B><FONT COLOR="#0000FF">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
<tt>OptionalArg.make</tt> uses a nested fold.  The first <tt>fold</tt> accumulates the default values in a product, associated to the right, and a reversal function that converts a product (of the same arity as the number of defaults) from right associativity to left associativity.  The accumulated defaults are used by the second fold, which recurs over the product, replacing the appropriate component as it encounters optional arguments.  The second fold also constructs a "fill" function, <tt>f</tt>, that is used to reconstruct the product once the end-of-arguments is reached.  Finally, the finisher reconstructs the product and uses the reversal function to convert the product from right associative to left associative, at which point it is passed to the user-supplied function. 
</p>
<p>
Much of the complexity comes from the fact that while recurring over a product from left to right, one wants it to be right-associative, e.g. look like  
<pre class=code>
a &amp; (b &amp; (c &amp; d))
</PRE>
 but the user function in the end wants the product to be left associative, so that the product argument pattern can be written without parentheses (since <tt>&amp;</tt> is left associative). 
</p>
<h2 id="head-bdcc5ca8c9a34bead29282d453a2db99bcecf045">Labelled optional arguments</h2>
<p>
In addition to the positional optional arguments described above, it is sometimes useful to have labelled optional arguments.  These allow one to define a function, <tt>f</tt>, with defaults, say <tt>a</tt> and <tt>b</tt>.  Then, a caller of <tt>f</tt> can supply values for <tt>a</tt> and <tt>b</tt> by name.  If no value is supplied then the default is used. 
</p>
<p>
Labelled optional arguments are a simple extension of <a href="FunctionalRecordUpdate">FunctionalRecordUpdate</a> using post composition.  Suppose, for example, that one wants a function <tt>f</tt> with labelled optional arguments <tt>a</tt> and <tt>b</tt> with default values <tt>0</tt> and <tt>0.0</tt> respectively.  If one has a functional-record-update function <tt>updateAB</tt> for records with <tt>a</tt> and <tt>b</tt> fields, then one can define <tt>f</tt> in the following way. 
</p>

<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> f =
   <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
   Fold.post
   (updateAB {a = <B><FONT COLOR="#5F9EA0">0</FONT></B>, b = <B><FONT COLOR="#5F9EA0">0.0</FONT></B>},
    <B><FONT COLOR="#A020F0">fn</FONT></B> {a, b} =&gt; print (concat [Int.toString a, <B><FONT COLOR="#BC8F8F">&quot; &quot;</FONT></B>,
                                Real.toString b, <B><FONT COLOR="#BC8F8F">&quot;\n&quot;</FONT></B>]))
   z
</PRE>
<p>
 
</p>
<p>
The idea is that <tt>f</tt> is the post composition (using <tt>Fold.post</tt>) of the actual code for the function with a functional-record updater that starts with the defaults. 
</p>
<p>
Here are some example calls to <tt>f</tt>. 
<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> () = f $
<B><FONT COLOR="#A020F0">val</FONT></B> () = f (U#a <B><FONT COLOR="#5F9EA0">13</FONT></B>) $
<B><FONT COLOR="#A020F0">val</FONT></B> () = f (U#a <B><FONT COLOR="#5F9EA0">13</FONT></B>) (U#b <B><FONT COLOR="#5F9EA0">17.5</FONT></B>) $
<B><FONT COLOR="#A020F0">val</FONT></B> () = f (U#b <B><FONT COLOR="#5F9EA0">17.5</FONT></B>) (U#a <B><FONT COLOR="#5F9EA0">13</FONT></B>) $
</PRE>
 
</p>
<p>
Notice that a caller can supply neither of the arguments, either of the arguments, or both of the arguments, and in either order.  All that matter is that the arguments be labelled correctly (and of the right type, of course). 
</p>
<p>
Here is another example. 
<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> f =
   <B><FONT COLOR="#A020F0">fn</FONT></B> z =&gt;
   Fold.post
   (updateBCD {b = <B><FONT COLOR="#5F9EA0">0</FONT></B>, c = <B><FONT COLOR="#5F9EA0">0.0</FONT></B>, d = <B><FONT COLOR="#BC8F8F">&quot;&lt;&gt;&quot;</FONT></B>},
    <B><FONT COLOR="#A020F0">fn</FONT></B> {b, c, d} =&gt;
    print (concat [Int.toString b, <B><FONT COLOR="#BC8F8F">&quot; &quot;</FONT></B>,
                   Real.toString c, <B><FONT COLOR="#BC8F8F">&quot; &quot;</FONT></B>,
                   d, <B><FONT COLOR="#BC8F8F">&quot;\n&quot;</FONT></B>]))
   z
</PRE>
 
</p>
<p>
Here are some example calls. 
<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> () = f $
<B><FONT COLOR="#A020F0">val</FONT></B> () = f (U#d <B><FONT COLOR="#BC8F8F">&quot;goodbye&quot;</FONT></B>) $
<B><FONT COLOR="#A020F0">val</FONT></B> () = f (U#d <B><FONT COLOR="#BC8F8F">&quot;hello&quot;</FONT></B>) (U#b <B><FONT COLOR="#5F9EA0">17</FONT></B>) (U#c <B><FONT COLOR="#5F9EA0">19.3</FONT></B>) $
</PRE>
 
</p>
</div>



<p>
<hr>
Last edited on 2007-08-15 22:06:57 by <span title="fenrir.uchicago.edu"><a href="MatthewFluet">MatthewFluet</a></span>.
</body></html>