Friday, January 25, 2008
I have a new blog
Monday, January 14, 2008
Blogging and formatted code
Tuesday, November 20, 2007
Tangible Functional Programming: a modern marriage of usability and composability
Monday, July 09, 2007
"Tangible Functional Programming" -- icfp version
Sunday, July 01, 2007
Implementing a type for partial values
(Edit 2008-01-14: updated formatting.)
In my previous post, I gave an interface for a type of "partial values" and invited implementations. Here's mine, which surprised me in its simplicity. The whole module is online.
The trick is to represent Partial a as a -> a, i.e., a way to selectively replace parts of a value. Typically the replaced parts are bottom/undefined. I want Partial a to be a monoid, and Data.Monoid provides an instance:
-- | The monoid of endomorphisms under composition. newtype Endo a = Endo { appEndo :: a -> a } instance Monoid (Endo a) where mempty = Endo id Endo f `mappend` Endo g = Endo (f . g)
So my definition is simply a synonym:
type Partial = Endo Note that mempty and mappend do exactly what I want. mempty adds no information at all, while u `mappend` v adds (overrides) information with u and then with v.
The implementation of functions on Partial is trivial.
-- | Convenience for partial-manipulating functions inPartial :: ((a->a) -> (a'->a')) -> (Partial a -> Partial a') inPartial f = Endo . f . appEndo valp :: c -> Partial c valp c = Endo (const c) pval :: Partial c -> c pval (Endo f) = f undefined unFst :: Partial a -> Partial (a,b) unFst = inPartial first unSnd :: Partial b -> Partial (a,b) unSnd = inPartial second unElt :: Functor f => Partial a -> Partial (f a) unElt = inPartial fmap
I'm not sure I'll end up using the Partial type in Eros, but I like having it around. If you think of variations, extensions and/or other uses, please let me know.
A type for partial values
(Edit 2008-01-14: updated formatting.)
In simplifying my Eros implementation, I came across a use for a type that represents partial information about values. I came up with a very simple implementation, though perhaps not quite ideal. In this post, I'll present the interface and invite ideas for implementation. In the next post, I'll give the implementation I use.
First the type:
type Partial a I require that Partial a be a monoid, for which mempty is the completely undefined value, and in u `mappend` v, v selectively replaces parts of u. (Lattice-wise, mempty is bottom, and mappend is not quite lub, as it lacks commutativity).
Now the programming interface:
-- | Treat a full value as a partial one. Fully overrides any -- "previous" (earlier argument to mappend) partial value. valp :: c -> Partial c -- | Force a partial value into a full one, filling in bottom for any -- missing parts. pval :: Partial c -> c -- | Inverse to fst, on partial values. Inject info into the -- the first half of a pair, and leave the second half alone. unFst :: Partial a -> Partial (a,b) -- | Inverse to snd. unSnd :: Partial b -> Partial (a,b) -- | Inverse to "element" access, on all elements. A way to -- inject some info about every element. For f, consider -- [], (->) a, Event, etc. unElt :: Functor f => Partial a -> Partial (f a)
That's it. I'd love to hear ideas for representing Partial a and implementing the functions above. In the next post, I'll give mine.
Saturday, June 02, 2007
Paper draft: "Applicative Data-Driven Computation"
Friday, March 30, 2007
Software releases: TypeCompose, Phooey, GuiTV
- Uses new TypeCompose package, which includes a simple implementation of data-driven computation.
- New Applicative functor interface.
- Eliminated the catch-all Phooey.hs module. Now import any one of Graphics.UI.Phooey.{Monad ,Applicative,Arrow}.
- Phooey.Monad has two different styles of output widgets, made by owidget and owidget'. The latter is used to implement Phooey.Applicative.
- Self- and mutually-recursive widgets now work again in Phooey.Monad. They wedge in Phooey.Arrow and Phooey.Applicative.
Tuesday, March 27, 2007
ICFP '07 paper draft -- comments please
We present a user-friendly approach to unifying program creation and execution, based on a notion of “tangible values” (TVs), which are visible and interactive GUI manifestations of pure values. Programming happens by gestural composition of TVs. Our goal is to give end-users the ability to create parameterized, composable content without imposing the usual abstract and linguistic working style of programmers. We hope that such a system will put the essence of programming into the hands of many more people, and in particular people with artistic/visual creative style.
In realizing this vision, we develop algebras for visual presentation and for “deep” function application, where function and argument may both be nested within a structure of tuples, functions, etc. Composition gestures are translated into chains of combinators that act simultaneously on statically typed values and their visualizations.
Here is a figure from the paper, showing one stage of an interactively composed interactive 2D region. The user selects compatibly-typed input and output widgets, typically in different TVs. The result is a new TV that merges the source TVs, except for the connected input and output, which vanish. The sliders control the disk and checker sizes and the checker's rotation angle.

Edit on March 28:I just added two relevant pointers to the
Monday, February 12, 2007
separating IO from logic -- example
Monday, January 22, 2007
Software releases
- Phooey is a functional GUI library that has much of Eros's GUI implementation techniques, but much more carefully structured than in the Eros paper.
- DeepArrow has the general notion of "deep application"
- TV has the algebra of composable interfaces, or visualizations of pure values, and it has tangible values, which are separable combinations of interface and value. It uses Phooey to generate GUIs very simply from interfaces
- Figure out how to support simple GUIs and Eros's gesturally composable GUIs, without code/library replication.
- Re-implement Eros on top of simpler pieces.
- Refactor Pajama into reusable libraries and release.
- Building and optimizing "expressions"
- Common sub-expression elimination
- Generation of Java code
- Perhaps other back-ends besides Java
- Pajama, on top of these pieces
Wednesday, September 13, 2006
New Pajama wiki
- Replacing the remaining old code from Pan (done while I was at Microsoft Research). Most of the code has been rewritten and simplified, including the complicated code motion stuff (common subexpression elimination and loop hoisting), code generation (nicely exploiting Java), and GUI construction.
- Getting it whipped into shape to be a open source project.
- Applying the (domain-independent) compiler to other domains (sound, 3D, ...).
- Improvements to the wiki, including easier uploading of examples and automatic generation of galleries.
- Integration of Pajama and Eros (end-user syntax-free authoring of functional prorams).
Monday, September 11, 2006
Non-syntactic, end-user, functional programming
Suppose users of interactive programs could also create such programs with a simple extension of their current style of interaction. First, such a development would enable many more people to create and share computational content. Second, it would allow this content to be created without imposing the abstract, linguistic mode of creativity. This freedom may give birth to new kinds of programs whose creation is nurtured by a concrete and visual environment.Comments please (related work, ideas, typos, unclear bits, etc)! Technorati tags: EndUserProgramming, TangibleValues, FunctionalProgramming
Thursday, April 13, 2006
P.S. to "Pajama site improved"
Tuesday, April 11, 2006
Pajama site improved
Friday, January 13, 2006
Unifying and generalizing spatial transformation
(Edit 2008-01-14: updated formatting.)
I’m trying out an idea I had a while back for unifying and generalizing different notions of spatial transformation in Pan (and spatial & temporal transformation in Fran. The three notions are transforming a point, an image (which is a function from point to alpha), and an image filter (which is a function from image to image). A basic “transform” is a function from points to points. To transform a point, just apply the function. To transform an image, inversely transform the points fed into the image. To transform a filter, inversely transform the source image and forward transform the result image.
type VectorE = (DoubleE,DoubleE)
type PointE = (DoubleE, DoubleE)
type Image c = PointE -> c
type HyperFilter c = Filter c -> Filter c
Then for instance, scaling has these three variants:
scaleP :: VectorE -> TransformE
scaleP (sx,sy) = \ (x,y) -> (sx * x, sy * y)
scale :: VectorE -> Filter c
scale (sx,sy) = (. scaleP (1/sx, 1/sy))
atScale :: VectorE -> HyperFilter c
atScale (sx,sy) xf =
scale (sx,sy) . xf . scale(1/sx,1/sy)
Hyperfilters allow some beautifully modular formulations of filters.
Note how in scale and atScale, I’m inverting the scaling. Exactly this pattern of inversion happens for other types of transformations as well (translation, rotation, swirl, etc). The new idea is to capture this inversion pattern once in a general rule for transforming functions. A type class specifies types that can be spatially transformed, which is direct for points, a do-nothing for numbers and booleans, distributes over tupling, and works similarly to atScale above for functions. To make this fly, I’m changing my representation of points and vectors from pairs to data types, which makes the code less succinct but is more strongly typed.
There’s a big catch in this plan: I only know how to handle invertible transformations, which rules out, e.g., tiling.
Here’s the class of transformable values:
class ITrans a where
iTrans :: ITransformE -> a -> a
and the handling of functions:
instance (ITrans a, ITrans b) => ITrans (a->b) where
iTrans xf f = iTrans xf . f . iTrans (invIT xf)
The type of invertible transforms simply has a pair of transforms:
data ITransformE =
ITransformE { itForward :: TransformE
, itBackward :: TransformE }
invIT :: ITransformE -> ITransformE
invIT (ITransformE forw back) = ITransformE back forw
Besides doing what I already do more uniformly, this generalized approach to transformation should be just the thing for Wednesday, January 11, 2006
Pajama!
- Easy to run examples. Anyone with Java 1.5 or better can simply visit a web page to see and interact with the examples.
- Examples run on all major platforms (wherever Java 1.5 runs), while Pan ran on Windows only.
- The Pajama compiler runs on all platforms supporting GHC and the java compiler. In contrast, the Pan compiler ran only under Windows and only with Microsoft's Visual C++ compiler. Worse yet, Pan used a GUI library (WTL) that Microsoft no longer supports. I haven't been able to run the Pan compiler for quite a while now.


