thinking of the future i would suggest some Alias and some dropOuts regarding keywords.

We have the procedures "SUB" and "FUNCTION" theirs behaviour is just starting to differ - at least thinAir
bugs now if i end a function with "End Sub". Previously it did not matter - all were functions and SUB was an alias only but returned a long variable...

Now both are to categorize as "Procedures" or "scriptportions with an own variable-scope.
There we have a bunch of keywords,
where i would suggest to rename the "Function_"- part since these work on Subs too - to somewhat
that unites both as

' one more i would add - it's already present in thinCore and since
' GetStackLevel (" thinBasic_StackGetCurrent") is here it should
' fit into that section as 


  ' Returns a string containing the names of the current nesting stack levels
  ' As a minimum this function will return one string containing "GLOBAL"
    DECLARE FUNCTION thinBasic_StackGetList                          _
                            LIB   "thinCore.dll"                    _
                            ALIAS "thinBasic_StackGetList"          _
                            (                                       _
                              OPTIONAL BYVAL sSep AS STRING         _
                            ) AS STRING
this function is the key to any future variable scoping, i think of a scope on scriptlevel,
as soon as scripts become typified - so its the same mechanics as with UDTs. The trick
is to have virtual variables upon all udt-subelement-variables - which are public currently.
I guess it is easier to create a variable with restricted or limited access by using a symbol
as part of the name that overrides the dot. Suggest were "This;method" or "my!property" -
or a bit as pascal/python "object::subelement"
However for the regular subelements that are defined within "Type-End Type" but outside of
UDT-functions as this below
- Since Functions in UDTs not necessarily return a value and to clarify and prevent of confusion
- i suggest to name these either "METHOD" or "PROCEDURE"
What they currently do not do is to participate at the udt-variable-scope- every method has its own
local - procedural - scope. Since these methods are enclosed within Type-End Type it were a logic
conclusion when defined variables within type-end type are local accessible the same way as global
variables can be accessed
Type t_myUDT
   ABC as String 
   XYZ as Number

' there is no code in the areas between methods - except some assignments to static values
' the here - above- defined subelements are used nowhere without the prefix of the variables name
' or by prefixing these with "Me." ... 

  Method _Create()
    ' when this is entered the udt-variables ABC or XYZ are not valid here. There are 2 options
    ' how these can be made local accessible here. 
   ' option 1 : all udt-variables (except statics) are passed byref automatically into any methods
  '  so to say ABC and XYZ come in here as invisible function parameters because they are not listed
  ' in the functions header - but are present - previous any function parameters, so 
  End Method

  Method DoSomething(Byval ABC as String) As Boolean

    ' this headline must invoke an ERROR for duplicate definition of ABC when ABC and XYZ were
   ' passed as invisible parameters ByRef.
    ' there were no need to use Me.ABC - just ABC would serve.

   ' the other option is working without the byref-parameters but it were to define on entering 
   ' a method as below
End Method

Method WithUDTScope()
' --- at this point thincore must interfere, means like detect location of ME (does it anyway)
'     and read the lines outside of the methods, interpreting these as
Local XYZ As Number At VarPtr(Me.XYZ)
'    for strings the layover works different ( i posted a thread in the past year 
'   - should be no problem to apply here,  

End Method
End Type
When the variables are dimensioned locally - virtual upon the udt-elements - the functions - Methods -
participate, share the variables on local scope while this encloses all functions within the same udt:
It means the creation of a new variable-scope is as easy as that.

Then one more Alias to the keyword TYPE: suggest UNIT and means a new kind of script: based on the
udt-rules. Outside of methods it has no code but only dimension, declare, #Include,

the last classic : Callback
Callbacks are functions always since they have a result, an answer or a reply to return.
For now just
Callback cbMain() As Long

End Callback
to separate the callback from tb-functions as first step, repair thinAir that will not auto-place "End Function" on a callback (btw. I changed my OS - thinAir works again is not "blind" anymore.)

later - when windows no longer supports the hWnd-Api (deprecated already but i guess support will be given for decades) there willl be no more Callbacks, activeX nor OLE.

.. time for "Events" and start to drag the interpreter into a 64Bit-environment.
backward compatibility for core only since the technologies where the modules are based on are left in the past.

Back to the unit- alias Type for scripts and the multiple variable-scopes.

By nature its encapsulated - nothing of it is accessible from outside but the methods only after the Unit was included to the project and an instance (variable or array) of it was dimensioned.

No "Private" nor "Public" required to achieve that. Still thinkable to protect data within the type-scope
in a very simple way: variables that are not meant to be public will not be provided byref nor virtual,
require the "ME"-prefix - which is a byref passed certification of the callers identity. For safety reasons
the data could be shifted together with "ME" - a fake of "ME" is impossible that way since only thincore
knows the current position of real ME.

The dimensioning of aa variable as instance of the scriptunit offers itself to be used for multiple documents or objects that we will use more than once. Any controls can become units to have them work similar on any window, even dialogs can be created as
Units - so they provide scripting, for example any dialog can initially check if APP_Inifile contains a
section thats name matches the dialogs name where it can read its own individual creation parameters
as well as the dialog template (editor, browser, toolwindow, MDI etc.) can construct the skeleton for it
already in the Units _Create()-function once a library of basic "ini-scripts" is available

- perhaps it were another name than "_Create" for code-Units since the actual creation were if someone
is typing the scripttext of it and also "_Destroy" is not really happening since the script persists until
execution stops.

_Load, _Initial or _StartUp were better verbs here, also well as _Unload, _Final or _ShutDown

one more big script-unit i have in mind that is a bit more than just the content from Unit to End Unit,
but there will the main part of the code reside and provide a variable-scope accessible to the mainfiles

Outside of the Unit-End Unit-Block were no more code to execute located -
but only
directives and preparse-statements,
global enumerations and variables,
new udt-structures
resource-blocks (rawtext, asm, oxygen, compiled/endcompiled, embedded .ini and .config(.xml)-
native string-tables

All these code- and resource-blocks can be encrypted and compressed
- in thinAir only present as a folded #Region -

useful only if a name or tag is added to specify during execution the block,
which ressource or template were to use.