Feature Use static variables for all instances of a script

zarqon

Well-known member
I really like mafia's static variables. I enjoy being able to reduce the amount of "loading time" a script needs.

I've found myself wishing, however, that they would be even more static. At the moment, if I have a script loadstuff.ash that processes some data into a static map variable, and then call dostuff.ash, which imports loadstuff.ash, loadstuff will do all its loading work into a static variable. Now, I call printstuff.ash, which also imports loadstuff.ash. Rather than use the stored static variable (which is associated with dostuff.ash), it does all the work again and creates the same static map again, only this time associated with the name printstuff.ash. There are now multiple copies of the map in memory, which is being used identically by all scripts that reference it.

I haven't been able to think of a compelling reason why it may be undesirable to simply associate the map with loadstuff.ash, so that regardless of whether dostuff or printstuff was called, it would access the same static variable.

For example, ZLib and BatBrain get imported into a variety of scripts, which means the benefit of using static variables there is reduced. ZLib's script settings are loaded once per script that imports ZLib rather than just once. BatBrain's factors map probably gets loaded a good half a dozen times for me during normal play. So after using 10 scripts that import ZLib, users will have 10 copies of vars in memory. This seems like it could be improved by consolidating the duplicates.

So! I would like to request a change to the behavior of static variables, to be per session rather than per calling script. Thanks!
 

xKiv

Active member
How do you propose to differentiate these superstatic/shared variables?
Should two variables with the same name share the same value even if they are declared in a different library?

I would definitely say this shouldn't be a change to all static variables. It would work for write-once-then-read-only data like these preloaded preprocessed maps, but sometimes you might want a librarry that keeps separate state for each script it is used in, or something? Don't throw away a thing just because you are currently only using it for something that a different thing would do better.

BTW, what happens when two scripts are using the same shared map in parallel (that can happen, run one from cli and another triggered from relay browser) and one of them changes it? Or changes some data *in it*? Now that you are sharing it potentially among all ASH interpretters, you are really asking for race conditions, deadlocks, and other such "awesome" stuff.
 

Veracity

Developer
Staff member
This would be a major change. You are, essentially, requesting that "import" no longer loads a script into your source at compile time but is "linked" to it at run time. I.e., shared libraries. I've wanted something like that, but it is very complicated.

I assume that you've noticed that when you "import" a script, all of the functions (and variables) of that script become part of the symbol table of functions (and variables) accessible to the main script. You can call functions (and access variables) as if the code for them were in the same script. Technically, when you compile a script, we built an "interpreter" for that script, the "parse tree" of the whole script is built, and every scope within that parse tree has an associated symbol table of types, variables, and functions. So: all of the types, functions, and variables of the imported script are entered in to the symbol table of the top level scope and can be accessed as if they had been in the same file as the top level script.

A "shared library" feature would, I assume, work like this: rather than "import", you'd say "link" (or something) and the other script would be compiled into its own interpreter. Some or all of its top-level types, functions, and variables would be "exported" and would be, effectively, entered into the top-level symbol table of the other script. They would be associated with the interpreter of the linked library, and any references to those functions or variables would execute in the context of the other interpreter. The variable (or return value of the function) would be passed back to the caller. Synchronization would be required to ensure that only one script at a time was "in" a particular shared library. Well, we already synchronize on interpreters, so this is more of the same - except that synchronizing on multiple resources (i.e. shared libraries) can lead to deadlock, if not done exactly right.

Long story short, it is technically feasible, but would require major changes both in the parser and in the run time model of the ASH interpreter.
 

Veracity

Developer
Staff member
And xkiv's ninja comment points out a lot more of the complexity of sharing libraries. With import, you know immediately if multiple imported scripts define the same variable or function. With runtime linking, it wouldn't necessarily be a problem for multible libraries to define the same symbols - until and unless the main program wanted to call or access such a symbol. At which point, how do you resolve it?

And, yes - "write once" ("final") data is really not the same as "static" in ASH; "static" data will be INITIALIZED once, but nothing in ASH keeps you from assigning it as many times as you want - and certainly nothing prevents you from manipulating maps (and fields of records) repeatedly at run time. Declaring read-only or final or what-have-you data is a whole 'nother feature request.
 
Top