<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.26">
<title>PropertyList</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<link rel="stylesheet" href="./asciidoctor.css">
<link rel="stylesheet" href="./mlton.css">

</head>
<body class="article">
<div id="mlton-header">
<div id="mlton-header-text">
<h2>
<a href="./Home">
MLton
20241230+git20251029+dfsg-5
</a>
</h2>
</div>
</div>
<div id="header">
<h1>PropertyList</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>A property list is a dictionary-like data structure into which
properties (name-value pairs) can be inserted and from which
properties can be looked up by name.  The term comes from the Lisp
language, where every symbol has a property list for storing
information, and where the names are typically symbols and keys can be
any type of value.</p>
</div>
<div class="paragraph">
<p>Here is an SML signature for property lists such that for any type of
value a new property can be dynamically created to manipulate that
type of value in a property list.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml">signature PROPERTY_LIST =
   sig
      type t

      val new: unit -&gt; t
      val newProperty: unit -&gt; {add: t * 'a -&gt; unit,
                                peek: t -&gt; 'a option}
   end</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is a functor demonstrating the use of property lists.  It first
creates a property list, then two new properties (of different types),
and adds a value to the list for each property.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml">functor Test (P: PROPERTY_LIST) =
   struct
      val pl = P.new ()

      val {add = addInt: P.t * int -&gt; unit, peek = peekInt} = P.newProperty ()
      val {add = addReal: P.t * real -&gt; unit, peek = peekReal} = P.newProperty ()

      val () = addInt (pl, 13)
      val () = addReal (pl, 17.0)
      val s1 = Int.toString (valOf (peekInt pl))
      val s2 = Real.toString (valOf (peekReal pl))
      val () = print (concat [s1, " ", s2, "\n"])
   end</code></pre>
</div>
</div>
<div class="paragraph">
<p>Applied to an appropriate implementation <code>PROPERTY_LIST</code>, the <code>Test</code>
functor will produce the following output.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>13 17.0</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementation">Implementation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Because property lists can hold values of any type, their
implementation requires a <a href="UniversalType">UniversalType</a>.  Given that, a property
list is simply a list of elements of the universal type.  Adding a
property adds to the front of the list, and looking up a property
scans the list.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml">functor PropertyList (U: UNIVERSAL_TYPE): PROPERTY_LIST =
   struct
      datatype t = T of U.t list ref

      fun new () = T (ref [])

      fun 'a newProperty () =
         let
            val (inject, out) = U.embed ()
            fun add (T r, a: 'a): unit = r := inject a :: (!r)
            fun peek (T r) =
               Option.map (valOf o out) (List.find (isSome o out) (!r))
         in
            {add = add, peek = peek}
         end
   end</code></pre>
</div>
</div>
<div class="paragraph">
<p>If <code>U: UNIVERSAL_TYPE</code>, then we can test our code as follows.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml">structure Z = Test (PropertyList (U))</code></pre>
</div>
</div>
<div class="paragraph">
<p>Of course, a serious implementation of property lists would have to
handle duplicate insertions of the same property, as well as the
removal of elements in order to avoid space leaks.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_also_see">Also see</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>MLton relies heavily on property lists for attaching information to
syntax tree nodes in its intermediate languages.  See
<a href="https://github.com/MLton/mlton/blob/master/lib/mlton/basic/property-list.sig"><code>property-list.sig</code></a> and
<a href="https://github.com/MLton/mlton/blob/master/lib/mlton/basic/property-list.fun"><code>property-list.fun</code></a>.</p>
</li>
<li>
<p>The <a href="MLRISCLibrary">MLRISCLibrary</a> <a href="References#LeungGeorge99">uses property lists
extensively</a>.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>