vision
Install

Concept guide

How Vision thinks

Vision programs are made from described things and verbs. A small marker shows where that work reaches beyond the program.

Start with the things in the problem

A kind describes a thing by naming the facts it holds. The example below has a note with a title and a body. Later, the construction block builds one note and fills those two fields.

This keeps related facts together. Code can pass the note around as one value instead of carrying its title and body as separate values that happen to belong to each other.

Give the work a verb

Verbs name what the program can do. render takes a note and answers with text. It only reads its input and builds a new value, so its declaration and its calls need no world-touch marker.

A verb can call another verb. In the example, save calls the calm render verb before it writes anything. The names keep the intent visible: render the note, encode the result, then save it.

Calm work stays unmarked

Local arithmetic, comparisons, and value construction stay inside the program. They need no >>. Parentheses make the order of mixed arithmetic explicit here; the whole calculation remains calm.

tiles.viscompiler checked
to begin:
    the width is 40
    the depth is 3
    the tiles is (the width times the depth) plus 2
    say "we need {the tiles} tiles"
to begin:
    the width is 40
    the depth is 3
    the tiles is (the width times the depth) plus 2
    say "we need {the tiles} tiles"
This program only names values, calculates a total, and prints it. No tracked world-touch needs a marker.

Mark the boundary with >>

>> means that a line touches the world outside the program. The marker appears on the file write, on the call to the effectful save verb, and on each verb declaration whose body reaches that boundary.

The compiler checks both directions. Leave >> off an effectful line and the program is rejected. Put it on a calm verb and the program is rejected too. Calls carry the rule with them, so a verb that reaches the world through another verb must also say so.

note.viscompiler checked
>> to begin:
    the note is "a line written down"
    the data is the note encoded as bytes
    >> write the data to the file at "note.txt"
        | unwritable: say "could not write the note" and stop
>> to begin:
    the note is "a line written down"
    the data is the note encoded as bytes
    >> write the data to the file at "note.txt"
        | unwritable: say "could not write the note" and stop
The calculation and byte encoding stay unmarked. The file write and its enclosing begin verb carry >>.

Put the pieces together

thinking.viscompiler checked
kind note:
    title: text
    body: text

to render(note: note), returns text:
    answer "{note.title}: {note.body}"

>> to save(note: note, path: text):
    the rendered is render(note)
    the data is the rendered encoded as bytes
    >> write the data to the file at path
        | unwritable: say "the note could not be saved" and stop

>> to begin:
    the field note is a note:
        title is "Field notes"
        body is "Mark the line that reaches outside."

    say render(field note)
    >> save(field note, "field-note.txt")
kind note:
    title: text
    body: text

to render(note: note), returns text:
    answer "{note.title}: {note.body}"

>> to save(note: note, path: text):
    the rendered is render(note)
    the data is the rendered encoded as bytes
    >> write the data to the file at path
        | unwritable: say "the note could not be saved" and stop

>> to begin:
    the field note is a note:
        title is "Field notes"
        body is "Mark the line that reaches outside."

    say render(field note)
    >> save(field note, "field-note.txt")
This program prints one line and saves the same text to field-note.txt. The build gate checks both outputs exactly.

say is the deliberate small exception. Direct console output stays unmarked. If the value on that line reads the clock or environment, that world touch still needs >>. File access, networking, clocks, randomness, and environment reads all use the visible boundary.

Try the boundary

Change the title or body and run the program again. Then remove the marker from the call to save in begin and compile once more. The compiler rejects the call because its effect is no longer visible. Restore the marker, and the program is honest again.

Next, read a larger Vision program and see how these same pieces fit together across more than one verb.