1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
keywords for file-local/module-local/exported classes/functions?
----------------------------------------------------------------
- local / (none) / export
- (none) / visible / export
- (none) / module / global
- file identifiers only make sense as either module-local or exported.
Or it could be module-export/file-export sections of each file?
(similar to `interface` in Pascal)
contents
moduleexport
SomeClass since 0.1
OtherClass since 0.2
fileexport
ModuleInternal
end
Or, when prototyping:
contents auto
contents
fileexport
all
end
Or, shorter:
module_export
SomeClass
end
file_export
AnotherClass
end
(although it's still not trivially greppable)
Alternative keywords:
exports
SomeClass
end
provides
AnotherClass
end
Or, with a keyword per line:
provides SomeClass
provides AnotherClass
Or, use a per-project text file:
file things.slul
SomeClass
AnotherClass
But there needs to be a clear distinction between `moduleexport`
and `fileexport`. Module exports shouldn't be done accidentally!
BUT most things will be "provided"/"file_exported" in lowercase files.
So it might make more sense to just have local for local things.
At least for types. And a `calledfrom` for functions?
Regarding module interfaces:
- Should the module interface be generated with a command?
(e.g. with `slul make-interface 1.2.0 1.1.34`)
- Should the module interface be manually created but checked by
the compiler?
Class-local calls vs typeident calls (or enum values)
-----------------------------------------------------
(this is only a problem in e.g. `y = b x`, where `b` could be
either a class-local call (`this.b`) or it could be a constructor
in the typescope of the type of `y`).
solutions:
- `calls` section in function decl, analaguous to `modifies`.
(slul2 would really become a "safetynaut" language :D )
- and actually, `modifies` is kind of of limited use if
doesn't track access from nested function calls.
- on the other hand, adding a `modifies` line to some deeply
nested "helper" function could cause a time-consuming "ripple"
effect, where all (nested!) callers would have to be updated too
- as a pragmatic solution, perhaps have `calls` and `modifies` apply
only to the function at hand, and not nested calls.
- have different naming conventions for typeidents
(e.g. uppercase, prefix with `new`/`create`/`make`, ...)
- but it would have to work for enum values, too.
- related: maybe the `own` qualifier/keyword could be used
for making ownership transfer clear.
(ownership and generics is a bit tricky, though...
converting between "List of own T" to "List of T" is not safe)
- or just defer bindings until the whole class/file has been parsed.
- could accumulate all unprefixed (no dot) identifiers in a tree.
- at the end of the class/file, the tree could be traversed, and
the identifiers could be searched in this order:
1. the class
2. the type (but this isn't known, so this step
would need to be deferred)
|