User:Colby Russell/Static initializers: Difference between revisions

habitats
(ordering concerns for static initializers)
(habitats)
 
(5 intermediate revisions by one other user not shown)
Line 40:
A use case: in the new lexer, I want to be able to assert that the constants selected for <code>Scanner</code> "enums" don't collide with the constants selected for <code>Token</code>. Even with the convention that <code>Token</code>'s constants are no less than, say, <code>101</code>, it sure would be nice to both communicate the relationship between carefully selected constants to other programmers and getting machine verification at the same time.
 
NB: There are also ordering concerns, similar to those we ran into for <code>extends</code>, based on TC39's (IMO extremely silly and unnecessary) decision to make class hoisting differ from the way function hoisting works. This means we have some difficult choices:
 
1.# forbid cross-module references for top-level scope (no <code>Scanner.WHITESPACE = Token.WHITESPACE</code>, for example; we could make an exception for where we're already handling ordering issues, such as if <code>A</code> extends <code>B</code>, then <code>A.FOO = B.BAR</code> is permitted, but that seems sketchy)
2.# forbid them as above, but give static assertions special powers and by necessity sequester parsing issues with the mandate that they appear only as a triple slash directives
3.# allow everything forbidden in (1), so long as there's a way to do re-ordering that eliminates the problem, and then have the compiler do it
 
Of these choices, I like (3) the least, because it also compromises our principle of "you can keep all the rules in your head, and whatever the compiler does you could do yourself by hand if you wanted to" and it leads to code that isn't [[top-down]]. And I don't especially look forward to having to implement a satisfiability solver even in the compiler.
 
'''2020 July 26''': Another way of describing state, especially to [[User:Colby Russell/JS bridge|alien]] programmers: the runtime (more specifically, the thread[XXX] of execution kicked off by `main` [or what-have-you]), combined with the filesystem is your state, and you don't have arbitrary write access to the filesystem for state persistence, so it's best to keep this in mind while designing your programs. Unlike JS or, say, Modula, there is no module state, because module state implies top-level state (and indeed, the entire notion of module state is just another way to avoid saying "global state" by trying to cast it in a way that people won't notice), and top-level state is prohibited by the declarative nature of the t-block file format.
 
'''2021 January 18''': The simple way I've chosen to deal with this is to instantiate aliens and then make them accessible as a property of the caller's `statics` property. For example, in triickl 0.11.0 primary module's constructor, we have:
 
this.statics = Triickl.initializeForeignModules();
 
... and then elsewhere:
 
const { sha1 } = this.statics;
 
... which we can use within that method as `sha1(foo)`. I like this a lot better than the magical awaken/activate pattern detailed earlier. Perhaps better still would be if these were initialized in the shunting block and accessible from the `statics` property of the system interface? This does introduce a disconnect between the code that actually uses it and the place where the module is imported, however... So maybe the system layer should allow a QueryInterface-like call? The module that uses it would import the constructor, which would be expected to conform to a certain contract (a no-arg constructor), and the system layer can lazily initialize a given constructor if we check against a weakmap and find no entry.
 
'''2021 January 21''': reified "global" states should probably be called something like "habitats". They're created somewhere around main during program initialization and then passed explicitly. To get habitats on the cheap, maybe the convention should be to pass the habit to the host support modules during initialization of the system layers, and application code can access its facilities via `system.habitat`. I considered "environment", but it seems too verbose.
Anonymous user