Mercurial > urweb
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 |