comparison doc/manual.tex @ 1797:bb942416bf1c

Remove 'class' declaration; now use 'con' instead
author Adam Chlipala <adam@chlipala.net>
date Sun, 29 Jul 2012 12:27:13 -0400
parents 69daa6d70299
children 3d922a28370b
comparison
equal deleted inserted replaced
1796:0de0daab5fbb 1797:bb942416bf1c
19 \tableofcontents 19 \tableofcontents
20 20
21 21
22 \section{Introduction} 22 \section{Introduction}
23 23
24 \emph{Ur} is a programming language designed to introduce richer type system features into functional programming in the tradition of ML and Haskell. Ur is functional, pure, statically-typed, and strict. Ur supports a powerful kind of \emph{metaprogramming} based on \emph{type-level computation with type-level records}. 24 \emph{Ur} is a programming language designed to introduce richer type system features into functional programming in the tradition of ML and Haskell. Ur is functional, pure, statically typed, and strict. Ur supports a powerful kind of \emph{metaprogramming} based on \emph{type-level computation with type-level records}.
25 25
26 \emph{Ur/Web} is Ur plus a special standard library and associated rules for parsing and optimization. Ur/Web supports construction of dynamic web applications backed by SQL databases. The signature of the standard library is such that well-typed Ur/Web programs ``don't go wrong'' in a very broad sense. Not only do they not crash during particular page generations, but they also may not: 26 \emph{Ur/Web} is Ur plus a special standard library and associated rules for parsing and optimization. Ur/Web supports construction of dynamic web applications backed by SQL databases. The signature of the standard library is such that well-typed Ur/Web programs ``don't go wrong'' in a very broad sense. Not only do they not crash during particular page generations, but they also may not:
27 27
28 \begin{itemize} 28 \begin{itemize}
29 \item Suffer from any kinds of code-injection attacks 29 \item Suffer from any kinds of code-injection attacks
153 \item \texttt{cleanup}: maximum number of cleanup operations (e.g., entries recording the need to deallocate certain temporary objects) that may be active at once per request 153 \item \texttt{cleanup}: maximum number of cleanup operations (e.g., entries recording the need to deallocate certain temporary objects) that may be active at once per request
154 \item \texttt{database}: maximum size of database files (currently only used by SQLite) 154 \item \texttt{database}: maximum size of database files (currently only used by SQLite)
155 \item \texttt{deltas}: maximum number of messages sendable in a single request handler with \texttt{Basis.send} 155 \item \texttt{deltas}: maximum number of messages sendable in a single request handler with \texttt{Basis.send}
156 \item \texttt{globals}: maximum number of global variables that FFI libraries may set in a single request context 156 \item \texttt{globals}: maximum number of global variables that FFI libraries may set in a single request context
157 \item \texttt{headers}: maximum size (in bytes) of per-request buffer used to hold HTTP headers for generated pages 157 \item \texttt{headers}: maximum size (in bytes) of per-request buffer used to hold HTTP headers for generated pages
158 \item \texttt{heap}: maximum size (in bytes) of per-request heap for dynamically-allocated data 158 \item \texttt{heap}: maximum size (in bytes) of per-request heap for dynamically allocated data
159 \item \texttt{inputs}: maximum number of top-level form fields per request 159 \item \texttt{inputs}: maximum number of top-level form fields per request
160 \item \texttt{messages}: maximum size (in bytes) of per-request buffer used to hold a single outgoing message sent with \texttt{Basis.send} 160 \item \texttt{messages}: maximum size (in bytes) of per-request buffer used to hold a single outgoing message sent with \texttt{Basis.send}
161 \item \texttt{page}: maximum size (in bytes) of per-request buffer used to hold HTML content of generated pages 161 \item \texttt{page}: maximum size (in bytes) of per-request buffer used to hold HTML content of generated pages
162 \item \texttt{script}: maximum size (in bytes) of per-request buffer used to hold JavaScript content of generated pages 162 \item \texttt{script}: maximum size (in bytes) of per-request buffer used to hold JavaScript content of generated pages
163 \item \texttt{subinputs}: maximum number of form fields per request, excluding top-level fields 163 \item \texttt{subinputs}: maximum number of form fields per request, excluding top-level fields
520 \\ 520 \\
521 &&& \_ & \textrm{wildcard} \\ 521 &&& \_ & \textrm{wildcard} \\
522 &&& (e) & \textrm{explicit precedence} \\ 522 &&& (e) & \textrm{explicit precedence} \\
523 \\ 523 \\
524 \textrm{Local declarations} & ed &::=& \cd{val} \; x : \tau = e & \textrm{non-recursive value} \\ 524 \textrm{Local declarations} & ed &::=& \cd{val} \; x : \tau = e & \textrm{non-recursive value} \\
525 &&& \cd{val} \; \cd{rec} \; (x : \tau = e \; \cd{and})^+ & \textrm{mutually-recursive values} \\ 525 &&& \cd{val} \; \cd{rec} \; (x : \tau = e \; \cd{and})^+ & \textrm{mutually recursive values} \\
526 \end{array}$$ 526 \end{array}$$
527 527
528 As with constructors, we include both abstraction and application for kind polymorphism, but applications are only inferred internally. 528 As with constructors, we include both abstraction and application for kind polymorphism, but applications are only inferred internally.
529 529
530 \emph{Declarations} primarily bring new symbols into context. 530 \emph{Declarations} primarily bring new symbols into context.
531 $$\begin{array}{rrcll} 531 $$\begin{array}{rrcll}
532 \textrm{Declarations} & d &::=& \mt{con} \; x :: \kappa = c & \textrm{constructor synonym} \\ 532 \textrm{Declarations} & d &::=& \mt{con} \; x :: \kappa = c & \textrm{constructor synonym} \\
533 &&& \mt{datatype} \; x \; x^* = dc\mid^+ & \textrm{algebraic datatype definition} \\ 533 &&& \mt{datatype} \; x \; x^* = dc\mid^+ & \textrm{algebraic datatype definition} \\
534 &&& \mt{datatype} \; x = \mt{datatype} \; M.x & \textrm{algebraic datatype import} \\ 534 &&& \mt{datatype} \; x = \mt{datatype} \; M.x & \textrm{algebraic datatype import} \\
535 &&& \mt{val} \; x : \tau = e & \textrm{value} \\ 535 &&& \mt{val} \; x : \tau = e & \textrm{value} \\
536 &&& \mt{val} \; \cd{rec} \; (x : \tau = e \; \mt{and})^+ & \textrm{mutually-recursive values} \\ 536 &&& \mt{val} \; \cd{rec} \; (x : \tau = e \; \mt{and})^+ & \textrm{mutually recursive values} \\
537 &&& \mt{structure} \; X : S = M & \textrm{module definition} \\ 537 &&& \mt{structure} \; X : S = M & \textrm{module definition} \\
538 &&& \mt{signature} \; X = S & \textrm{signature definition} \\ 538 &&& \mt{signature} \; X = S & \textrm{signature definition} \\
539 &&& \mt{open} \; M & \textrm{module inclusion} \\ 539 &&& \mt{open} \; M & \textrm{module inclusion} \\
540 &&& \mt{constraint} \; c \sim c & \textrm{record disjointness constraint} \\ 540 &&& \mt{constraint} \; c \sim c & \textrm{record disjointness constraint} \\
541 &&& \mt{open} \; \mt{constraints} \; M & \textrm{inclusion of just the constraints from a module} \\ 541 &&& \mt{open} \; \mt{constraints} \; M & \textrm{inclusion of just the constraints from a module} \\
542 &&& \mt{table} \; x : c & \textrm{SQL table} \\ 542 &&& \mt{table} \; x : c & \textrm{SQL table} \\
543 &&& \mt{view} \; x = e & \textrm{SQL view} \\ 543 &&& \mt{view} \; x = e & \textrm{SQL view} \\
544 &&& \mt{sequence} \; x & \textrm{SQL sequence} \\ 544 &&& \mt{sequence} \; x & \textrm{SQL sequence} \\
545 &&& \mt{cookie} \; x : \tau & \textrm{HTTP cookie} \\ 545 &&& \mt{cookie} \; x : \tau & \textrm{HTTP cookie} \\
546 &&& \mt{style} \; x : \tau & \textrm{CSS class} \\ 546 &&& \mt{style} \; x : \tau & \textrm{CSS class} \\
547 &&& \mt{class} \; x :: \kappa = c & \textrm{concrete constructor class} \\
548 &&& \mt{task} \; e = e & \textrm{recurring task} \\ 547 &&& \mt{task} \; e = e & \textrm{recurring task} \\
549 \\ 548 \\
550 \textrm{Modules} & M &::=& \mt{struct} \; d^* \; \mt{end} & \textrm{constant} \\ 549 \textrm{Modules} & M &::=& \mt{struct} \; d^* \; \mt{end} & \textrm{constant} \\
551 &&& X & \textrm{variable} \\ 550 &&& X & \textrm{variable} \\
552 &&& M.X & \textrm{projection} \\ 551 &&& M.X & \textrm{projection} \\
588 587
589 At the expression level, an analogue is available of the composite $\lambda$ form for constructors. We define the language of binders as $b ::= p \mid [x] \mid [x \; ? \; \kappa] \mid X \mid [c \sim c]$. A lone variable $[x]$ stands for an implicit constructor variable of unspecified kind. The standard value-level function binder is recovered as the type-annotated pattern form $x : \tau$. It is a compile-time error to include a pattern $p$ that does not match every value of the appropriate type. 588 At the expression level, an analogue is available of the composite $\lambda$ form for constructors. We define the language of binders as $b ::= p \mid [x] \mid [x \; ? \; \kappa] \mid X \mid [c \sim c]$. A lone variable $[x]$ stands for an implicit constructor variable of unspecified kind. The standard value-level function binder is recovered as the type-annotated pattern form $x : \tau$. It is a compile-time error to include a pattern $p$ that does not match every value of the appropriate type.
590 589
591 A local $\mt{val}$ declaration may bind a pattern instead of just a plain variable. As for function arguments, only irrefutable patterns are legal. 590 A local $\mt{val}$ declaration may bind a pattern instead of just a plain variable. As for function arguments, only irrefutable patterns are legal.
592 591
593 The keyword $\mt{fun}$ is a shorthand for $\mt{val} \; \mt{rec}$ that allows arguments to be specified before the equal sign in the definition of each mutually-recursive function, as in SML. Each curried argument must follow the grammar of the $b$ non-terminal introduced two paragraphs ago. A $\mt{fun}$ declaration is elaborated into a version that adds additional $\lambda$s to the fronts of the righthand sides, as appropriate. 592 The keyword $\mt{fun}$ is a shorthand for $\mt{val} \; \mt{rec}$ that allows arguments to be specified before the equal sign in the definition of each mutually recursive function, as in SML. Each curried argument must follow the grammar of the $b$ non-terminal introduced two paragraphs ago. A $\mt{fun}$ declaration is elaborated into a version that adds additional $\lambda$s to the fronts of the righthand sides, as appropriate.
594 593
595 A signature item $\mt{functor} \; X_1 \; (X_2 : S_1) : S_2$ is elaborated into $\mt{structure} \; X_1 : \mt{functor}(X_2 : S_1) : S_2$. A declaration $\mt{functor} \; X_1 \; (X_2 : S_1) : S_2 = M$ is elaborated into $\mt{structure} \; X_1 : \mt{functor}(X_2 : S_1) : S_2 = \mt{functor}(X_2 : S_1) : S_2 = M$. 594 A signature item $\mt{functor} \; X_1 \; (X_2 : S_1) : S_2$ is elaborated into $\mt{structure} \; X_1 : \mt{functor}(X_2 : S_1) : S_2$. A declaration $\mt{functor} \; X_1 \; (X_2 : S_1) : S_2 = M$ is elaborated into $\mt{structure} \; X_1 : \mt{functor}(X_2 : S_1) : S_2 = \mt{functor}(X_2 : S_1) : S_2 = M$.
596 595
597 An $\mt{open} \; \mt{constraints}$ declaration is implicitly inserted for the argument of every functor at the beginning of the functor body. For every declaration of the form $\mt{structure} \; X : S = \mt{struct} \ldots \mt{end}$, an $\mt{open} \; \mt{constraints} \; X$ declaration is implicitly inserted immediately afterward. 596 An $\mt{open} \; \mt{constraints}$ declaration is implicitly inserted for the argument of every functor at the beginning of the functor body. For every declaration of the form $\mt{structure} \; X : S = \mt{struct} \ldots \mt{end}$, an $\mt{open} \; \mt{constraints} \; X$ declaration is implicitly inserted immediately afterward.
598 597
947 946
948 \subsection{Declaration Typing} 947 \subsection{Declaration Typing}
949 948
950 We use an auxiliary judgment $\overline{y}; x; \Gamma \vdash \overline{dc} \leadsto \Gamma'$, expressing the enrichment of $\Gamma$ with the types of the datatype constructors $\overline{dc}$, when they are known to belong to datatype $x$ with type parameters $\overline{y}$. 949 We use an auxiliary judgment $\overline{y}; x; \Gamma \vdash \overline{dc} \leadsto \Gamma'$, expressing the enrichment of $\Gamma$ with the types of the datatype constructors $\overline{dc}$, when they are known to belong to datatype $x$ with type parameters $\overline{y}$.
951 950
952 This is the first judgment where we deal with constructor classes, for the $\mt{class}$ declaration form. We will omit their special handling in this formal specification. Section \ref{typeclasses} gives an informal description of how constructor classes influence type inference.
953
954 We presuppose the existence of a function $\mathcal O$, where $\mathcal O(M, \overline{s})$ implements the $\mt{open}$ declaration by producing a context with the appropriate entry for each available component of module $M$ with signature items $\overline{s}$. Where possible, $\mathcal O$ uses ``transparent'' entries (e.g., an abstract type $M.x$ is mapped to $x :: \mt{Type} = M.x$), so that the relationship with $M$ is maintained. A related function $\mathcal O_c$ builds a context containing the disjointness constraints found in $\overline s$. 951 We presuppose the existence of a function $\mathcal O$, where $\mathcal O(M, \overline{s})$ implements the $\mt{open}$ declaration by producing a context with the appropriate entry for each available component of module $M$ with signature items $\overline{s}$. Where possible, $\mathcal O$ uses ``transparent'' entries (e.g., an abstract type $M.x$ is mapped to $x :: \mt{Type} = M.x$), so that the relationship with $M$ is maintained. A related function $\mathcal O_c$ builds a context containing the disjointness constraints found in $\overline s$.
955 We write $\kappa_1^n \to \kappa$ as a shorthand, where $\kappa_1^0 \to \kappa = \kappa$ and $\kappa_1^{n+1} \to \kappa_2 = \kappa_1 \to (\kappa_1^n \to \kappa_2)$. We write $\mt{len}(\overline{y})$ for the length of vector $\overline{y}$ of variables. 952 We write $\kappa_1^n \to \kappa$ as a shorthand, where $\kappa_1^0 \to \kappa = \kappa$ and $\kappa_1^{n+1} \to \kappa_2 = \kappa_1 \to (\kappa_1^n \to \kappa_2)$. We write $\mt{len}(\overline{y})$ for the length of vector $\overline{y}$ of variables.
956 953
957 $$\infer{\Gamma \vdash \cdot \leadsto \Gamma}{} 954 $$\infer{\Gamma \vdash \cdot \leadsto \Gamma}{}
958 \quad \infer{\Gamma \vdash d, \overline{d} \leadsto \Gamma''}{ 955 \quad \infer{\Gamma \vdash d, \overline{d} \leadsto \Gamma''}{
1024 $$\infer{\Gamma \vdash \mt{task} \; e_1 = e_2 \leadsto \Gamma}{ 1021 $$\infer{\Gamma \vdash \mt{task} \; e_1 = e_2 \leadsto \Gamma}{
1025 \Gamma \vdash e_1 :: \mt{Basis}.\mt{task\_kind} \; \tau 1022 \Gamma \vdash e_1 :: \mt{Basis}.\mt{task\_kind} \; \tau
1026 & \Gamma \vdash e_2 :: \tau \to \mt{Basis}.\mt{transaction} \; \{\} 1023 & \Gamma \vdash e_2 :: \tau \to \mt{Basis}.\mt{transaction} \; \{\}
1027 }$$ 1024 }$$
1028 1025
1029 $$\infer{\Gamma \vdash \mt{class} \; x :: \kappa = c \leadsto \Gamma, x :: \kappa = c}{
1030 \Gamma \vdash c :: \kappa
1031 }$$
1032
1033 $$\infer{\overline{y}; x; \Gamma \vdash \cdot \leadsto \Gamma}{} 1026 $$\infer{\overline{y}; x; \Gamma \vdash \cdot \leadsto \Gamma}{}
1034 \quad \infer{\overline{y}; x; \Gamma \vdash X \mid \overline{dc} \leadsto \Gamma', X : \overline{y ::: \mt{Type}} \to x \; \overline{y}}{ 1027 \quad \infer{\overline{y}; x; \Gamma \vdash X \mid \overline{dc} \leadsto \Gamma', X : \overline{y ::: \mt{Type}} \to x \; \overline{y}}{
1035 \overline{y}; x; \Gamma \vdash \overline{dc} \leadsto \Gamma' 1028 \overline{y}; x; \Gamma \vdash \overline{dc} \leadsto \Gamma'
1036 } 1029 }
1037 \quad \infer{\overline{y}; x; \Gamma \vdash X \; \mt{of} \; \tau \mid \overline{dc} \leadsto \Gamma', X : \overline{y ::: \mt{Type}} \to \tau \to x \; \overline{y}}{ 1030 \quad \infer{\overline{y}; x; \Gamma \vdash X \; \mt{of} \; \tau \mid \overline{dc} \leadsto \Gamma', X : \overline{y ::: \mt{Type}} \to \tau \to x \; \overline{y}}{
1039 }$$ 1032 }$$
1040 1033
1041 \subsection{Signature Item Typing} 1034 \subsection{Signature Item Typing}
1042 1035
1043 We appeal to a signature item analogue of the $\mathcal O$ function from the last subsection. 1036 We appeal to a signature item analogue of the $\mathcal O$ function from the last subsection.
1037
1038 This is the first judgment where we deal with constructor classes, for the $\mt{class}$ forms. We will omit their special handling in this formal specification. Section \ref{typeclasses} gives an informal description of how constructor classes influence type inference.
1044 1039
1045 $$\infer{\Gamma \vdash \cdot \leadsto \Gamma}{} 1040 $$\infer{\Gamma \vdash \cdot \leadsto \Gamma}{}
1046 \quad \infer{\Gamma \vdash s, \overline{s} \leadsto \Gamma''}{ 1041 \quad \infer{\Gamma \vdash s, \overline{s} \leadsto \Gamma''}{
1047 \Gamma \vdash s \leadsto \Gamma' 1042 \Gamma \vdash s \leadsto \Gamma'
1048 & \Gamma' \vdash \overline{s} \leadsto \Gamma'' 1043 & \Gamma' \vdash \overline{s} \leadsto \Gamma''
1088 } 1083 }
1089 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa \leadsto \Gamma, x :: \kappa}{}$$ 1084 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa \leadsto \Gamma, x :: \kappa}{}$$
1090 1085
1091 \subsection{Signature Compatibility} 1086 \subsection{Signature Compatibility}
1092 1087
1093 To simplify the judgments in this section, we assume that all signatures are alpha-varied as necessary to avoid including multiple bindings for the same identifier. This is in addition to the usual alpha-variation of locally-bound variables. 1088 To simplify the judgments in this section, we assume that all signatures are alpha-varied as necessary to avoid including multiple bindings for the same identifier. This is in addition to the usual alpha-variation of locally bound variables.
1094 1089
1095 We rely on a judgment $\Gamma \vdash \overline{s} \leq s'$, which expresses the occurrence in signature items $\overline{s}$ of an item compatible with $s'$. We also use a judgment $\Gamma \vdash \overline{dc} \leq \overline{dc}$, which expresses compatibility of datatype definitions. 1090 We rely on a judgment $\Gamma \vdash \overline{s} \leq s'$, which expresses the occurrence in signature items $\overline{s}$ of an item compatible with $s'$. We also use a judgment $\Gamma \vdash \overline{dc} \leq \overline{dc}$, which expresses compatibility of datatype definitions.
1096 1091
1097 $$\infer{\Gamma \vdash S \equiv S}{} 1092 $$\infer{\Gamma \vdash S \equiv S}{}
1098 \quad \infer{\Gamma \vdash S_1 \equiv S_2}{ 1093 \quad \infer{\Gamma \vdash S_1 \equiv S_2}{
1196 }$$ 1191 }$$
1197 1192
1198 $$\infer{\Gamma \vdash \mt{class} \; x :: \kappa \leq \mt{class} \; x :: \kappa}{} 1193 $$\infer{\Gamma \vdash \mt{class} \; x :: \kappa \leq \mt{class} \; x :: \kappa}{}
1199 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa = c \leq \mt{class} \; x :: \kappa}{} 1194 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa = c \leq \mt{class} \; x :: \kappa}{}
1200 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa = c_1 \leq \mt{class} \; x :: \kappa = c_2}{ 1195 \quad \infer{\Gamma \vdash \mt{class} \; x :: \kappa = c_1 \leq \mt{class} \; x :: \kappa = c_2}{
1196 \Gamma \vdash c_1 \equiv c_2
1197 }$$
1198
1199 $$\infer{\Gamma \vdash \mt{con} \; x :: \kappa \leq \mt{class} \; x :: \kappa}{}
1200 \quad \infer{\Gamma \vdash \mt{con} \; x :: \kappa = c \leq \mt{class} \; x :: \kappa}{}
1201 \quad \infer{\Gamma \vdash \mt{con} \; x :: \kappa = c_1 \leq \mt{class} \; x :: \kappa = c_2}{
1201 \Gamma \vdash c_1 \equiv c_2 1202 \Gamma \vdash c_1 \equiv c_2
1202 }$$ 1203 }$$
1203 1204
1204 \subsection{Module Typing} 1205 \subsection{Module Typing}
1205 1206
1247 \mt{sigOf}(\mt{open} \; \mt{constraints} \; M) &=& \cdot \\ 1248 \mt{sigOf}(\mt{open} \; \mt{constraints} \; M) &=& \cdot \\
1248 \mt{sigOf}(\mt{table} \; x : c) &=& \mt{table} \; x : c \\ 1249 \mt{sigOf}(\mt{table} \; x : c) &=& \mt{table} \; x : c \\
1249 \mt{sigOf}(\mt{view} \; x = e) &=& \mt{view} \; x : c \textrm{ (where $\Gamma \vdash e : \mt{Basis}.\mt{sql\_query} \; [] \; [] \; (\mt{map} \; (\lambda \_ \Rightarrow []) \; c') \; c$)} \\ 1250 \mt{sigOf}(\mt{view} \; x = e) &=& \mt{view} \; x : c \textrm{ (where $\Gamma \vdash e : \mt{Basis}.\mt{sql\_query} \; [] \; [] \; (\mt{map} \; (\lambda \_ \Rightarrow []) \; c') \; c$)} \\
1250 \mt{sigOf}(\mt{sequence} \; x) &=& \mt{sequence} \; x \\ 1251 \mt{sigOf}(\mt{sequence} \; x) &=& \mt{sequence} \; x \\
1251 \mt{sigOf}(\mt{cookie} \; x : \tau) &=& \mt{cookie} \; x : \tau \\ 1252 \mt{sigOf}(\mt{cookie} \; x : \tau) &=& \mt{cookie} \; x : \tau \\
1252 \mt{sigOf}(\mt{style} \; x) &=& \mt{style} \; x \\ 1253 \mt{sigOf}(\mt{style} \; x) &=& \mt{style} \; x
1253 \mt{sigOf}(\mt{class} \; x :: \kappa = c) &=& \mt{class} \; x :: \kappa = c \\
1254 \end{eqnarray*} 1254 \end{eqnarray*}
1255 \begin{eqnarray*} 1255 \begin{eqnarray*}
1256 \mt{selfify}(M, \cdot) &=& \cdot \\ 1256 \mt{selfify}(M, \cdot) &=& \cdot \\
1257 \mt{selfify}(M, s \; \overline{s'}) &=& \mt{selfify}(M, s) \; \mt{selfify}(M, \overline{s'}) \\ 1257 \mt{selfify}(M, s \; \overline{s'}) &=& \mt{selfify}(M, s) \; \mt{selfify}(M, \overline{s'}) \\
1258 \\ 1258 \\
1327 1327
1328 \subsection{\label{typeclasses}Constructor Classes} 1328 \subsection{\label{typeclasses}Constructor Classes}
1329 1329
1330 Ur includes a constructor class facility inspired by Haskell's. The current version is experimental, with very general Prolog-like facilities that can lead to compile-time non-termination. 1330 Ur includes a constructor class facility inspired by Haskell's. The current version is experimental, with very general Prolog-like facilities that can lead to compile-time non-termination.
1331 1331
1332 Constructor classes are integrated with the module system. A constructor class of kind $\kappa$ is just a constructor of kind $\kappa$. By marking such a constructor $c$ as a constructor class, the programmer instructs the type inference engine to, in each scope, record all values of types $c \; c_1 \; \ldots \; c_n$ as \emph{instances}. Any function argument whose type is of such a form is treated as implicit, to be determined by examining the current instance database. 1332 Constructor classes are integrated with the module system. A constructor class of kind $\kappa$ is just a constructor of kind $\kappa$. By marking such a constructor $c$ as a constructor class, the programmer instructs the type inference engine to, in each scope, record all values of types $c \; c_1 \; \ldots \; c_n$ as \emph{instances}. Any function argument whose type is of such a form is treated as implicit, to be determined by examining the current instance database. Any suitably kinded constructor within a module may be exposed as a constructor class from outside the module, simply by using a $\mt{class}$ signature item instead of a $\mt{con}$ signature item in the module's signature.
1333 1333
1334 The ``dictionary encoding'' often used in Haskell implementations is made explicit in Ur. Constructor class instances are just properly-typed values, and they can also be considered as ``proofs'' of membership in the class. In some cases, it is useful to pass these proofs around explicitly. An underscore written where a proof is expected will also be inferred, if possible, from the current instance database. 1334 The ``dictionary encoding'' often used in Haskell implementations is made explicit in Ur. Constructor class instances are just properly typed values, and they can also be considered as ``proofs'' of membership in the class. In some cases, it is useful to pass these proofs around explicitly. An underscore written where a proof is expected will also be inferred, if possible, from the current instance database.
1335 1335
1336 Just as for constructors, constructors classes may be exported from modules, and they may be exported as concrete or abstract. Concrete constructor classes have their ``real'' definitions exposed, so that client code may add new instances freely. Abstract constructor classes are useful as ``predicates'' that can be used to enforce invariants, as we will see in some definitions of SQL syntax in the Ur/Web standard library. 1336 Just as for constructors, constructors classes may be exported from modules, and they may be exported as concrete or abstract. Concrete constructor classes have their ``real'' definitions exposed, so that client code may add new instances freely. Automatic inference of concrete class instances will not generally work, so abstract classes are almost always the right choice. They are useful as ``predicates'' that can be used to enforce invariants, as we will see in some definitions of SQL syntax in the Ur/Web standard library. Free extension of a concrete class is easily supported by exporting a constructor function from a module, since the class implementation will be concrete within the module.
1337 1337
1338 \subsection{Reverse-Engineering Record Types} 1338 \subsection{Reverse-Engineering Record Types}
1339 1339
1340 It's useful to write Ur functions and functors that take record constructors as inputs, but these constructors can grow quite long, even though their values are often implied by other arguments. The compiler uses a simple heuristic to infer the values of unification variables that are mapped over, yielding known results. If the result is empty, we're done; if it's not empty, we replace a single unification variable with a new constructor formed from three new unification variables, as in $[\alpha = \beta] \rc \gamma$. This process can often be repeated to determine a unification variable fully. 1340 It's useful to write Ur functions and functors that take record constructors as inputs, but these constructors can grow quite long, even though their values are often implied by other arguments. The compiler uses a simple heuristic to infer the values of unification variables that are mapped over, yielding known results. If the result is empty, we're done; if it's not empty, we replace a single unification variable with a new constructor formed from three new unification variables, as in $[\alpha = \beta] \rc \gamma$. This process can often be repeated to determine a unification variable fully.
1341 1341
1432 \mt{val} \; \mt{debug} : \mt{string} \to \mt{transaction} \; \mt{unit} 1432 \mt{val} \; \mt{debug} : \mt{string} \to \mt{transaction} \; \mt{unit}
1433 \end{array}$$ 1433 \end{array}$$
1434 1434
1435 \subsection{HTTP} 1435 \subsection{HTTP}
1436 1436
1437 There are transactions for reading an HTTP header by name and for getting and setting strongly-typed cookies. Cookies may only be created by the $\mt{cookie}$ declaration form, ensuring that they be named consistently based on module structure. For now, cookie operations are server-side only. 1437 There are transactions for reading an HTTP header by name and for getting and setting strongly typed cookies. Cookies may only be created by the $\mt{cookie}$ declaration form, ensuring that they be named consistently based on module structure. For now, cookie operations are server-side only.
1438 $$\begin{array}{l} 1438 $$\begin{array}{l}
1439 \mt{con} \; \mt{http\_cookie} :: \mt{Type} \to \mt{Type} \\ 1439 \mt{con} \; \mt{http\_cookie} :: \mt{Type} \to \mt{Type} \\
1440 \mt{val} \; \mt{getCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \mt{transaction} \; (\mt{option} \; \mt{t}) \\ 1440 \mt{val} \; \mt{getCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \mt{transaction} \; (\mt{option} \; \mt{t}) \\
1441 \mt{val} \; \mt{setCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \{\mt{Value} : \mt{t}, \mt{Expires} : \mt{option} \; \mt{time}, \mt{Secure} : \mt{bool}\} \to \mt{transaction} \; \mt{unit} \\ 1441 \mt{val} \; \mt{setCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \{\mt{Value} : \mt{t}, \mt{Expires} : \mt{option} \; \mt{time}, \mt{Secure} : \mt{bool}\} \to \mt{transaction} \; \mt{unit} \\
1442 \mt{val} \; \mt{clearCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \mt{transaction} \; \mt{unit} 1442 \mt{val} \; \mt{clearCookie} : \mt{t} ::: \mt{Type} \to \mt{http\_cookie} \; \mt{t} \to \mt{transaction} \; \mt{unit}
1775 \mt{val} \; \mt{sql\_times} : \mt{t} ::: \mt{Type} \to \mt{sql\_arith} \; \mt{t} \to \mt{sql\_binary} \; \mt{t} \; \mt{t} \; \mt{t} \\ 1775 \mt{val} \; \mt{sql\_times} : \mt{t} ::: \mt{Type} \to \mt{sql\_arith} \; \mt{t} \to \mt{sql\_binary} \; \mt{t} \; \mt{t} \; \mt{t} \\
1776 \mt{val} \; \mt{sql\_div} : \mt{t} ::: \mt{Type} \to \mt{sql\_arith} \; \mt{t} \to \mt{sql\_binary} \; \mt{t} \; \mt{t} \; \mt{t} \\ 1776 \mt{val} \; \mt{sql\_div} : \mt{t} ::: \mt{Type} \to \mt{sql\_arith} \; \mt{t} \to \mt{sql\_binary} \; \mt{t} \; \mt{t} \; \mt{t} \\
1777 \mt{val} \; \mt{sql\_mod} : \mt{sql\_binary} \; \mt{int} \; \mt{int} \; \mt{int} 1777 \mt{val} \; \mt{sql\_mod} : \mt{sql\_binary} \; \mt{int} \; \mt{int} \; \mt{int}
1778 \end{array}$$ 1778 \end{array}$$
1779 1779
1780 Finally, we have aggregate functions. The $\mt{COUNT(\ast)}$ syntax is handled specially, since it takes no real argument. The other aggregate functions are placed into a general type family, using constructor classes to restrict usage to properly-typed arguments. The key aspect of the $\mt{sql\_aggregate}$ function's type is the shift of aggregate-function-only fields into unrestricted fields. 1780 Finally, we have aggregate functions. The $\mt{COUNT(\ast)}$ syntax is handled specially, since it takes no real argument. The other aggregate functions are placed into a general type family, using constructor classes to restrict usage to properly typed arguments. The key aspect of the $\mt{sql\_aggregate}$ function's type is the shift of aggregate-function-only fields into unrestricted fields.
1781 $$\begin{array}{l} 1781 $$\begin{array}{l}
1782 \mt{val} \; \mt{sql\_count} : \mt{tables} ::: \{\{\mt{Type}\}\} \to \mt{agg} ::: \{\{\mt{Type}\}\} \to \mt{exps} ::: \{\mt{Type}\} \to \mt{sql\_exp} \; \mt{tables} \; \mt{agg} \; \mt{exps} \; \mt{int} 1782 \mt{val} \; \mt{sql\_count} : \mt{tables} ::: \{\{\mt{Type}\}\} \to \mt{agg} ::: \{\{\mt{Type}\}\} \to \mt{exps} ::: \{\mt{Type}\} \to \mt{sql\_exp} \; \mt{tables} \; \mt{agg} \; \mt{exps} \; \mt{int}
1783 \end{array}$$ 1783 \end{array}$$
1784 1784
1785 $$\begin{array}{l} 1785 $$\begin{array}{l}
1937 1937
1938 $$\begin{array}{l} 1938 $$\begin{array}{l}
1939 \mt{val} \; \mt{tryDml} : \mt{dml} \to \mt{transaction} \; (\mt{option} \; \mt{string}) 1939 \mt{val} \; \mt{tryDml} : \mt{dml} \to \mt{transaction} \; (\mt{option} \; \mt{string})
1940 \end{array}$$ 1940 \end{array}$$
1941 1941
1942 Properly-typed records may be used to form $\mt{INSERT}$ commands. 1942 Properly typed records may be used to form $\mt{INSERT}$ commands.
1943 $$\begin{array}{l} 1943 $$\begin{array}{l}
1944 \mt{val} \; \mt{insert} : \mt{fields} ::: \{\mt{Type}\} \to \mt{sql\_table} \; \mt{fields} \\ 1944 \mt{val} \; \mt{insert} : \mt{fields} ::: \{\mt{Type}\} \to \mt{sql\_table} \; \mt{fields} \\
1945 \hspace{.1in} \to \$(\mt{map} \; (\mt{sql\_exp} \; [] \; [] \; []) \; \mt{fields}) \to \mt{dml} 1945 \hspace{.1in} \to \$(\mt{map} \; (\mt{sql\_exp} \; [] \; [] \; []) \; \mt{fields}) \to \mt{dml}
1946 \end{array}$$ 1946 \end{array}$$
1947 1947
2304 2304
2305 Similar support is provided for \cd{style} attributes. Normal CSS syntax may be used in string literals that are \cd{style} attribute values, and the desugaring may be accessed elsewhere with the pseudo-function \cd{STYLE}. 2305 Similar support is provided for \cd{style} attributes. Normal CSS syntax may be used in string literals that are \cd{style} attribute values, and the desugaring may be accessed elsewhere with the pseudo-function \cd{STYLE}.
2306 2306
2307 \section{\label{structure}The Structure of Web Applications} 2307 \section{\label{structure}The Structure of Web Applications}
2308 2308
2309 A web application is built from a series of modules, with one module, the last one appearing in the \texttt{.urp} file, designated as the main module. The signature of the main module determines the URL entry points to the application. Such an entry point should have type $\mt{t1} \to \ldots \to \mt{tn} \to \mt{transaction} \; \mt{page}$, for any integer $n \geq 0$, where $\mt{page}$ is a type synonym for top-level HTML pages, defined in $\mt{Basis}$. If such a function is at the top level of main module $M$, with $n = 0$, it will be accessible at URI \texttt{/M/f}, and so on for more deeply-nested functions, as described in Section \ref{tag} below. See Section \ref{cl} for information on the \texttt{prefix} and \texttt{rewrite url} directives, which can be used to rewrite the default URIs of different entry point functions. The final URL of a function is its default module-based URI, with \texttt{rewrite url} rules applied, and with the \texttt{prefix} prepended. Arguments to an entry-point function are deserialized from the part of the URI following \texttt{f}. 2309 A web application is built from a series of modules, with one module, the last one appearing in the \texttt{.urp} file, designated as the main module. The signature of the main module determines the URL entry points to the application. Such an entry point should have type $\mt{t1} \to \ldots \to \mt{tn} \to \mt{transaction} \; \mt{page}$, for any integer $n \geq 0$, where $\mt{page}$ is a type synonym for top-level HTML pages, defined in $\mt{Basis}$. If such a function is at the top level of main module $M$, with $n = 0$, it will be accessible at URI \texttt{/M/f}, and so on for more deeply nested functions, as described in Section \ref{tag} below. See Section \ref{cl} for information on the \texttt{prefix} and \texttt{rewrite url} directives, which can be used to rewrite the default URIs of different entry point functions. The final URL of a function is its default module-based URI, with \texttt{rewrite url} rules applied, and with the \texttt{prefix} prepended. Arguments to an entry-point function are deserialized from the part of the URI following \texttt{f}.
2310 2310
2311 Elements of modules beside the main module, including page handlers, will only be included in the final application if they are transitive dependencies of the handlers in the main module. 2311 Elements of modules beside the main module, including page handlers, will only be included in the final application if they are transitive dependencies of the handlers in the main module.
2312 2312
2313 Normal links are accessible via HTTP \texttt{GET}, which the relevant standard says should never cause side effects. To export a page which may cause side effects, accessible only via HTTP \texttt{POST}, include one argument of the page handler of type $\mt{Basis.postBody}$. When the handler is called, this argument will receive a value that can be deconstructed into a MIME type (with $\mt{Basis.postType}$) and payload (with $\mt{Basis.postData}$). This kind of handler should not be used with forms that exist solely within Ur/Web apps; for these, use Ur/Web's built-in support, as described below. It may still be useful to use $\mt{Basis.postBody}$ with form requests submitted by code outside an Ur/Web app. For such cases, the function $\mt{Top.postFields} : \mt{postBody} \to \mt{list} \; (\mt{string} \times \mt{string})$ may be useful, breaking a \texttt{POST} body of type \texttt{application/x-www-form-urlencoded} into its name-value pairs. 2313 Normal links are accessible via HTTP \texttt{GET}, which the relevant standard says should never cause side effects. To export a page which may cause side effects, accessible only via HTTP \texttt{POST}, include one argument of the page handler of type $\mt{Basis.postBody}$. When the handler is called, this argument will receive a value that can be deconstructed into a MIME type (with $\mt{Basis.postType}$) and payload (with $\mt{Basis.postData}$). This kind of handler should not be used with forms that exist solely within Ur/Web apps; for these, use Ur/Web's built-in support, as described below. It may still be useful to use $\mt{Basis.postBody}$ with form requests submitted by code outside an Ur/Web app. For such cases, the function $\mt{Top.postFields} : \mt{postBody} \to \mt{list} \; (\mt{string} \times \mt{string})$ may be useful, breaking a \texttt{POST} body of type \texttt{application/x-www-form-urlencoded} into its name-value pairs.
2314 2314
2504 2504
2505 Functions are specialized to particular argument patterns. This is an important trick for avoiding the need to maintain any closures at runtime. Currently, specialization only happens for prefixes of a function's full list of parameters, so you may need to take care to put arguments of function types before other arguments. The optimizer will not be effective enough if you use arguments that mix functions and values that must be calculated at run-time. For instance, a tuple of a function and an integer counter would not lead to successful code generation; these should be split into separate arguments via currying. 2505 Functions are specialized to particular argument patterns. This is an important trick for avoiding the need to maintain any closures at runtime. Currently, specialization only happens for prefixes of a function's full list of parameters, so you may need to take care to put arguments of function types before other arguments. The optimizer will not be effective enough if you use arguments that mix functions and values that must be calculated at run-time. For instance, a tuple of a function and an integer counter would not lead to successful code generation; these should be split into separate arguments via currying.
2506 2506
2507 \subsection{Untangle} 2507 \subsection{Untangle}
2508 2508
2509 Remove unnecessary mutual recursion, splitting recursive groups into strongly-connected components. 2509 Remove unnecessary mutual recursion, splitting recursive groups into strongly connected components.
2510 2510
2511 \subsection{Shake} 2511 \subsection{Shake}
2512 2512
2513 Remove all definitions not needed to run the page handlers that are visible in the signature of the last module listed in the \texttt{.urp} file. 2513 Remove all definitions not needed to run the page handlers that are visible in the signature of the last module listed in the \texttt{.urp} file.
2514 2514