Experiments in Code Typography

I'm writing an essay documenting the typographic design decisions I made when building YinYang. I'm basically at the point of having a decent first draft; please take a look!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Cautiously optimistic!

I'm broadly most reminded of Mathematica notebooks, although your system avoids many/all(?) of the need for escape sequences to type things not found on a keyboard. (â‹®deltaâ‹® for \[Delta], for example) You just end up with a little cruft (the dots) to denote how difficult it's going to be to delete a multi-component symbol. It's perhaps a better balance between a straight-up text editor and projectional/structural editor than Word, MPS, or Simonyi's Intentional stuff.

What decides the method name postfixes? The language, environment, or programmer? The technique of selecting a few consonants reminds me of the way I shorten identifiers by taking the first letter of each hump in a camelCase sequence: querySelectorAll becomes qSA.

I assume the four inward-pointing arrows are for code folding. Looks a bit bulky, although that view comes from someone who doesn't ever use the feature.

Is it possible to have an incomplete string literal? If so, what does it look like? If not, what happens when you backspace over a string?

You mentioned elastic tabs; what about spaces? Are they rendered differently in string literals?

Does metatext from probes hover over lines of source code below? Or does it push the other lines down? (Or does it just intentionally break when you abuse the feature, like you do for nested parentheses?)

Can an end-user add their own multiple-symbol combinations (like +++)? How does a beginner learn how to type?

If I click on a parentheses group, does the caret plop down where I click, or is the parenthetical expression selected/focused?

Sorry for all of the questions, I'm just curious and since you're introducing some new interface behavior, I'm having to guess at how some aspects of it function since I can't play around with it myself.

your system avoids

your system avoids many/all(?) of the need for escape sequences to type things not found on a keyboard. (â‹®deltaâ‹® for \[Delta], for example)

Some Greek is supported, but it is completely not intuitive: any identifier written as "D_" is rendered as "Δ∙".

What decides the method name postfixes? The language, environment, or programmer?

The programmer, though I guess it could be defined semi-automatically in the case of a trait member (by setting a trait-wide postfix).

I assume the four inward-pointing arrows are for code folding. Looks a bit bulky, although that view comes from someone who doesn't ever use the feature.

Correct, it is something I added recently and haven't really refined yet. I just needed something to indicate code folding state (they point outward when code is folded).

Is it possible to have an incomplete string literal? If so, what does it look like?

Yes, it renders with a double quote. The lexer is smart about about determining double quote bounds, and auto-completion is performed by default (and if you type the ending double quote yourself, it will just move the cursor forward).

You mentioned elastic tabs; what about spaces? Are they rendered differently in string literals?

I think so. Space outside of a token is rendered with a fixed size (the width of 'X' I think). Inside the string literal, its whatever of the native text rendering component specifies.

Does metatext from probes hover over lines of source code below? Or does it push the other lines down?

If a meta-text line is present, it pushes the lines under it down.

Can an end-user add their own multiple-symbol combinations (like +++)? How does a beginner learn how to type?

Rendering is fixed in the text editor, so no, though I see why not as long as the rules are followed (rendered tokens must have the same character count as the inputted ascii ones). As far as discoverability, some of the symbols are obvious according to a simple rules, many are not; anyways, code completion should help out a lot (letting you know what the rendered and inputted token is).

If I click on a parentheses group, does the caret plop down where I click, or is the parenthetical expression selected/focused?

The former. Actually, my editor doesn't support multi-character select yet at all.

Some comments

Here are some opinions on this:

Your core typography (as shown in the first example) has way too much complexity. The layout has to be clean while looking at it; as was mentioned in the other thread, typography should make it easy to see what's important, and easy to ignore what is unimportant, and these change depending on context.

I'd drop the arrows-point-to-a-center marker things as too much marking for something that's fairly unimportant.

I like the indent blocks; they make things easier to read. It might be useful to also change color as you nest here.

The parenthesis formatting is too heavy. They pull a *lot* of attention, and when used for function calls, they look disconnected from the function. While the concept is neat, I don't think it works well in practice. It is possible that something similar to Lisp syntax would work here: Render a function call foo(bar, baz) something like ( foo | bar : baz ), that would at least make the rendering communicate the grouping better.

I think rendering highly nested parentheses as black is a problem. When you are writing code yourself, you can always fix it, but if you're working with generated code or somebody else has written the code, you can't.

The dots for "keeping the same number of characters" seems off to me. You change to a different editing mode when editing expressions with parentheses; I you could do that when editing anything that is presently rendered with a dot as well. The dots are distracting during regular reading of code, pulling attention to syntactic details.

I strongly dislike the italics for single character variable names when multi-character variables are rendered differently. Single character variable names are the same as other variables. They should be rendered the same.

You've created a new magic way of showing quoted text (which when in a parenthesis looks like a 3D popout thing). Go with some form of regular quotes, possibly double angle quotes like «foo». These are both more commonly used, easier on the eyes (because they are inline), and won't create the odd popout effect.

I'm also somewhat skeptical of the choice of requiring all public names globally to be unique; I think this is going to be a pain to program with (though it does make searching easier.)

Overall, I think this is an interesting experiment; it just requires some tweaking.

Thanks for sharing!

I'd drop the

I'd drop the arrows-point-to-a-center marker things as too much marking for something that's fairly unimportant.

Code folding isn't unimportant, but I guess some different rendering of colon is preferable since they correspond.

It is possible that something similar to Lisp syntax would work here: Render a function call foo(bar, baz) something like ( foo | bar : baz ), that would at least make the rendering communicate the grouping better.

This is a good idea, though right now I'm using only lexical information to render (vs. parsing info). I'm not really sure what it would look like yet, I don't have a lot of contrast to work with.

I think rendering highly nested parentheses as black is a problem.

The opacity of the background increases by about 5% per-level, so you'd have to have 19 or so deep nesting before it becomes black, say about 10 levels before it becomes a big problem. Typical nestings outside of Lisp are only around 2 or 3 levels deep, so it should be fine.

If you nest too deeply, think of it as a code smell that manifests visually.

The dots are distracting during regular reading of code, pulling attention to syntactic details.

They are already rendered lightly when the line is not selected. I guess I could just make them transparent unless the line is selected, in which case they need to be seen for the purpose of editing an identifier.

I strongly dislike the italics for single character variable names when multi-character variables are rendered differently. Single character variable names are the same as other variables. They should be rendered the same.

In typography, letters are rendered with respect to how they are used. So, for example, the "i" in "ie" will be rendered differently from the "i" in "in." "i", "j", "x", "y", "z" as stand alone identifiers mean something else...they are not really just letters, they are standalone variables.

My first choice was to use some math-style rendering for them, but this totally crashed ("calibri math" has some issues with these characters!). Perhaps italics isn't the right answer, but I really want them to stand out compared to the less math-oriented multi-character identifiers.

You've created a new magic way of showing quoted text (which when in a parenthesis looks like a 3D popout thing). Go with some form of regular quotes, possibly double angle quotes like «foo». These are both more commonly used, easier on the eyes (because they are inline), and won't create the odd popout effect.

I actually tried double angles, they were very ugly. I'm not quite sure what to do with strings yet, I'm not really happy about string concat-style and probably need to add interpolation anyways.

I'm also somewhat skeptical of the choice of requiring all public names globally to be unique; I think this is going to be a pain to program with (though it does make searching easier.)

That is an example of a language design experiment that I'm trying to make workable with interaction (code completion) and visual (typography) design. The rendering, at least, should work out better on high resolution displays.

Details of rendering

Code folding isn't unimportant, but I guess some different rendering of colon is preferable since they correspond.

But weren't the lots-of-pointers just for "this can be code folded"? This is not important when I am reading code. Code *being* folded is important, but the ability to fold code is a an uninteresting concern most of the time.

One way of dealing with this would be to render the code-can-be-folded icon as transparent most of the time, with a radius around the pointer where you make it less transparent, and only when the mouse is moving. This allows the user to hit it to fold, but removes the clutter when that is not what they're looking for (except just as they're moving the mouse over that area.)

This is a good idea, though right now I'm using only lexical information to render (vs. parsing info). I'm not really sure what it would look like yet, I don't have a lot of contrast to work with.

What I tried to suggest was that you just pull the function name into the "parenthesis", and add a solid bar after it to distinguish it from arguments. As in this kind of drawing (foo | bar : baz) where | is supposed to be a solid line and : is supposed to be a dotted line.

Perhaps italics isn't the right answer, but I really want them to stand out compared to the less math-oriented multi-character identifiers.

We have a fundamental disconnect in how we mentally process this, then: I think of variables as variables; there's no "math oriented" or "not math oriented" variables. Short variables are something that's used mostly for iterators when there is no built in iteration support, or by sloppy programmers. But there is no fundamental difference for me between "i" and "ab" and "pdl", and rendering them distinctly is just a distraction.

I'm also somewhat skeptical of the choice of requiring all public names globally to be unique; I think this is going to be a pain to program with (though it does make searching easier.)

That is an example of a language design experiment that I'm trying to make workable with interaction (code completion) and visual (typography) design. The rendering, at least, should work out better on high resolution displays.

I've previously programmed where I've used globally unique names; my experience is that for somewhat large programs, you either end up with very long identifiers (because you prefix namespaces), or you end up with it being non-intuitive what cases you've ended up using a different name (because the first name was taken by somebody else.)

One way to do this that I think might work: Standardize on a particular prefix for each trait - the trait name. Have the calls recorded with that prefix, but hide it when displaying the code in the editor - possibly displaying the prefix for anything that has a conflict in the entire project.

You'll still need good refactoring support to help splitting trait, as your names are going to have to change. It's still the best variant I can think of.

What I tried to suggest was

What I tried to suggest was that you just pull the function name into the "parenthesis", and add a solid bar after it to distinguish it from arguments. As in this kind of drawing (foo | bar : baz) where | is supposed to be a solid line and : is supposed to be a dotted line.

I'm trying to pull it in a bit, but it doesn't really match what the developer writes. To pull it in for reals, we need to play with the actual syntax of the language :)

We have a fundamental disconnect in how we mentally process this, then: I think of variables as variables; there's no "math oriented" or "not math oriented" variables. Short variables are something that's used mostly for iterators when there is no built in iteration support, or by sloppy programmers. But there is no fundamental difference for me between "i" and "ab" and "pdl", and rendering them distinctly is just a distraction.

Typographically there is a huge different between "i", "in", "ni", "ie", etc... When using a proportional font, you render identifiers, not individual letters. I'm just proposing that we have more appropriate renderings of single character identifiers, which can be dealt with in font design (anyone want to design a proportional math/coding font?).

I've previously programmed where I've used globally unique names; my experience is that for somewhat large programs, you either end up with very long identifiers (because you prefix namespaces), or you end up with it being non-intuitive what cases you've ended up using a different name (because the first name was taken by somebody else.)

This is something work on. Since traits can be inherited multiply and argument types aren't constrained, perhaps we should have every trait that defines a foo/1 method extend an implicit trait that introduces foo/1.

I'm trying to pull it in a

I'm trying to pull it in a bit, but it doesn't really match what the developer writes. To pull it in for reals, we need to play with the actual syntax of the language :)

I think the function call rendering your present variant (update v3) looks quite good; I hadn't seen that when posting my above comment.

Typographically there is a huge different between "i", "in", "ni", "ie", etc... When using a proportional font, you render identifiers, not individual letters. I'm just proposing that we have more appropriate renderings of single character identifiers, which can be dealt with in font design (anyone want to design a proportional math/coding font?).

One thing that *might* work is to have a gradually changing slant as you get from short to long identifiers, since the visual of slant gets more distinct as you get longer identifiers. A varying slant may possibly end up rendering as "feeling like an identifier" without being visually distracting. However, I don't know how easy this would be font-wise - fonts are generally designed at a particular slant, and I don't know how well it would work to re-slant. It might work OK if you only do it a little bit.

This is something work on. Since traits can be inherited multiply and argument types aren't constrained, perhaps we should have every trait that defines a foo/1 method extend an implicit trait that introduces foo/1.

This may work; I feel I don't get an exact feel for what implications that will have because I don't really know the rest of your language.

Back to typography: I find the last version to have a little low indent, which makes the nesting hard to read for me. This might change with getting used to the "nesting bands" on the side - right now, I find myself just ignoring those as I'm used to using indent as my cue.

If you look at Cambrian

If you look at Cambrian Math, you'll find that there are stylized character renderings for all single characters that are not meant to kerned with other characters. Unfortunately, these characters don't work well in my implementation.

I'm a fan of low indent and visual queues. I really hate the 4 space indent that causes horizontal scrolling when viewing two buffers side by side. I'll up it and see what happens.

Feedback

I agree with Eivind that you need to get rid of much of the clutter. For example, the dots everywhere to remind you that there's an extra symbol there to back over... I'd just get rid of them. What I do is have a binding step that takes place at certain times after which all symbols are atomic and deleted with a single backspace.

I'd also get rid of the four arrow contradiction symbols everywhere. What are those for? (Collapse group maybe?) One thing to consider is having mouse selected UI items hidden until the mouse gets close enough.

I do something similar with underscore and subscripts, but it sounds like you're making that part of the identifier. In my system the part after the underscore is a tag to help you uniquely identify which symbol you mean. Tags are optional if removing them doesn't create ambiguity.

What I do is have a binding

What I do is have a binding step that takes place at certain times after which all symbols are atomic and deleted with a single backspace.

We tried this in the Scala IDE, developers seemed to hate it.

One thing to consider is having mouse selected UI items hidden until the mouse gets close enough.

Good idea! We already hide things/render things different if the line is selected or not.

Tags are optional if removing them doesn't create ambiguity.

It is up to programmer to include them or not in my system. My language has absolutely no support for ambiguity, as this creates problems for search; instead, its intended to heavily rely on code completion (when I implement that, I'll talk about it more).

cursor proximity

I agree that it would be worthwhile to experiment with mouse cursor proximity to reveal hidden elements. Similarly, what if you only show the digraph marker dots when the keyboard cursor gets close to them? Either right next to them, or within a "word" or so. I think that could be tuned to accomplish the goal of hinting the correct number of backspaces to press without the continuous visual clutter.

That is also possible, but I

That is also possible, but I don't want the editor flickering so much.

animated transparency

rather than eliminate the dot and have it "pop" in, leave it there for the purposes of layout and give it opacity of zero. Then animate the opacity towards 100% with some power curve relative to distance. Mouse distance can clearly be measured in pixels, but keyboard distance could be measured in characters, words, tokens, etc.

That's definitely possible!

That's definitely possible! I'll see what happens.

We tried this in the Scala

We tried this in the Scala IDE, developers seemed to hate it.

Yeah, there are two annoying aspects: having to wait for feedback and then having things change later when your focus has moved on. I can see this being a complaint. Maybe I should revisit this and do something closer to what you've done. This issue is intertwined with several other issues where it seemed desirable to leave things ambiguous. For example, to solve this, I'll need to go back to dot being a special form rather than just a simple operator, as the narrowed context from OO style method look-up is a big win, I think. Also, syntax ambiguity (multiple '+' definitions, for example) would have to be reined in.

I do think it's desirable to separate the tag from the symbol name. You can't really expect symbols to be globally unique. There will be times when modules are imported from different authors with different names. I guess by global you mean module level scope, and you require such conflicts to be resolved at import time. That sounds like it might be fine.

globally unique names

Even today we have globally unique module and package names. We simply use the import section to provide local shorthand... but that has costs in the form of import section boiler-plate, a less useful global search, and an extra barrier for reorganizing code.

If we instead used full, unqualified names for things, that would be noisy and painful to type in a conventional text editor. But I think it could work out with an editor that can hide or minify parts of the name. Especially if we also assume fuzzy auto-completion. Sean's editor already exhibits some of these properties.

My AO language conflates modules and functions, i.e. functions are the unit of modularity. I just call them 'words' in the Forth tradition, and the set of all defined words is a dictionary.

I'm interested in developing a wiki-like programming experience, where there is one or a few de-facto standard global wikis with perhaps 100k-1M useful functions already defined for almost every problem you can imagine (and more every day). Functions also serve as automatic tests, documentation, type declarations, optimization and rewrite rules, reflective applications and services, etc. via a set of naming conventions (similar to how every page in a wiki may have a related 'Talk:' page).

A private enterprise might 'fork' a wiki from the global standard (e.g. DVCS style) then extend it locally, and some may cherry-pick the less sensitive utilities and push them back to the community. Name conflicts, in either direction, may be resolved through global name refactoring or remapping, which can be remembered for future updates.

I have a hypothesis, that a wiki-like programming environment will offer much greater opportunity for refactoring of patterns that tend to arise only once per application or service. Also, I think it will provide a very nice resource for understanding programming at a more global and social scale.

The conventional approach of 'imports' seems as though it was designed for editing code primarily as plain text. With newer technologies and ideas, we can at least reconsider some of our older approaches. And I believe we can create a better programming experience.

names are too valuable to waste on compilers

as Jonathan says...

This is mostly what I'm thinking. Now its time to do.

It isn't clear to me what

It isn't clear to me what that means. I want names to be simple for both humans and machines to work with, to the extent we use them at all. But that's more about valuing simplicity than valuing names.

We don't really need to

We don't really need to worry about naming for compilers, GUIDs are food enough. Names are useful to us, and our interactive tooling that bridges between us and the compiler can resolve human rich names into compiler usable GUIDs.

Actually, the way I

Actually, the way I implemented it in the Scala IDE, -> would automatically go to arrow, but each strategy has trade offs.

+/2 is not ambiguous and can be overridden rather than overloaded. We get away with this since (a) YinYang is dynamically typed and (b) it is easy for all the primitives to extend the trait with the addition operator. On the other hand, without overloading, we had to find another operator for string concat (since the trait with '+' in it also has '-' !). Actually, I think this is better than the current free for all where operators can be overloaded willy nilly.

The globally unique name thing is something I'm trying out. The idea is to get all developers into the same namespace and rely more on search rather than namespace ghettos to keep things sane. This also means getting rid of modules...everything just exists, and you can use it as long as you can name it :)

Better method call, dot renderings

A link to a new screenshot trying to better with method calls and placeholder dots (essay is not updated).

Much better!

That looks much better. The previous looked (to me) like a step back from plain text; this looks a clear step forward.

Check out the updated essay

Check out the updated essay for the current version. I had problems maintaining (method | arg | arg) with real paren relationships, so I had to tone it down a bit.

whine bitch moan

thanks for taking on such a sisyphean task.

personally, i do not like the whole cartouche effect. i'd rather even just read s-exprs. :-}

Beyond s-exprs, what are

Beyond s-exprs, what are other method call formats to consider? Smalltalk selector style?

Bunch of nits on the new screenshot

- A lot of the punctuation needs more horizontal spacing to let things "breathe." Specifically, the colon needs some leading white space (look at the "object c:" line), and the dot operator needs a bit more space on both sides.
- It is really hard to tell "=" from "+=" and your triple-bar equals at a glance. I'm also really unsold on the use of small superscript for "+" in "+=."
- The visual difference between no parenthization and one level of parenthization is large and jarring. it makes it look like parenthized expressions belong to a different syntactic category than unparenthized ones.
- The notation for method calls, tuples, and ordinary parenthized expressions are difficult to distinguish from one another, despite serving very different roles.
- The way that the method is put "inside" the paren group for a call, and only distinguished by color, makes nested calls visually confusing. In the "foo foo foo" line, a reader can't use background color to line up the "10", "+" or "20" with their corresponding level of nesting, because all the "foos" are tinted away from the background color. The same thing goes for open and close braces - it is impossible to visually match the pile of closing braces at the end of the "foo foo foo" line with the opening of the corresponding constructs.
- There are two different notions of "subscripting" in this language. If I have a car, and it will have a velocity, should that be "V_car" or "car.vel"? This isn't strictly an issue with the typography, and people have to make the same kinds of choices in any language, but in this case the typography makes the issue jump out at me ("rod.from_in") and makes it possible for programmers to get very confused if they think the typographic subscripting represents an operator (e.g., visually parse it as "(rod.from)_in").

- c is italicized so it

- c is italicized so it leans into the next character. This is a problem with italics. I've been using proportional fonts for a couple years now and have no problem with short dot spacing. In fact, fixed width dot spacing is very annoying.

- I thought ⁺=, ≡, and = are quite easy to tell apart. Font size matters, but they don't seem visually ambiguous to me. They all involve assignment.

- The idea is to help visual parsing better, not be consistent. Parens should be jarring.

- (0, 1) is just shorthand for Vec(0, 1); in fact, it is the comma operator that is doing the work.

- I've added depth in my next version, so it should be easier to parse now.

- If "vel" was a unique member of the trait Car, and you wanted to access it on an instance of Car named car, then you would have to type "car.vel_car" (assuming car is the postfix you wanted to use for all things Car-exclusive) because YinYang has a global namespace for public members and doesn't use type information to resolve symbol bindings. On the other hand, this is valid:

object car
car.vel_car = ...

Since vel_car is defined to be a member of trait Car, car is inferred to extend Car.

Updated essay...

...with visual design elements. Changes :

- now rendering single letter variables in a script font, which is much more drastic than italics.

- Side bars start out light and get darkers as the indent level increases

- little unicode dots used for character count reasons do not show unless the line is being edited.

- Paren renderings now look more like...parens with shading. I'm also doing something with the method names of top-level calls, but this is too annoying to do on a nested basis, so it might get dropped later.

- Spaces are now variable in width according to columns in a global grid that acts like pervasive tab stops.

Thanks for the input!

Update v3

Seriously listening to everyone's comments. Changes:

- Got rid of postfixes, no one liked them. I'll figure something else for namespace management (probably something implicit and hidden); in the mean time, multi-part identifiers are separated by _, which is rendered as a light gray dot to be more readable (Python isn't a camel case language anyways).

- Got rid of different font sizes in general so the look is cleaner.

- All temporary variables are defined with $ (rendered as §)

- Colon and Dot are given more space by using a fixed-width font.

- operators typeset in bold dark gray to set them apart from identifiers.

Definitely better

This is much better now. FWIW I did a bunch of informal testing with various typography things when I first came to the VS editor and anything that either varied height or font-face failed miserably. It ended up being far too distracting.

More recently we did a bunch of testing with visualizing nesting and found that the half boxes didn't work very well once you get a good amount of code on screen. Having thin, relatively unobtrusive lines to indicate scope was much less distracting. In this case,you're drawing a lot of attention to the more nested scopes by adding color, which I'm not sure is helpful. It might be worth trying to thin the lines some and don't play with the saturation too much. I could see it being valuable to indicate the current scope you're in with color, but having them be persistently bold and thick makes the code really hard to read.

Thanks. I'll try something

Thanks. I'll try something much more subtle in v4 for side bars (1 point lines, 50% black, on the left and bottom of the block).

static vs. interactive rendering?

seeing all the nesting stuff drives me crazy usually. too ugly etc. but sometimes it can be useful when studying code. xcode does it when i mouse over things. it drives me nuts actually. i wish i could have it on only when i want it on, or something. $0.02

Yeah

We found a similar trend among people. In most cases anything but the subtlest hint of scope was considered distracting and people would ask how to get rid of it.

One thing I discovered in the big user study I did for VS was that there are very distinct phases that people go through while programming and that the interactions for those phases should be pretty different. For example, people who swore they never touch the mouse would primarily drive with the mouse when they were in debugging "mode", but when they were writing code they moved effortlessly with the keyboard. The things you need/want in those phases varies and unfortunately we don't tend to account for that in our tools.

User studies considered harmful

However, user studies don't tell the whole story.

For example, some user studies say users are annoyed by continuous feedback, e.g. a red underline on an incomplete identifier b/c it is not found yet. Some programmers add timers, or delay feedback to when the user isn't typing anymore, rather than make continuous feedback more palatable. But this is freaking annoying! You don't want to type with one step up from a bow and arrow (if you want to know if the id is right or not, stop typing), but you want a freaking water hose that says "not found yet" until the identifier is found.

I think there is a lot of "I learned how to [do/read/write] it this way and don't want to change that", which is quite reasonable but prevents much progress from occurring at all, so programming continues to remain stuck in the 70s.

Take some chances, even if you get some flack for it. A very accomplished UX designer once told me "listen to your users, but not too much." Be willing to experiment and take some risks.

I can get used to nearly anything

I can get used to nearly anything as long as the system doesn't change after I have internalized it. Once I am used to any particular feedback I only notice when it looks different from normal. Because the red boxes make all the errors look too similar to distinguish while I am typing, the most salient signifier of error will be that a red mark remains on a line I finished. The fewer the visual movements are when I type the more I will be able to see.

Unfound identifiers could be shown in a teletype font so you get that satisfying click of them changing font and looking right when they are right (you already have some of that when reserved words color). I also think that it would more pleasant if errors like "expected block" and "missing expression" showed (in pastel) what they expected you to type instead of red boxes. This kind of continuous feedback would be more visually distinct.

Don't listen. Observe.

There's a difference between listening to people and observing them. Listening to what people say is mostly useless aside from a way to frame how *they* happen to think about something. Observing their actual actions, though, is often very telling. You see all the things they don't even realize they do. You see them stumble and stutter when they're too busy trying to figure out what to do next. You see their first attempt at something and what their second guess will be, which they will have forgotten a few moments later. That kind of feedback is real and can't be faked or paved over with rationalizations. The goal of user testing is not to tailor to specific people or to find some statistically useful sample of behavior. It's to understand what behaviors you could care about and experiment with how correcting them affects people.

In terms of taking chances, we're going way out there. Our version of programming looks much more like excel than it does any form of code we have now. So experimenting and taking risks isn't exactly our problem :)

Expert tool bias

The other problem with user studies relates to the amount of training needed to use the tool. For example, architects are well known for spending a lot of time learning how to use Autocad, which creates a lot of resistance to non-incremental change. I imagine programming tools are similar. Expert review and walkthrough becomes more effective at some point.

I agree that observing is the right approach. Also, breaking up the experiments into pieces where you can make reasonable conclusions based on those observations is quite necessary. Still, if you want to know anything for sure, statistical confidence is necessary (otherwise, you'll wind up putting delays in your feedback leading to inoffensive but subpar experiences).

What you are doing with Aurora/Eve is risky, ya. There are similar projects along these lines: you probably know about Burnett's Forms/3 or Repenning's AgentSheets. The VPL community is also the original HCI community; these are the people who basically invented usability testing.

request for mode with less help and less motion

(This is intended to be helpful, in case you don't get a chance to do any user testing with folks holding preferences like mine. I wonder how many UI folks want to ask users, "Why didn't you tell me you hate that earlier?")

After years of using tools, I noticed two UI details making me angry: 1) undiscoverable actions, and 2) spontaneous tool behavior without user cause. This post is mainly about the second, because your interest in active IDE experience makes it relevant to the sort of feedback I might give.

I won't use an editor that changes anything I type. I want to see exactly what I keyed and nothing else, so help seems like interference. When a UI preference dialog permits, I turn off every possible way a interface can do something automatically on my behalf. Basically, I don't want to see pixels change unless it's in response to something I just did. I'm always thinking about a lot of things besides what I see now — usually about what I plan to do next — and anything that demands attention is disruptive, and costly in terms of my time.

Here's an analogy. When playing video games, I always turn off auto-aim because I want camera direction to exactly match what I did to controls. Aim help is interference because it makes the controls unpredictable and unreliable. Unrequested motion can even be slightly disorienting. I'm not prone to motion sickness, but I get a twinge when an interface follows a plan not my own, especially when obeying my orders is otherwise the norm.

You can see why I hate Javascript in web pages. I want content to hold still and do nothing but translate coordinate systems when I scroll. Gratuitous UI motion is only entertaining if you have nothing going on in your mind. I would expect novices to like help, and experts to hate it.

ligatures

I agree to a point. The obvious solution here is heavier use of ligatures where we simply typeset pairs of characters together without obscuring their meaning (BTW, did you know "&" is a ligature for "et"?).

Unfortunately their is no font that yet provides for "programming ligatures." However, if people find the rendering useful and the input unintuitive, then that would drive demand for someone to create a new font! So rather than render <= as the traditional less-than equal symbol, we could render something that includes < and = together in a way that approximates the traditional symbol without keeping them as separate characters.

The rest is a bit strong: "Whenever I go to destroy the death star, I turn off my targeting computer and use the force" can work for some people (especially Luke Skywalker), but dammit, that targeting computer is useful to most people. Also, you are never going to be able to fly a modern fighter jet without "fly by wire." Motion-based feedback can be very useful and non-annoying if done right (see iPhone).

optional mute buttons for busy features

This is just for conversation, since I likely already said what was actually useful. (Irritation is roughly proportional to pixel movement times infeasibility of expecting movement in advance; motion plus surprise is distracting.)

I like targeting computers, but I want to toggle them on and off. Unlike Skywalker's one shot at the Death Star's weak spot, programming is more like a game where you do things over and over again, instead of just once. So it's possible to compare one run with another, many times, as part of deliberate practice. When it comes to fighter jets, there's such a thing as too much UI; some pilots used to turn some of it off in order to remove distractions.

Limits of human attention are interesting. In the 70's I taught myself to juggle, and after a few hundred hours I was pretty good at five balls. Part of my interest was analyzing how much I could track at once, which was not a lot. Usually I was tuning trajectories to be non-interfering. Folks watching me asked how I could catch balls without seeing them, since when watching where balls crest you can't even see your hands. Turns out I caught on auto-pilot and only thought about throwing. I could throw one ball, close my eyes when it crested, then still catch it blind just as well (with direction of ball's center of mass hitting within half inch of the base of my middle finger). Conscious decision is something like 'acquire object' and my brain arranges my palm is where the object is going without me attending detail. I have snatched objects from the air knocked off tables multiple times; I can tell right away whether a moving object is within the ambit of where I can get my hand in half a second, but it doesn't involve conscious thought. It's just training from catching tens of thousands of dropped rubber balls, and anything that just started falling moves slowly. (The danger is in slapping instead of catching, when out of practice, with hand moving as fast as feasible.)

Now, that doesn't have much to do with programming, except there's only so much you can attend at once, so busy interfaces necessarily make you dumber, in the moment, to the extent you have less capacity left over to use yourself. Perhaps the more introverted you are, the more irritating it is to have a flamboyant tool throw away all your spare attention; who knows?

If the only thing your UI does is alter typography without altering layout, maybe that's ignorable by both conscious mind reasoning and mind's eye imagining. I don't find continuous syntax coloring as I type a distraction in emacs, because symbol location doesn't change. I prefer syntax coloring even though I worked without it the first several years of my career. As long as cues for slicing and dicing ways of grouping information are not over-done, I like many at once, if I can tune them out by not caring.

I guess I did know ampersand was a ligature for et; I was once pretty interested in everything that had to do with language and symbology. (Picture me browsing every single book on the shelves for related classifications; read table of contents, flip through book, then go on to the next volume when most books are boring.) As a teenager I thought the history of the design of Gregg shorthand was interesting. Did you know the use of (very high decibel) whistling to transmit speech has been independently invented in geographically diverse areas, like mountainous and island communities, where physical proximity was sometimes very awkward?

I have an iPhone, which I don't use more than combined pocket watch and pager. Almost everything folks love about modern mobile computing I find a complete waste of time: the triumph of drivel over substance, often in the form of self-story dramatization. (For example, talk about juggling is drivel too, sure; actually juggling is something else.)

Thinner lines, more

Much preferable to me

Much preferable to me

Needs more cowbell

When typing, the side line feels too far away, like I'm typing into dead space. To fix that, I think the sideline has to be brought in close to where the indented line starts, maybe with a one space gap.