Designated input vs normal (output/computed) variables

Hey!

First off, I’m really happy this project has come to be. It has a lot of creative as well as didactic potential, which are two fields I feel are often neglected in the ‘programmer world’ (leaving a wide and unnecessary gap between programmers, creative coders, and teachers). I’m interested in seeing how the project evolves.

Not really being a creative coder myself, I for some reason started working on a small ‘UI’ problem in one of my notebooks, trying to figure out whether this might have some nice solution, with viewof etc… Soon enough, though, I figured out the gist of the uphill battle I was fighting: although viewof gives an interesting potential for user’s inputting data, it is somehow still an ‘added feature’, or small hack, on top of an inherently static data flow. You write a bunch of variables, the system figures out the dependency graph, and the data flows through. (Of course it’s a bit more funky, because we’re working with javascript and the DOM, so every variable has an optional ‘extra’ visual output (dom nodes), and we can do all kinds of javascript trickey if need be.)

This is good and wonderful of course, but somehow I have the feeling that many people will try to do some kind of small UI thing, here or there, be it supporting their d3 creations, for some other thing, or just absent mindedly. And although I don’t think Observable should set it’s aim at actually working UI logic out at all, it seemed to me that there’s something we’re missing here, that might explain why I thought doing some UI thing might be fun/possible in the first place, but couldn’t.

Then it hit me: the inherent circularity in UI’s is solved through conceptually distinguishing the two flows of data. Data is what goes in, and events come back out. But this is not workable in Observable at all, because there’s a whole DOM ecosystem within a notebook already, and this would radically complicate things. But there’s another, similar yet orthogonal, conceptual distinction that is made in UI frameworks, specifically those that pieces things together with dependency graphs (I’m thinking Knockout, Vue.js, and others MVVM etc): the initial nodes, and the computed nodes. In Knockout, this is ko.observable vs. ko.computed, and in Vue.js, it’s the data and computed properties. The former are meant to be able to be changed, at any time, anyhow; the latter just compute. This distinction is notably missing from Observable, although the reactive layer is essentially the same (at least to Knockout).

Now I know that one of the main features of Observable is exactly its lack of any crazy app- or domain-specific features/syntax/etc. “It’s just regular javascript and DOM,” and then a simple layer of reactive programming, and then some stuff like viewof, and then a small standard library. But I think this one syntax addition might be worth thinking over: designating certain variables as ‘inputs’, i.e. actually stating that they are solely there to be written to by other pieces of code. One might write them with a question mark, marking their unknownness at time of writing, as such: ? x = 6 where a default value is provided as well. Input variables are distinguished from normal variables in that (1) it is not allowed to let their default value depend on any other variable, and (2) they can be written to, whereas normal variables obviously can not.

It’s late where I’m from, so maybe this is just late night gibberish, but I’d love to hear your thoughts if it’s anything more than that :slight_smile:

Keep up the good work!

2 Likes

Fantastic question. I was going to propose an interim solution, but you beat me to it! I only have a minor suggestion, which is to use viewof to reference the mutable container. Here’s my take:

https://beta.observablehq.com/@mbostock/mutable-values

Thanks :slight_smile:

Interesting, I didn’t know you were able to write viewof x as were it an expression in javascript. It does allow for nicer mutable values, indeed. However, I just can’t get my head around the conceptual ramifications of it (and notably the principle of disallowing co-occurence of x and viewof x for the sake of removing circularity) — it just seems a bit patch-worky, but I haven’t been able to decide why (or if).

Here’s me doodling around with the concept, trying to figure out edge-cases: https://beta.observablehq.com/@kelleyvanevert/mutable-values.