Add something on scoping
@@ -6,7 +6,9 @@ author: Yann Hamdaoui
# Overriding
-This document is a proposal for an overriding mechanism in Nickel.
+This document is a proposal for an overriding mechanism in Nickel. It is
+expected to evolve while we put these ideas in practice, but shall serve as
+design and implementation baseline.
Related issues: [#103](https://github.com/tweag/nickel/issues/103),
[#240](https://github.com/tweag/nickel/issues/240),
@@ -433,6 +435,27 @@ Merging simply merges the underlying representations:
repr(r1) & repr(r2) := fun self => r1 self & r2 self
```
+This brings the problem of scoping: should a record be able to access a yet
+undefined field because it is expected to be provided by a subsequent merge?
+Two possible approaches:
+
+ - **dynamically scoping**: records can reference fields that are not explicitly
+ defined locally, such as:
+ ```nickel
+ {a = b} & {b = 1}
+ ```
+ However, dynamic scoping have a number of issues, and is usually considered
+ bad practice.
+ - **lexically scoping**: as currently, require self-referenced fields to be
+ defined locally. Note that thanks to contracts, one can require the existence
+ of a field without defining it. For example, we could write the previous
+ example as:
+ ```nickel
+ {a = b, b | Num} & {b = 1}
+ ```
+ This is also a better practice to explicitly state the fields whose presence
+ is required.
+
### Priorities
Merge is fundamentally commutative. The problem is, not all fields should be
