# HG changeset patch # User Adam Chlipala # Date 1224798724 14400 # Node ID 9119a5920106b137e97ee859175ff6c899782ba8 # Parent cb5897276abf5b6978014433b8ace40d19459da4 Prose for Ref and Metaform diff -r cb5897276abf -r 9119a5920106 demo/prose --- a/demo/prose Thu Oct 23 17:35:10 2008 -0400 +++ b/demo/prose Thu Oct 23 17:52:04 2008 -0400 @@ -76,6 +76,12 @@

+ref.urp + +

This example shows how to mix the module system with SQL to implement a kind of "abstract data type." The functor RefFun.Make takes in a type belonging to the type class of those types that may be included in SQL. The functor output includes an abstract type ref, along with operations for working with refs via transactions. In the functor implementation, we see that ref is implemented as int, treated as primary keys of a SQL table.

+ +

The functor creates a new encapsulated SQL sequence and table on each call. These local relations show up in the automatically-generated SQL file that should be run to prepare the database for use, but they are invisible from client code. We could change the functor to create different SQL relations, without needing to change client code.

+ sum.urp

Metaprogramming is one of the most important facilities of Ur. This example shows how to write a function that is able to sum up the fields of records of integers, no matter which set of fields the particular record has.

@@ -107,6 +113,11 @@ metaform1.urp +

We can use metaprogramming with row types to build HTML forms (and their handlers) generically. The functor Metaform.Make takes in a unit row fs and a value-level record names assigning string names to the fields of fs. The functor implementation builds a form handler with a library function foldURX2, which runs over two value-level records in parallel, building an XML fragment.

+ +

The form itself is generated using the more primitive foldUR. We see the type xml form [] (mapUT string cols) as the result of the fold. This is the type of XML fragments that are suitable for inclusion in forms, require no form fields to be defined on entry, and themselves define form fields whose names and types are given by mapUT string cols. The useMore function "weakens" the type of an XML fragment, so that it "pretends" to require additional fields as input. This weakening is necessary to accommodate the general typing rule for concatenating bits of XML. +

The functor use in Metaform1 is trivial. The compiler infers the value of the structure member fs from the type of the value provided for names.

+ metaform2.urp -ref.urp +

This example showcases code reuse by applying the same functor as in the last example. The Metaform2 module mixes pages from the functor with some new pages of its own.

diff -r cb5897276abf -r 9119a5920106 demo/refFun.ur --- a/demo/refFun.ur Thu Oct 23 17:35:10 2008 -0400 +++ b/demo/refFun.ur Thu Oct 23 17:52:04 2008 -0400 @@ -24,4 +24,5 @@ fun delete r = dml (DELETE FROM t WHERE Id = {r}) + end