1New Locatives
2=============
3Old Locatives. Environ::lookup_lvar() returns a Locative, with only an
4update(Operation&) method, but it is currently always a Local_Locative
5with a Value* reference() method.
6
7The original design was to provide an abstract Locative interface that would
8support unboxed typed locatives, which we could update in place without
9extracting the value into a boxed form.
10
11New Locatives.
12Now we use a more functional style, combined with "linear logic" for
13efficient update. The base operations would be:
14    Value fetch() -- in Expression context
15    Value steal() -- May leave the contents undefined (for a local
16        variable anyway). Must call store() to restore normality.
17        If we panic before this happens, we destroyed a local variable,
18        probably doesn't matter.
19    void store(Value)
20For indexed update, we steal, amend then store, moving rather than copying
21the value around.
22
23For an unboxed typed locative, the value needs to be efficiently converted
24to boxed form for a fetch anyway. So plan for that: use a representation that
25makes this cheap. Eg a typed structure is a subclass of Ref_Value with typed
26unboxed fields. Amending a typed structure field with linear logic works how?
27* If the new field value is the correct type, then COW and mutate the field.
28* If the new field value has the wrong type, then
29  * Copy the structure into a DRecord and do the update (amend is blind).
30    Then the store() panics due to a bad field type. But amend doesn't know
31    about the type restriction on its output.
32  * The field update fails: records with typed fields have this restriction.
33    Doesn't this mess up the algebra of records?
34  * Okay, but, if I'm going to implement ADTs, then typed records can exist.
35    At the very least, you can use a special lens with a type restriction to
36    access & update a field, getting the same effect. This "special lens"
37    could be part of the same ADT as the typed record value.
38  This detour doesn't affect the design, can be resolved later.
39
40Preliminary New Locatives
41-------------------------
42Locative
43    Value fetch(Frame& f)
44        The Frame lets us fetch from a slot.
45    void store(Frame& f, Value newval, const Phrase& nvsyntax)
46        The Frame lets us store into a slot.
47        The nvsyntax lets us throw an error if newval is bad:
48        not currently used (Local_Locative accepts any value).
49analyse_indexed_locative(Phrase, Indexed_Locative, env)
50    On success, you get a Locative and a path (std::list of index Expressions).
51    It recurses down to an Identifier.
52Assign_Locative (has a Locative destination and a new_value Expression)
53    loc.store(f, nv->eval(f), *nv->syntax_)
54Assign_Indexed_Locative (has a Locative, index and elems expressions)
55  ::exec(Frame& f, Executor&)
56    index = index_expr->eval(f)
57    elems = elems_expr->eval(f)
58    curval = loc->fetch(f)
59    newval = amend(curval, index, elems, At_Phrase(*syntax_,f))
60    loc->store(f, newval, *elems_expr->syntax_);
61
62Error handling for Assign_Indexed_Locative.
63The syntax we are passing to loc->store is not the phrase that computed newval.
64So this design is screwed up; the error handling needs to be rethought.
65Since the third argument to Locative::store() is ignored anyway, remove it.
66Design something better when the need arises.
67