Seminar Topics & Project Ideas On Computer Science Electronics Electrical Mechanical Engineering Civil MBA Medicine Nursing Science Physics Mathematics Chemistry ppt pdf doc presentation downloads and Abstract

Full Version: Ur/Web: A Simple Model for Programming the Web
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
[attachment=73050]


Abstract
The World Wide Web has evolved gradually from a document delivery
platform to an architecture for distributed programming. This
largely unplanned evolution is apparent in the set of interconnected
languages and protocols that any Web application must manage.
This paper presents Ur/Web, a domain-specific, statically typed
functional programming language with a much simpler model for
programming modern Web applications. Ur/Web’s model is uni-
fied, where programs in a single programming language are compiled
to other “Web standards” languages as needed; supports novel
kinds of encapsulation of Web-specific state; and exposes simple
concurrency, where programmers can reason about distributed,
multithreaded applications via a mix of transactions and cooperative
preemption. We give a tutorial introduction to the main features
of Ur/Web and discuss the language implementation and the
production Web applications that use it.
Categories and Subject Descriptors D.2.2 [Software Engineering]:
Design Tools and Techniques - Modules and interfaces;
D.3.2 [Programming Languages]: Language Classifications - Concurrent,
distributed, and parallel languages; Applicative (functional)
languages



Introduction
The World Wide Web is a very popular platform today for programming
certain kinds of distributed applications with graphical user
interfaces (GUIs). Today’s complex ecosystem of “Web standards”
was not planned monolithically. Rather, it evolved gradually, from
the starting point of the Web as a delivery system for static documents.
The result is not surprising: there are many pain points in
implementing rich functionality on top of the particular languages
that browsers and servers speak. At a minimum, today’s rich applications
must generate HTML, for document structure; CSS, for
document formatting; JavaScript, a scripting language for clientside
interactivity; and HTTP, a protocol for sending all of the above
and more, to and from browsers. Most recent, popular applications
also rely on a language like JSON for serializing complex datatypes


for network communication, and on a language or API like SQL
for storing persistent, structured data on servers. Code fragments
in these different languages are often embedded within each other
in complex ways, and the popular Web development tools provide
little help in catching inconsistencies.
These complaints are not new, nor are language-based solutions.
The Links project [7, 11] pioneered the “tierless programming”
approach, combining all the pieces of dynamic Web applications
within one statically typed functional language. More recent designs
in the mainstream reap some similar benefits, as in Google’s
Web Toolkit1
and Closure2
systems, for adding compilation on top
of Web-standard languages; and Microsoft’s LINQ [27], for typesafe
querying (to SQL databases and more) within general-purpose
languages.
Such established systems provide substantial benefits to Web
programmers, but there is more we could ask for. This paper focuses
on a language design that advances the state of the art by addressing
two key desiderata. First, we bring encapsulation to rich
Web applications, supporting program modules that treat key pieces
of Web applications as private state. Second, we expose a simple
concurrency model to programmers, while supporting the kinds of
nontrivial communication between clients and servers that today’s
applications take advantage of. Most Web programmers seem unaware
of either property as something that might be worth asking
for, so part of our mission in this paper is to evangelize for them.
We present the Ur/Web programming language, an extension
of the Ur language [8], a statically typed functional language inspired
by dependent type theory. A prior paper described Ur and
its type system, but did not discuss the Web-specific extensions.
Open-source implementations of Ur/Web have been available since
2006, and several production Web applications use the language,
including at least one profitable commercial site.
Ur/Web reduces the nest of Web standards to a simple programming
model, coming close to retaining just the essence of the Web
as an application platform, from the standpoints of security and
performance.
• An application is a program in one language (Ur/Web) that runs
on one server and many clients, with automatic compilation of
parts of programs into the languages appropriate to the different
nodes (e.g., JavaScript). The server is completely under the programmer’s
control, while clients may deviate arbitrarily from
code we provide to them to run. For reasons of performance
scaling or reliability, we may use multiple physical machines
to implement server functionality, but it is sound for the programmer
to imagine all server code running in a single isolated
machine.
• All objects passed between parts of the application are strongly
typed. Applications may be written with no explicit marshaling


or other conversion of data between formats. Where snippets of
code appear as first-class values, they are presented as abstract
syntax trees, ruling out flaws like code injection vulnerabilities
that rely on surprising consequences of concatenating code-asstrings.
• The only persistent state in the server sits in an SQL database,
accessed through a strongly typed SQL interface.
• The server exposes a set of typed functions that are callable
remotely. A client begins interacting with the application in a
new browser tab by making a remote procedure call to one of
these functions, with arbitrary correctly typed arguments.
The server runs the associated function atomically, with no
opportunity to observe interference by any other concurrent
operations, generating an HTML page that the client displays.
• The HTML page in a client may contain traditional links to
other pages, which are represented as suspended calls to other
remotely callable functions, to be forced when a link is followed,
to generate the new HTML page to display.
• Any HTML page may also contain embedded Ur/Web code
that runs in the client. Such code may spawn as many clientside
threads as is convenient, and the threads obey a cooperative
multithreading semantics, where one thread runs at a time,
and we only switch threads during well-defined blocking operations.
Threads may modify the GUI shown to the user, via a
functional-reactive programming system that mixes dataflow
programming with imperative callbacks.
• Client-side thread code may also make blocking remote procedure
calls treated similarly to those for regular links. Such
a call may return a value of any function-free type, not just
HTML pages; and the thread receiving the function result may
compute with it to change the visible GUI programmatically,
rather than by loading a completely new page. As before, every
remote procedure call appears to execute atomically on the
server.
• Server code may allocate typed message-passing channels,
which may be both stored in the database and returned to clients
via remote function calls. The server may send values to a channel,
and a client that has been passed the channel may receive
those values asynchronously. Channel sends are included in the
guarantee of atomicity for remote calls on the server; all sends
within a single call execution appear to transfer their messages
to the associated channels atomically.
The next section expands on these points with a tutorial introduction
to Ur/Web. We highlight the impact on the language design
of our goals to support encapsulation and simple concurrency.
Next, we describe key implementation techniques in the Ur/Web
compiler and runtime system, and we evaluate the effectiveness of
the language, partly through surveying deployed applications that
use it.
The open-source implementation of Ur/Web is available at:
http://www.impredicativeur/
2. A Tutorial Introduction to Ur/Web
We will introduce the key features of Ur/Web through a series of
refinements of one example, a multiuser chat application. Visitors
to the site choose from a selection of chat rooms, each of which
maintains a log of messages. Any visitor to a chat room may
append any line of text to the log, and there should be some
way for other users to stay up-to-date on log additions. We start
with a simple implementation, in the style of 20th-century Web
applications, before it became common to do significant client side scripting. We evolve toward a version with instant updating
upon all message additions, where a chat room runs within a single
HTML page updated incrementally by client-side code. Along the
way, we highlight our running themes of encapsulation and simple
concurrency.
2.1 HTML and SQL
Mainstream modern Web applications manipulate code in many
different languages and protocols. Ur/Web hides most of them
within a unified programming model, but we decided to expose
two languages explicitly: HTML, for describing the structure of
Web pages as trees, and SQL, for accessing a persistent relational
database on the server. In contrast to mainstream practice, Ur/Web
represents code fragments in these languages as first-class, strongly
typed values. We use the type system of Ur [8] to define rich syntax
tree types, where the generic type system is sufficient to enforce the
typing rules of the embedded languages, HTML and SQL. Going
into the details of type encoding would take us off-track in this
paper, so the reader may pretend that Ur/Web includes special builtin
support for type-checking HTML and SQL.
Figure 1 gives our first chat-room implementation, relying on
embedding of HTML and SQL code. While in general Ur/Web
programs contain code that runs on both server and clients, all code
from this figure runs on the server, where we are able to enforce
that it is run exactly as written in the source code.
The first two lines show declarations of SQL tables, which
can be thought of as mutable global variables of type “multiset
of records.” Table room’s records contain integer IDs and string
titles, while table message’s records contain integer room IDs,

timestamps, and string messages. The former table represents the
set of available chat rooms, while the latter represents the set of all
(timestamped) messages sent to all rooms.
It is unusual for a programming language to treat SQL tables as
declared within the language. The more common view is that the
SQL database exists as a resource “out there somewhere,” and the
programming language merely connects to it. Our strange choice
has important consequences for encapsulation, which we will get
to shortly.
We direct the reader’s attention now to the declaration of function
main, near the end of Figure 1. Here we see Ur/Web’s syntax
extensions for embedded SQL and HTML code. Such notation is
desugared into calls to constructors of abstract syntax tree types,
at which point the normal Ur type-checker may validate the typecorrectness
of embedded fragments. The main definition demonstrates
two notations for “antiquoting,” or inserting Ur code within
a quoted code fragment. The notation {e} asks to evaluate expression
e to produce a subfragment to be inserted at that point, and notation
{[e]} adds a further stage of formatting e as a literal of the
embedded language (using type classes [37] as in Haskell’s show).
Note that we are not exposing syntax trees to the programmer as
strings, so neither antiquoting form presents any danger of code injection
attacks, where we accidentally interpret user input as code.
What exactly does the main definition do? First, we run an SQL
query to list all chat rooms. In our tutorial examples, we will call a
variety of functions from Ur/Web’s standard library, especially various
higher-order functions for using SQL query results. We adopt
a typographic convention for documenting each library function
briefly, starting with queryX1, used in main:
queryX1 Run an SQL query that returns columns from a single table
(leading to the 1 in the identifier), calling an argument function
on every result row. Since just a single table is involved, the
input to the argument function can be a record with one field per
column returned by the query. The argument function should return
XML fragments (leading to the X in the identifier), and all
such fragments are concatenated together, in order, to form the
result of queryX1.
Note that a remotely callable function like main lives in a distinguished
monad for input-output [29] as in Haskell, since Ur is
purely functional. Thus, we use the <- notation to run an effectful
computation and bind its result to a variable, and we call the
return function to lift pure values into trivial computations.
The remaining interesting aspect of main is in its use of an
HTML <a> tag to generate a hyperlink. Instead of denoting a link
via a URL as in standard HTML, we use a link attribute that
accepts a suspended Ur/Web remote function call. In this case, we
call chat, which is defined earlier. The Ur/Web implementation
handles proper marshaling of arguments in suspended calls.
Now let us examine the implementation of function chat, providing
a page for viewing the current message log of a chat room.
First, there is a nested definition of a function say, which will be
called to append a message to the log.
dml Run a piece of SQL code for its side effect of mutating the
database. The function name refers to SQL’s data manipulation
language.
This particular invocation of dml inserts a new row into the
message table with the current timestamp, after which we display
the same page as chat itself would generate. Note that say,
like all remotely callable functions, appears to execute atomically,
so the programmer need not worry about interleavings between
concurrent operations by different clients. To tune performance,
programmers might want to indicate the boundaries of atomic execution
units explicitly, but we have found that it works well to make the atomic units be precisely the remote calls, which saves
programmers from needing to write any explicit code to begin or
end transactions.
The main body of chat runs appropriate queries to retrieve the
room name and the full, sorted message log.
oneRowE1 Run an SQL query that should return just one result
row containing just a single column (justifying the 1) that is
computed using an arbitrary SQL expression (justifying the E).
That one result value becomes the result of the oneRowE1 call.
We antiquote the query results into the returned page in an unsurprising
way. The only new feature involves HTML forms. In
general, we tag each input widget with a record field name, and
then the submit button of the form includes, in its action attribute,
an Ur/Web function that should be called upon submission, on a
record built by combining the values of all the input widgets. We
will not say any more about HTML forms, which to some extent
represent a legacy aspect of HTML that has been superseded by
client-side scripting. Forms are a non-Turing-complete language
for input solicitation, and these days it is more common to use a
Turing-complete language (JavaScript) for the same task.
Note that this first example already displays a small bit of encapsulation:
the local function say may only be referenced within
the declaration of chat. Clients may ignore the intended order of
link-following and visit say directly, but we at least know our application
itself will not accidentally generate links to say outside
the intended scope.
Compiling an application to run on the real Web platform requires
exposes remotely callable functions (like main, chat, and
say) via URLs. Ur/Web automatically generates pleasing URL
schemes by serializing the function-call expressions that appear in
places like link attributes. For instance, the link to chat in the
declaration of main is compiled to a URL /chat/NN, where NN
is a textual representation of the room ID. The link to say within
the submit button above is compiled like /say/NN, including the
value of a local variable id implicitly captured in the function.
The Ur/Web compiler handles generation of URL schemes in
such a way that it is guaranteed that no two functions will wind
up with conflicting schemes. This approach contrasts sharply with
the manual URL routing found in most mainstream frameworks.
There are serious costs to modularity when composing two libraries
requires understanding their URL schemes.
Some other systems, like the PLT Scheme Web Server [20] and
Links [11], avoid the problem by generating non-human-readable
URLs, standing for continuation references. We prefer to keep
URLs readable, since they serve as a common interface with the
broader Internet world. However, Links pioneered many of the
other design elements on display in Figure 1, including type-safe
combination of HTML and database code within a single language.
One further key difference is that Ur/Web works with direct embedding
of SQL code, whereas Links compiles to SQL from a subset
of itself, presented as a monadic query language [7].
The key distinguishing elements of Ur/Web’s design, in comparison
to past languages, become clearer when we turn to taking
better advantage of encapsulation. Before doing so, we pause to
discuss some relative strengths and weaknesses of the HTML and
SQL encodings in Ur/Web.
Ur/Web effectively encodes XML with algebraic datatypes,
which are not expressive enough to capture all of the constraints
associated with XML schemas. Regular expression types [19] are
an established approach to enforcing the rules of XML more literally,
and they have been integrated with ML-style languages in the
OCamlDuce project [16]. Programmers may benefit from that style
of more precise type-checking. On the other hand, more complex
static checking of XML may be more difficult for programmers