### Setter semantics

Dusk OS defines the immediate word "to" along with what is called "setter
semantics". Any word, not only values, can have a setter routine. That setter is
activated when "to" is called right before invoking it. This works at compile
time too. For values, "to" is the exact equivalent to "!", but more efficient
because we don't push and pop a destination address to stack. For other words,
it might have another meaning. For example, [drv/pc/ioport] uses setter
semantics to compile x86 OUT instructions.

To implement a setter, you use "to?," like this:

  :> ."getting!" ;
  :> ."setting!" ;
  code foo findselector
    litn to?, ifz, swap i) @, then exit,
  foo \ prints "getting!"
  to foo \ prints "setting!"
  : bar foo to foo ;
  bar \ prints "getting!setting!"

## value

These semantics allow the concept of "value", which is like a "variable", but
calling the word automatically dereferences the address, which saves a whole
bunch of "@" calls. When you need to write to a value, use "to".

Values are compatible with Big Moustache [lib/bm] and can be used with the ">"
modifier.

## getsetter,

When implementing a typical setter words, you often end up with a findselector
word that has to support many possibilities:

* scry
* interpret-time get
* interpret-time set
* compile-time get
* compile-time set

If you follow the instructions above, that's quite some boilerplate you have to
carry around. To reduce this boilerplate, we have "getsetter,", which has this
signature:

  ( settercompilerxt setterxt gettercompilerxt getterxt scryval -- )

You supply it with the correct values and it generates an immediate findselector
for you, which will yield the correct values depending on values SCRYING, to?
and FINDCOMPILER. For example, here's the implementation of "value":

  : _do@, dup, m) @, ;
  : _do!, m) !, drop, ;
  : value here# n"VALU" , swap , ( valu )
    code> swap dup 4+ litn ['] _do!, bbr,
    code> swap dup 4+ _do!, exit,
    code> swap dup 4+ litn ['] _do@, bbr,
    code> swap dup 4+ _do@, exit,
    getsetter, ;

The first code> is the settercompilerxt, which is what happens when we invoke
the value with "to" activated and during compilation. It will do, at *compile
time*, the equivalent of "valueaddr m) !, drop,".

The second code> is the same thing, but for interpret time. So instead of
compiling "valueaddr m) !, drop,", it calls a word that has compiled this very
code already.

The other two code> are the like the first, but for when "to" is not activated.

Finally, on top of PS, we end up with a pointer to the *tagged* [doc/usage/tag]
address of our value, which allows units like [lib/bm] to do introspection on
that value and compile moustaches for it.
