Zenzoa

Hybrid Design

Programming for Non-Programmers

I’ve been voraciously reading about how programming (or, creating an interactive system) can be more accessible. Here’s a summary of what I’ve discovered so far:

Tools

Eve

Eve

An project that aims at “finding a better way for us to interact with computers” by creating a programming environment based around transforming data.



Elm

Elm

A functional reactive programming language for front-end web development.



Twine

Twine

A tool for creating interactive fiction thats lays out individual pages as boxes that you can move around, and draws lines between pages that link to each other.



Hypercard

Hypercard

An early Apple product that allowed non-programmers to create simple stack-based programs using a drag-and-drop WYSIWYG editor and a natural-language-like scripting language.



Education

Logo

Logo

An educational language that allows children to control a ‘Turtle’ that draws geometric shapes on the screen or a sheet of paper.



Scratch

Hopscotch and Scratch

Visual programming languages that transform code into interlocking blocks.



Papers

BCM

Applying Psychological Principles to Support Novice Conceptual Modelers

The authors of this thesis used psychology to create a better modeling tool called BCM and tested it against traditional UML and ERD methods.



Language and Structure in Non-Programmers' Solutions to Programming Problems

Studying the Language and Structure in Non-Programmers’ Solutions to Programming Problems

A study looking at how kids use natural language to describe the behavior of computer programs (in this case, PacMan).



Out of the Tarpit

Out of the Tarpit

An examination of complexity in complex programming projects and how to mitigate it.



Functional Relational Programming

Out of the Tarpit is about dealing with complexity in programming systems. The authors make a distinction between:

There’s not a whole lot you can do about essential complexity, so the goal is to limit (and separate out) accidental complexity.

Accidental complexity in programming tends to arise from:

If that sounds like they’re beating up on your typical object-oriented style programming… that’s because they are. They instead look to functional and logic programming for inspiration. Of course, those languages need to break their own rules for pragmatics’ sake, allowing side-effects and flow control structures to deal with interactivity and performance.

I’d go further and suggest that people tend to think with nouns more than they think with verbs (or, at least English speakers do). Creating a robust programming language does not necessarily lead to one that’s easy to learn or to use. And if you can’t easily reason about a tool, it won’t be used effectively – if it’s used at all.

The proposed solution, then, starts with a relational database as the core data structure. Instead of classes, you have relations. A relation* is a set of records with certain attributes**. Or put another way, a relation is a table with a set of typed, named columns (the attributes) and any number of un-ordered, non-repeating rows (the records).

A relation is a collection of records with a set of attributes

Your essential state is simply your user input. It might come from some other source, like an API or something, but it contains only the information relevant to the problem. Any other information or state needed for implementing the solution – accidental state – gets derived from these base relations.

Derived relations depend only on base relations. They don’t get modified directly. You can use a combination of relational algebra (joining, intersecting, projecting, selecting, and other fun nonsense***) and pure functions to create them.

Finally you get to input and output.

This is where it starts to look like functional reactive programming. There are well-defined ways in which the system can affect or be affected by the outside world. What’s more, there’s only one place you can change state – the base relations – and everything else grows out from there. Given the same data, you get the same derived relations and views and behavior every time.

Function relational programming model

There are couple of other parts to this model as well:

There’s the fun addition of constraints, which are simply boolean expressions that must hold true at all times. Every time you try to modify state (changing records in the base relations), every constraint has to pass before anything can change. Basically these are built-in tests.

There are also performance hints, which let you do such things as define a mapping from a relation to its storage format, mark which derived relations should be cached, and define the order and eagerness of evaluation for derived relations.

Overall, this model is dubbed functional-relational programming. The other FRP. OFRP. And so far, the only example I’ve seen of someone trying to implement this is Eve.

You’re hopefully starting to notice some striking similarities between functional-relational programming and AppSheet. We pretty much already treat users’ spreadsheet data as a relational database, and everything in our app model has an analogue in the OFRP model:

AppSheet App Model

What the OFRP model suggests is that we can expand the power of our app model without compromising its simplicity. For example:

Now, OFRP is not necessarily designed for learnability or ease of use. But in addressing the complexity that makes real-world systems hard to understand and maintain, it suggests that our apps can deal with arbitrarily complex problems without introducing a mess of problems of their own.

Our app model was built with a strongly declarative paradigm, and this has paid off! We’ve converged onto a solution for dealing with program complexity, and even though our apps tackle a small subset of all possible programs, I think we can take a lot of inspiration from functional-relational programming as we look for ways to tighten-up and expand our app model.


* Okay, I’m conflating relations and relvars for the sake of simplicity. “Relvar” is short for “relation variable,” which refers to the structure rather than the contents. In other words, the schema.

** Attributes are typed. They can be any primitive type (string, int, float, date, enum…) but nothing with subsidiary components (tuples, arrays, dictionaries…).

*** Relational algebra is cool and powerful, and there’s a bunch of information out there on making these transformations performative (though it’s sometimes tricky for large data sets).

Relational algebra overview