Currying isn't just a mathematical innovation; it's also a user
interface technique.

My Angle on Current UI Techniques
---------------------------------

"Forms" --- text widgets, checkboxes, radio buttons, sliders, buttons,
that sort of nonsense --- allow a person to create data in a computer
program, and to instruct it to take actions on their behalf.  They
don't really help much for direct manipulation, though, where the data
is already inside the computer --- perhaps as some kind of smart
object inside a computer program --- and the person wants to
manipulate it somehow.

That's because generally such manipulation involves simultaneous
selection of at least two objects: an object to act on, and an action
to take on it.

The primary computer UI techniques for that so far follow, in order of
increasing directness:
- indirect manipulation: the person's subjective experience is that
  they instruct a computer program what to do with the data.  For
  example, they might write a program in a language with instructions
  to manipulate various objects.
- verb modes: the person selects a "tool" that interprets their later
  clicks.  For example, in a drawing program, the person might click
  an "erase" icon, causing their subsequent mouse clicks and drags to
  erase things from their drawing.
- noun modes: the UI is focused on one primary object, and there are
  secondary objects sitting around that the person can, say, click on.
  When clicked on, they perform some action on the main object.  For
  example, you might select some text (the primary focus) and then
  click on a "cut" menu option (the secondary object); or in
  Hypercard, when you create a link, it adds a floating button to your
  screen (the secondary object), and when you have navigated to a card
  (the primary focus), clicking the button directs the link to that
  card.
- drag-and-drop: the person drags one object (generally the noun) onto
  the other (generally the verb).

In any of these techniques, the set of nouns may be either open or
closed, as may the set of verbs.

Currying With Current UI Techniques
-----------------------------------

Currying extends any of these techniques, including drag-and-drop, to
arbitrary numbers of objects.  Hypercard's "link to this page" button
is an example: there's a "make link" menu item (marred by a modal
dialog box, but no matter) which creates a new verb in the UI, and
that verb is a curried procedure: "make link from <some particular
place> to currently viewed card."

Robb Beal's experimental Mac OS X "Spring" user interface for the Web
used drag-and-drop for a variety of communication actions.  But to
select which action to take, Spring would pop up a menu after a drag
was completed, for selection of the action, because all of the objects
displayed in Spring canvases were nouns, not verbs.

Drag-and-Drop and REST
----------------------

Drag-and-drop maps well onto REST.  A drag-and-drop UI contains only
three user actions: display an object, invoke an object with no
arguments (by clicking or double-clicking on it), or invoke an object
with one argument (by dragging another object onto it).

This is particularly important because the existing REST UIs (i.e. web
browsers) are utterly impoverished in their ability to submit one
resource, or an entity obtained from some resource, to some other
user-selected resource; and they are utterly incompetent at managing
user-created data.

A REST-Backed Drag-and-Drop UI
------------------------------

I propose a spatial REST UI, which would interoperate with the
existing WWW as a sort of awkward browser, but would allow new kinds
of web-based applications to be built.

The objects arranged on the user's canvas are either resources
(identified by URL) or entities.  Resources are displayed with an
entity obtained by dereferencing them (e.g. HTTP GET) or, failing
that, just as a URL and perhaps some link text.  The user can easily
collapse the display down to just the title and favicon.

An HTML entity usually has links to other resources within it;
clicking on these links, or dragging them onto the canvas, will add
those resources to the canvas.

The data in an HTML form is a separate entity from the HTML itself.
Typing into the form creates a clone of that entity, which is
positioned on top of the original HTML page; the form can be submitted
to its ACTION URL in the usual way, or to some other URL by dragging
it onto that other URL, resulting in an HTTP POST (or GET) to that
other URL.

Dragging one resource onto another performs an HTTP POST to the URL of
the second resource of a form with one field: "dropped_url", with the
value of the first resource's URL.  (Perhaps it should also include a
representation, particularly for private resources?)

It's generally desirable for a drop-target to provide visual feedback
about whether it's a suitable target for a particular dragged object;
this reduces user errors.  Traditionally this is done with type
information, but that doesn't work that well in the world of the web;
most web pages have the same MIME type, and if someone else doesn't
like the MIME type you got, they may be able to content-negotiate for
a different representation of the same resource.

The web equivalent of WSDL or IDL is the HTML form; it specifies the
set of inputs required for a "remote call" in a machine-readable form,
including possible values for those selected from a finite set; it
normally includes human-readable documentation about those same
arguments; and it may even include machine validation rules.  So it
seems that the most harmonious place to put this drop-target feedback
is in an HTML form.

At the least, you could grey out resources whose GET representation
doesn't have a form with a variable named "dropped_url".  Perhaps
JavaScript in the form could be given a representation for the
resource and decide whether it was interested.

An Example Application
----------------------

I'm looking at a web page about Tim Burton's film, "Corpse Bride".  I
decide that I want to bookmark it, so I drag the web page onto the URL
for my bookmarking service.  This form POST creates a new resource (my
bookmark) and redirects me to it with a 303 See Other response, which
appears on my canvas next to the bookmarking service.  I add some
annotation ("raw images from digital cameras with dcRAW") by typing
into a form; as I begin typing, a border appears around the form,
because it's just been copied into a new window positioned on top of
the previous one.

At this point, my computer crashes, and I reboot.  When I restart my
REST canvas, it looks the same as before the crash, including the
un-submitted form data.

I'm not sure about the spelling, so I drag the form data over to a
spell-checking resource.  A marching-ants arrow appears from the form
data to the spell-checking resource and my annotation data is
submitted to it as a form POST; after checking the spelling of all the
form fields in its request, the spell-checking resource responds with
a very short HTML document: "Spelling OK.", which appears next to the
spell-checking resource.  The arrow disappears, but the form data
remains visible.

I finish typing the annotation and hit "Enter".  The form now submits:
an arrow appears from it to the titlebar of the web page and does the
marching-ants thing for a second or two.  The web server sends another
303 See Other, to the same URL, which causes the canvas to refresh its
view of the resource, reflecting my changes; and the form data window
that's obscuring it animates over to the trashcan and disappears
within.

Had I submitted it by dragging it onto its original resource, it would
not have disappeared from the screen.

Now I want to tag my bookmark with the tags "video", "media", and
"free-software".  I pop open a part of the canvas containing
commonly-used tags; I drag the "free-software" tag onto my bookmark.
This results in an HTTP POST to the bookmark resource, which fetches
the "free-software" tag's URL, recognizes it as a tag to be applied,
and responds by modifying the bookmark and sending another 303 to the
bookmark, which again refreshes my display.

Now, I always apply the "media" tag to anything I tag as "video".  I
have separate "media" and "video" tags, so I decide to automate the
combination.  I have a collection of "foreach" resources on my canvas.
I pop open the "foreach noun" resource and read the description and
conclude that it's the right one.  I click the button in its
description, and it does an HTTP POST to create a new "foreach noun"
collection, which (after a 303) appears next to it on my canvas.  I
drag it over to my "tags" area and pop it open; its description has a
link to the generic "foreach noun" resource, and links to a subsidiary
resource, "add to collection".  I drag "add to collection" onto the
canvas, and then drag "media" and "video" onto "add to collection".
Each drag results in a 303 back to the collection, which refreshes and
shows me its contents.  I edit its description with an inline form:
"media+video".

Now I click the "Collapse" button on the collection's representation
to collapse it back to just its favicon and title, "media+video".  Now
I can apply this "foreach noun" collection to any verb by dragging the
verb onto it.

So I drag my bookmark onto "media+video".  This results in an HTTP
POST to "media+video" with the URL of my bookmark.  (I'm assuming this
URL is secret, so knowing the URL is sufficient proof of authority to
edit.)  Now the "foreach noun" server does two HTTP POSTs to the
bookmark, one with the URL of the "media" tag and one with the URL of
the "video" tag.  Since the two HTTP responses are identical, it
returns one of them to my canvas, which responds by refreshing the
bookmark, which now has two more tags.  (I'm not sure what it should
do with different responses.)

(It's a little awkward that the drag direction here is backwards from
the normal tag dragging direction.  This is an inherent problem with
this UI, I think.)

I want to email my annotations to the author of the article.  I drag
their mailto: link out of the article onto the canvas; I click on my
bookmark's edit form to extract the form data as a separate entity.  I
drag this entity onto the mailto: link, and it creates a new "email
message" entity on my desktop next to the mailto: link, containing all
the form data.  I drag the form data itself to the trashcan to make it
disappear (so it stops obscuring the bookmark page), edit the mail
message, and hit the "send" button to send it.

Other Directions, Briefly
-------------------------

Other generic services that make sense with this UI, other than "spell
check", "bookmark", and "foreach noun":
- foreach verb
- Wayback Machine
- Alexa page rank for domain
- Google backlinks for URL
- Technorati search for URL
- automated translators
- add popup links to Chinese character translations
- pipeline: contains a sequence of verbs; feeds the output of one to
  the input of the next.  (Probably has options for some minimal
  translation, such as extracting form data or encapsulation in a form
  field, since most existing web services don't know what to do with
  an HTTP POST with content-type text/html.)
- verb chain of responsibility: try dropped URL on each verb until one
  returns success
- noun chain of responsibility: try dropped verb with each noun until
  it returns success for one of them
- form field renaming
- makeashorterlink-type services
- simple concatenation of page contents

Other URL schemes other than HTTP:
- aim
- mailto
- file

Other directions:
- support asynchronous invalidation, so web pages can be "live"
  - or at least let you manually configure polling, as Opera has for
    years
- support non-spatial layouts, such as nested hboxes and vboxes
- perhaps "titlebars" should be "tabs" that are placed on any of the
  four sides of a representation so as to be visible

Credits
-------

Inspired by Naked Objects.  Inspired by Spring.  Inspired by
Hypercard.  Bookmarking scenario from del.icio.us.  End users wiring
together web services inspired by Marty Tenenbaum.

Reply via email to