Skip to content
This repository was archived by the owner on Dec 28, 2021. It is now read-only.

Commit 7671e44

Browse files
committed
first draft, wip
1 parent f746857 commit 7671e44

File tree

1 file changed

+249
-0
lines changed

1 file changed

+249
-0
lines changed

docs/connections.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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

Comments
 (0)