Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/trunk/src/cm/Doc/manual.tex
ViewVC logotype

Diff of /sml/trunk/src/cm/Doc/manual.tex

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 436, Tue Sep 14 09:05:35 1999 UTC revision 445, Thu Sep 16 07:55:27 1999 UTC
# Line 345  Line 345 
345  \label{sec:api}  \label{sec:api}
346    
347  Functions that control CM's operation are accessible as members of a  Functions that control CM's operation are accessible as members of a
348  structure named {\tt CM}.  Here is a description of the members of  structure named {\tt CM}.  This structure itself is exported from a
349  this structure:  library called {\tt host-cm.cm}.  Other libraries can exploit CM's
350    functionality simply by putting a {\tt host-cm.cm} entry into their
351    own description files.  Section~\ref{sec:dynlink} shows one
352    interesting used of this feature.
353    
354    The library is pre-registered at the interactive prompt which is more
355    than a mere convenience: Structure {\tt CM} must be known a-priori at
356    top level because otherwise there would also be no way to make it known.
357    
358    Here is a description of the structure's members:
359    
360  \subsubsection*{Compiling}  \subsubsection*{Compiling}
361    
# Line 1062  Line 1071 
1071  Less common kinds of rules can also be defined using the generic  Less common kinds of rules can also be defined using the generic
1072  interface {\tt Tools.registerClass}.  interface {\tt Tools.registerClass}.
1073    
1074    \section{Example: Dynamic linking}
1075    \label{sec:dynlink}
1076    
1077    Autoloading is convenient and avoids wasted memory for modules that
1078    have not been mentioned yet.  However, sometimes one wants to be more
1079    aggressive and save the space needed for a function until---at
1080    runtime---that function is actually being dynamically invoked.
1081    
1082    CM does not provide immediate support for this kind of {\em dynamic
1083    linking}, but it is quite simple to achieve the effect by carefully
1084    arranging some helper libraries and associated stub code.
1085    
1086    Consider the following module:
1087    \begin{verbatim}
1088    structure F = struct
1089        fun f (x: int): int =
1090            G.g x + H.h (2 * x + 1)
1091    end
1092    \end{verbatim}
1093    
1094    Let us further assume that the implementations of structures {\tt G}
1095    and {\tt H} are rather large so that it would be worthwhile to avoid
1096    loading the code for {\tt G} and {\tt H} until {\tt F.f} is called
1097    with some actual argument.  Of course, if {\tt F} were bigger, then we
1098    also want to avoid loading {\tt F} itself.
1099    
1100    To achieve this goal, we first define a {\em hook} module which will
1101    be the place where the actual implementation of our function will be
1102    registered once it has been loaded.  This hook module is then wrapped
1103    into a hook library.  Thus, we have {\tt f-hook.cm}:
1104    \begin{verbatim}
1105    Library
1106            structure F_Hook
1107    is
1108            f-hook.sml
1109    \end{verbatim}
1110    
1111    and {\tt f-hook.sml}:
1112    
1113    \begin{verbatim}
1114    structure F_Hook = struct
1115        local
1116            fun placeholder (i: int) : int =
1117                raise Fail "F_Hook.f: unitinialized"
1118            val r = ref placeholder
1119        in
1120            fun init f = r := f
1121            fun f x = !r x
1122        end
1123    end
1124    \end{verbatim}
1125    
1126    The hook module provides a reference cell into which a function of
1127    type equal to {\tt F.f} can be installed.  Here we have chosen to hide
1128    the actual reference cell behind a {\bf local} construct.  Accessor
1129    functions are provided to install something into the hook
1130    ({\tt init}) and to invoke the so-installed value ({\tt f}).
1131    
1132    With this preparation we can write the implementation module {\tt f-impl.sml}
1133    in such a way that not only does it provide the actual
1134    code but also installs itself into the hook:
1135    \begin{verbatim}
1136    structure F_Impl = struct
1137        local
1138            fun f (x: int): int =
1139                G.g x + H.h (2 * x + 1)
1140        in
1141            val _ = F_Hook.init f
1142        end
1143    end
1144    \end{verbatim}
1145    \noindent The implementation module is wrapped into its implementation
1146    library {\tt f-impl.cm}:
1147    \begin{verbatim}
1148    Library
1149            structure F_Impl
1150    is
1151            f-impl.sml
1152            f-hook.cm
1153            g.cm       (* imports G *)
1154            h.cm       (* imports H *)
1155    \end{verbatim}
1156    \noindent Note that {\tt f-impl.cm} must mention {\tt f-hook.cm} for
1157    {\tt f-impl.sml} to be able to access structure {\tt F\_Hook}.
1158    
1159    Finally, we replace the original contents of {\tt f.sml} with a stub
1160    module that defines structure {\tt F}:
1161    \begin{verbatim}
1162    structure F = struct
1163        local
1164            val initialized = ref false
1165        in
1166            fun f x =
1167                (if !initialized then ()
1168                  else if CM.make "f-impl.cm" then initialized := true
1169                  else raise Fail "dynamic linkage for F.f failed";
1170                 F_Hook.f x)
1171        end
1172    end
1173    \end{verbatim}
1174    \noindent The trick here is to explicitly invoke {\tt CM.make} the
1175    first time {\tt F.f} is called.  This will then cause {\tt f-impl.cm}
1176    (and therefore {\tt g.cm} and also {\tt h.cm}) to be loaded and the
1177    ``real'' implementation of {\tt F.f} to be registered with the hook
1178    module from where it will then be available to this and future calls
1179    of {\tt F.f}.
1180    
1181    For the new {\tt f.sml} to be compiled successfully it must be placed
1182    into a library {\tt f.cm} that mentions {\tt f-hook.cm} and {\tt
1183    host-cm.cm}.  As we have seen, {\tt f-hook.cm} exports {\tt F\_Hook.f}
1184    and {\tt host-cm.cm} is needed because it exports {\tt CM.make}:
1185    \begin{verbatim}
1186    Library
1187            structure F
1188    is
1189            f.sml
1190            f-hook.cm
1191            host-cm.cm
1192    \end{verbatim}
1193    
1194    \noindent{\bf Beware!}  This solution makes use of {\tt host-cm.cm}
1195    which in turn requires the SML/NJ compiler to be present.  Therefore,
1196    is worthwhile only for really large program modules where the benefits
1197    of their absence are not outweighed be the need for the compiler.
1198    
1199  \section{Some history}  \section{Some history}
1200    
1201  Although its programming model is more general, CM's implementation is  Although its programming model is more general, CM's implementation is

Legend:
Removed from v.436  
changed lines
  Added in v.445

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0