|
| 1 | +# General Rules |
| 2 | +This section attempts to describe how the identifiers are introduced and |
| 3 | +resolved in the language. |
| 4 | + |
| 5 | + |
| 6 | +## Definition |
| 7 | +Definition is any binding introduced using assignment (`=` operator) syntax. |
| 8 | +Definition may be optionally preceeded by a signature in a form `name:type`. |
| 9 | + |
| 10 | +For example, the following is definition: |
| 11 | +``` |
| 12 | +add : Int -> Int -> Int |
| 13 | +add a b = a + b |
| 14 | +``` |
| 15 | + |
| 16 | +or this is a definition with no signature: |
| 17 | + |
| 18 | +``` |
| 19 | +five = 5 |
| 20 | +``` |
| 21 | + |
| 22 | +Definitions can be also introduced within a nested code block: |
| 23 | +``` |
| 24 | +main = |
| 25 | + a = 2 |
| 26 | + b = 2 |
| 27 | + add a b = a + b |
| 28 | + add a b |
| 29 | +``` |
| 30 | + |
| 31 | +Here `main` is a definition and has nested definitions of `a`, `b` and `add`. |
| 32 | + |
| 33 | +### Term discrepancy with IDE codebase |
| 34 | +Note: this document uses term "definition" in a wider term than usually IDE |
| 35 | +codebase does. Here any assignment-binding is a definition, no matter if it has |
| 36 | +any arguments or not. (i.e. this definition is either gui-definition or a gui-node) |
| 37 | + |
| 38 | + |
| 39 | +## Scope |
| 40 | +Scope is the span in the code which shares the bound identifiers set. Scopes can |
| 41 | +be seen as span-stree, creating a hierarchical, nested structure. |
| 42 | + |
| 43 | +Nested scope is allowed to: |
| 44 | +* access identifiers from the outer scope; |
| 45 | +* shadow identifiers from nested scope by introducing new bindings. |
| 46 | + |
| 47 | +Otherwise, it is illegal to bind twice the same identifier within a scope. |
| 48 | + |
| 49 | +// TODO weren't we supposed to support overloading? |
| 50 | + |
| 51 | +// TODO what is duplicate definition and what is unification? Is there a |
| 52 | +difference between `=` and `:` after all? |
| 53 | + |
| 54 | +The identifier is bound scope-wide. It is visible and usable in the lines before |
| 55 | +the actual binding occurs. Some monads (like IO) can introduce order-dependent |
| 56 | +behavior, however. This is not something that GUI can tell by looking at AST. |
| 57 | + |
| 58 | +Symbols introduced into a scope is not visible outside the scope's subtree. |
| 59 | + |
| 60 | +Scopes are introduced by: |
| 61 | +* module/file (the root scope); |
| 62 | +* code blocks following operators; |
| 63 | +* module-level definitions: for both signature (if present) and assignment-binding; |
| 64 | +* `->` operator for its right-hand side. |
| 65 | + |
| 66 | +Example: |
| 67 | +``` |
| 68 | +main : a |
| 69 | +main = |
| 70 | + succ = b -> b+1 |
| 71 | + succ 0 |
| 72 | +``` |
| 73 | + |
| 74 | +The sample code is a module with a single top-level definition. |
| 75 | + |
| 76 | +Here we have four scopes, each one nested in the previous one: |
| 77 | +* root scope (consisting of unindented lines), where `main` is visible; |
| 78 | +* definition `main` scope, where `main` and `a` are visible; |
| 79 | +* code block scope (all lines equally indented after |
| 80 | + `main =`), where both `main`, `a` and `succ` are visible |
| 81 | +* lambda body scope (right-hand side after `a ->`), where all `main`, |
| 82 | + `succ`, `a` and `b` are visible. |
| 83 | + |
| 84 | +Example: |
| 85 | +``` |
| 86 | +test = a -> b -> |
| 87 | + sum = a + b |
| 88 | +``` |
| 89 | + |
| 90 | +Here we have root scope, `test`'s scope, then scopes of lambdas (after `a ->` |
| 91 | +and after `b ->`) and finally scope for code block. |
| 92 | + |
| 93 | +// TODO what difference this make if code block introduces its own scope? |
| 94 | + |
| 95 | + |
| 96 | +## Contexts |
| 97 | +There are two kinds of context: pattern context and non-pattern context. |
| 98 | + |
| 99 | +Each position in code is either in a pattern context or not. By default code is |
| 100 | +in non-pattern context. Pattern context is introduced locally by certain |
| 101 | +language constructs: `=`, `:` and `->` operators (i.e. definition bindings, signature type ascription and lambdas). |
| 102 | + |
| 103 | +Each usage of a variable name (identifier starting with a lower case letter) |
| 104 | +actually binds this identifier with whatever it is being matched to. The bound |
| 105 | +identifier is visible and usable within the target scope. |
| 106 | + |
| 107 | +// TODO are operator identifiers bindable? Likely they require special rules. |
| 108 | + |
| 109 | +Pattern context always has the single target scope, where the identifiers are |
| 110 | +introduced into. What is the target scope depends on the operator that |
| 111 | +introduced pattern context. |
| 112 | + |
| 113 | +Pattern context is introduced within: |
| 114 | +* left-hand side of assignment operator, e.g. `main` in `main = println |
| 115 | + "Hello"`; |
| 116 | +* right-hand side of a colon operator, e.g. `a` in `foo:a`; |
| 117 | +* left-hand side of an arrow operator, e.g. `a` in `a -> a + 1`. |
| 118 | + |
| 119 | +Both `=` and `:` introduce identifiers into the scope where they occur, as they |
| 120 | +do not introduce any new scope of their own. |
| 121 | + |
| 122 | +The `->` operator introduces identifiers only into the scope of their right-hand |
| 123 | +side, if the lambda is not introduced in what is already a pattern context. |
| 124 | + |
| 125 | +Example: |
| 126 | +``` |
| 127 | +succ = a -> a + 1 |
| 128 | +foo = a |
| 129 | +``` |
| 130 | + |
| 131 | +Here lambda introduces `a` only into its right-hand side. The `a` that is being |
| 132 | +assigned to `foo` is not the same `a` as in lambda — it must be defined |
| 133 | +elsewhere in the module or the code will fail. |
| 134 | + |
| 135 | +However, if `->` appears in a pattern context, its left-hand side identifiers |
| 136 | +are introduced into the scope targeted by the outer pattern context. |
| 137 | + |
| 138 | +Example: |
| 139 | +``` |
| 140 | +(a -> b) -> a.default |
| 141 | +``` |
| 142 | + |
| 143 | +If not for this second rule, the `a` would be visible only in place of |
| 144 | +expression `b`. However, now it is visible in the outer lambda body and can be |
| 145 | +accessed. |
| 146 | + |
| 147 | + |
| 148 | +# IDE Connection Discovery |
| 149 | +IDE presents a definition body as a graph. Code lines of the body of the |
| 150 | +definition are displayed as nodes (unless they're definitions). |
| 151 | + |
| 152 | +We want to display connection between nodes, if an identifier introduced by one |
| 153 | +node into the graph's scope is used in another node's expression. |
| 154 | + |
| 155 | +Some simplifications are currently assumed: |
| 156 | +* Connections care only about usage of symbols introduced by assignment |
| 157 | + definition. For example, variables introduced by `:` operator's right side do |
| 158 | + not form connections. Same for lambda arguments. |
| 159 | +* we care only about identifiers introduced into graph's scope: anything that |
| 160 | + appears in subscopes can be disregarded. However, IDE must be aware of |
| 161 | + shadowing to properly tell if an identifier usage actually refers to an |
| 162 | + identifier from graph's scope. |
| 163 | +* There is no graph for the module's root scope, so any special rules for the |
| 164 | + root scope might be irrelevant. |
| 165 | +* IDE is concerned about producing correct results for correct programs. It does |
| 166 | + not care about diagnosing ill-formed programs, quite the opposite. We want to |
| 167 | + keep output as similar to the correct one as possible. (we will often |
| 168 | + visualize programs that are in progress of editing) |
| 169 | +* For the first release IDE can disregard the type ascription operator (`:`). |
| 170 | + |
| 171 | + |
| 172 | +// TODO: what is graph's scope? Is this a definition's scope (if there's such |
| 173 | +thing) or code block's scope? |
| 174 | + |
| 175 | +Basically, the problem can be reduced to being able to describe for any line in |
| 176 | +code block the list of identifiers it introduces into the graph's scope and the |
| 177 | +list of identifiers from graph's scope that it uses. |
| 178 | + |
| 179 | + |
| 180 | +## Connection |
| 181 | + |
| 182 | +Connection is an ordered pair of endpoints: source and destination. Endpoint is |
| 183 | +pair of node ID and crumbs. Source endpoint identifiers the node which |
| 184 | +introduces the identifier (source of data), and crumb describes the identifier |
| 185 | +position in the node's assignment's left-hand side. Destination endpoint |
| 186 | +similarly describes position in node's expression where the identifier is used. |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +# TO BE REWRITTEN |
| 197 | + |
| 198 | + |
| 199 | +``` |
| 200 | +a -> a -> b |
| 201 | +``` |
| 202 | + |
| 203 | +Here the first `a` and second `a` are separate identifiers, the latter shadowing |
| 204 | +the first one. If one wanted to express that both arguments are of the same |
| 205 | +type, `a -> A -> b` should have been used. |
| 206 | + |
| 207 | +--- |
| 208 | + |
| 209 | + |
| 210 | + |
| 211 | +``` |
| 212 | +a -> b = c |
| 213 | +``` |
| 214 | +Does this introduce the `a` into the module's scope? |
| 215 | + |
| 216 | +(rules say "only if inline `=` does not introduce a new scope) |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +``` |
| 221 | +a = Int |
| 222 | +foo = 5:a |
| 223 | +``` |
| 224 | + |
| 225 | +Does `a` in `5:a` refers to the previous line's `a` or is separate? |
| 226 | + |
| 227 | +Marcin: na pewno nie shadowują, mogą się unifikowac lub kolidowac jako |
| 228 | +redefinicja |
| 229 | + |
| 230 | + |
| 231 | + |
| 232 | +Co jeżeli |
| 233 | +``` |
| 234 | +a = Int |
| 235 | +foo = Int : a |
| 236 | +``` |
| 237 | + |
| 238 | + |
| 239 | + |
| 240 | +TODO |
| 241 | +W top levelu jaki jest dokładnie obszar scope'u definicji? |
| 242 | +Czy obejmuje sygnaturę? |
| 243 | + |
| 244 | +Czy może być wiele sygnatur do definicji? |
| 245 | +Jak dać sygnaturę do czegoś co nie ma żadnej nazwy lub ma wiele nazw? |
| 246 | + |
| 247 | +Różnica między pattern-matchingiem a typowaniem? |
| 248 | +Różnica między `a = 5` oraz `5:a`. Co jest wartością, co jest typem? |
| 249 | +Sygnatura bez definicji? |
0 commit comments