← All posts

Rux v0.7.1: what the window said, and what it did not

A patch release made entirely of driving v0.7 and writing down what happened. An input inside a component took no text at all, imports looked in one place and never said so, and a long list of mistakes were made quietly instead of reported.

v0.7 shipped a list of claims. v0.7.1 is what happened when those claims were driven one at a time, in a real application, in a real window.

Almost nothing in this release is a new feature. The pattern that came out of the exercise was not that Rux did the wrong thing. It was that Rux did nothing, and said nothing, and left the author to work out which of the two had happened.

An input inside a component took no text

The worst one. A text field with an r-model, written inside a component, could not be typed into. Not slowly, not partially: every keystroke went nowhere and the field stayed empty.

An r-model names a piece of state. Inside a component, that state belongs to the component instance, and the same component on screen twice has two of them. The input node never recorded which instance it had been written in, so the value was read and written in the document's scope, where the name does not exist. The write landed somewhere nothing reads, and the read came back empty.

The identity of an input is now three parts: the model, the row it is in if it is inside an r-for, and the instance it is in if it is inside a component. The same missing third part had two more consequences that were being lived with: :focus lit the matching input in every instance of a component, and a <label for=...> pointed at the wrong one. A label now takes its scope from the input it names rather than from wherever it happens to sit.

Imports looked in one place and did not say where

An import resolved against the project root only. A component sitting in the same folder as the file importing it was not found, which is the arrangement almost everybody tries first.

Imports now resolve beside the importing file first, then at the project root. When both fail, the error says both places it looked. There is still no super:: and no .., on purpose.

The silences

The rest of the release is a long list of the same shape: Rux did something defensible, and did it without a word.

Diagnostics say whose line it is

Adding line numbers to warnings made the multi-file case more dangerous before it made it safer. A warning raised inside an imported component carried the component's line number and the importing file's name, which points confidently at an innocent line in the wrong file. Unplaced is vague; placed and wrong is a trap.

Warnings now carry the file they came from, and a warning with no honest position is left without one rather than given a guess.

Where Rux differs from CSS

The divergences from CSS were scattered through the reference, each beside the feature it belonged to. They are now one page, and each entry says which kind of difference it is: a capability Rux does not have, a question CSS answers meaninglessly here, or a preference.

That last kind is now the one the project rules out. An author arrives knowing CSS, and every place Rux answers differently has to be learned, usually by being surprised in the window. The flex cross axis defaulting to flex-start rather than stretch is listed there as a divergence to be reverted: it changes the layout of every existing document, so it cannot go in a patch.

rux new writes an app

The scaffold used to write a hello world. It now writes a routed project: a screen, a tab bar, three pages, a shared piece of state and a component.

Writing it was the point of it. A template a reader copies from has to be a shape worth copying, and building one found defects that no test had reached, including the align-items divergence above, which bit three times inside one small application.

The editor

The VS Code extension is at 0.4.1. Completing an attribute used to offer its values as bare words, so type on an input listed five names with nothing to choose between them. Each value now carries a line explaining what it does that the others do not. The runtime remains the source through rux vocab, so the editor cannot drift from what the parser accepts.

Getting it

cargo install ruxlang

The validation line stays open. v0.7.1 is what one pass through the claims produced, and there is no reason to think one pass was enough.