[Wish] Wish to use 'Local' to prevent a nested function becoming a closure or introduce keyword 'Closure' to force it.
Posted: 22 May 2021, 06:33
@lexikos Wish to use Local to prevent a nested function from becoming a closure, or to introduce the keyword Closure to force a nested function to become a closure.
For example, when writing a hook using Dllcall in an object method, to ensure the object instance can be released even if the hook has been installed and hasn't been unhooked yet, you should write code in a nested function rather than a closure as the callback function which is used for registering to the hook. You must not write the code in a method as the callback because a method must have captured this causing the object can not be released. You had better write the code in nested function carefully to avoid the callback becoming closure, just for safety purpose or for reducing unnecessary closure creation.
All in all, you sometimes really need simply write a nested function without being a closure, for a callback or some other purposes.
Without Local or Closure, you would probably write:
With Local, you can write:
Like force-local mode, using keyword local to make sure the nested function will never be a closure.
Or, with the new keyword closure, you can write:
I strongly recommend introducing the new keyword closure rather than using local. The code of an outer function can be copied or cut into another function to become a unclosure inner function without any modifications. The nested function becomes a closure only when the keyword closure is given in the first line of or in front of the function (note: an AHK developer would never write the closure keyword if there are no outer variables being captured or no need to become a closure). It obviously simplifies the rules and probably increases the performance, because it no longer needs to make complex rules to take time to determine whether a nested function should become a closure. All the program has to do is to check if the keyword closure is given.
With the introduction of the keyword closure, you can even change the V2 language to allow using %String%:= in a closure to modify and capture the value of a variable from an outer function without all the possible outer variables from %String% being captured in advance. It can not do this at present from the new documention.
For example, when writing a hook using Dllcall in an object method, to ensure the object instance can be released even if the hook has been installed and hasn't been unhooked yet, you should write code in a nested function rather than a closure as the callback function which is used for registering to the hook. You must not write the code in a method as the callback because a method must have captured this causing the object can not be released. You had better write the code in nested function carefully to avoid the callback becoming closure, just for safety purpose or for reducing unnecessary closure creation.
All in all, you sometimes really need simply write a nested function without being a closure, for a callback or some other purposes.
Without Local or Closure, you would probably write:
Code: Select all
class MouseHook {
__New(Event := unset) {
a:=1
,b:=2
,c:=3
callBack(nCode, wParam, lParam) {
local a:=5
;...
local b:=6
;...
local c:=7
}
cbk:=CallbackCreate(callBack, 'F')
;...
Closure1(){
a:=5
,b:=6
,c:=7
}
}
;...
}
m:=MouseHook()
Code: Select all
class MouseHook {
__New(Event := unset) {
a:=1
,b:=2
,c:=3
callBack(nCode, wParam, lParam) {
local ;use this keyword to avoid it becoming a closure.
a:=5
;...
,b:=6
;...
,c:=7
}
cbk:=CallbackCreate(callBack, 'F')
;...
Closure1(){
a:=5
,b:=6
,c:=7
}
}
;...
}
m:=MouseHook()
Or, with the new keyword closure, you can write:
Code: Select all
class MouseHook {
__New(Event := unset) {
a:=1
,b:=2
,c:=3
callBack(nCode, wParam, lParam) {
a:=5
;...
,b:=6
;...
,c:=7
}
cbk:=CallbackCreate(callBack, 'F')
;...
Closure1(){
closure ;use this keyword to make it become a closure.
a:=5
,b:=6
,c:=7
}
}
;...
}
m:=MouseHook()
With the introduction of the keyword closure, you can even change the V2 language to allow using %String%:= in a closure to modify and capture the value of a variable from an outer function without all the possible outer variables from %String% being captured in advance. It can not do this at present from the new documention.
https lexikos.github.io /v2/docs/Functions.htm#nested Broken Link for safetyNon-static local variables of the outer function cannot be accessed dynamically unless they have been captured.