Allow built-in variables as default function parameters

Propose new features and changes
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Allow built-in variables as default function parameters

22 Dec 2020, 06:54

I just wanted tu define the following function:

Code: Select all

debug(s,line=A_Linenumber)
which should pass the line number of the actual function call to the debug routine.

Got a compiler error stating that this is an illegal default value. Why don't you allow that?
Any expession that can be evaluated at the time of the funtion call could be a default value for a parameter.
User avatar
lmstearn
Posts: 694
Joined: 11 Aug 2016, 02:32
Contact:

Re: Allow built-in variables as default function parameters

22 Dec 2020, 07:41

Would imagine it would be a tricky exercise for any compiler to do something like that, as variables aren't allowed as optional variables, unfortunately. Perhaps passing the variable directly in the caller be a reasonable alternative?

Code: Select all

debug(s,A_Linenumber)
...
...
debug(s,line)
{}
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

22 Dec 2020, 15:18

lmstearn wrote:
22 Dec 2020, 07:41
Perhaps passing the variable directly in the caller be a reasonable alternative?
Of course I can pass the parameter manually. But the idea of default values for parameters is that I can save myself typing them. The compiler can insert them automatically, if they are omitted, it has all necessary information. The code could be built just as if the default parameter has been passed explicitly.

I don't see the reason for this restriction...
TAC109
Posts: 1112
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: Allow built-in variables as default function parameters

22 Dec 2020, 17:09

@braunbaer
The allowable default parameters for a function are defined here. No proper variables of any type may be specified (other than true or false).

What you are requesting would be a major change to AutoHotkey.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

24 Dec 2020, 21:52

I understand that the allowable default parameters are currently very restricted. That is why i am posting this in the subforum "wishlist".

I don't think that it would really be a major change. Suppose you have a function declaration f(x,y:=GloabalDefaultXY). At some point in the code you can write f(a,LocalXY), and at some other point, you can write f(a), and the compiler could treat this just as if there had been written f(a,GloabalDefaultXY). I think this change would be rather simple, maybe even at the level of the code parser. The compiler could allow any valid expression, which could be automatically inserted as parameter while compiling. Even expressions should not be difficult to insert at that position.

And the change would also be 100% backward compatible (at least for previously working scripts).
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: Allow built-in variables as default function parameters

25 Dec 2020, 15:47

braunbaer wrote:
22 Dec 2020, 15:18
Of course I can pass the parameter manually. But the idea of default values for parameters is that I can save myself typing them. The compiler can insert them automatically, if they are omitted, it has all necessary information. The code could be built just as if the default parameter has been passed explicitly.
I don't see the reason for this restriction...
Reading this, not understanding how it would save on typing. This is because a built-in variable can always be included in the body of the function, thus serve the same use as if a default parameter. From a functional programming perspective, I do understand how some purist might want the function to act only on the parameters its been given, but what built-in variables will return is expected and is known. Be that as it may, AutoHotkey's optional parameters usually are good for other use cases, but sometimes we can't have everything. Of course it's up to the developers to decide.

Code: Select all

S := "The script's name is:"
Example1(S, A_ScriptName)
Example2(S)
Return

Example1(S, X)
{
	MsgBox,, Result, % S A_Space X
}

Example2(S)
{
	X := A_ScriptName
	MsgBox,, Result, % S A_Space X
}
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

25 Dec 2020, 16:22

SOTE wrote:
25 Dec 2020, 15:47
Reading this, not understanding how it would save on typing. This is because a built-in variable can always be included in the body of the function, thus serve the same use as if a default parameter.
There is at least one situation where it would save VERY MUCH typing.

I have a function debug(string, linenumber). The function makes some debugging output and a line number of the code should always be included. I would like to declare debug(string, linenumber=A_Linenumber). This would save me writing ",A_Linenumber" everytime I use this function call (and that happens often during debugging). I think that Inside the function, there is no easy way to find ou at which line number the function was called. I use macros to save me some typing, but it still would be easier if I could omit this parameter and get the default everytime automatically.
User avatar
Delta Pythagorean
Posts: 627
Joined: 13 Feb 2017, 13:44
Location: Somewhere in the US
Contact:

Re: Allow built-in variables as default function parameters

25 Dec 2020, 20:27

Technically you can do this already but it's very bad practice and only works for a handful of variables (that I can be bothered to try):

Code: Select all

my_func(file_name = "%A_ScriptName%") {
	return A_ScriptDir . "\" . file_name . ".ahk"
}

MsgBox, % my_func()	; Use default parameter.
MsgBox, % my_func("my_script") ; Use custom parameter.

[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat

SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: Allow built-in variables as default function parameters

26 Dec 2020, 05:28

Delta Pythagorean wrote:
25 Dec 2020, 20:27
Technically you can do this already but it's very bad practice and only works for a handful of variables (that I can be bothered to try):

Code: Select all

my_func(file_name = "%A_ScriptName%") 
{
	return A_ScriptDir . "\" . file_name . 	".ahk"
}
Good catch Delta, I overlooked the double-dereference and forced expression type thingy. Consequently, the below works too.
I don't necessarily think that doing such is bad practice, if it works and solves the programmer's issue. It's a viable capability of the scripting language.

Code: Select all

S := "The script's name is:"
Example3(S)
Y := Example4(S)
MsgBox % Y
Return

Example3(S, X = "A_ScriptName")
{
	MsgBox,, Result, % S A_Space %X%
}

Example4(S, X = "A_ScriptName")
{
	Y := % S A_Space %X%
	Return Y
}
just me
Posts: 9458
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Allow built-in variables as default function parameters

26 Dec 2020, 06:55

braunbaer wrote:... I would like to declare debug(string, linenumber=A_Linenumber). This would save me writing ",A_Linenumber" everytime I use this function call (and that happens often during debugging). ...

Code: Select all

debug(string, linenumber := A_Linenumber) {
   ...
}
If this would work, I guess A_LineNumber would contain the line number of the function's header
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

26 Dec 2020, 20:39

Well, in the current AHK implementation it doesn't work.
But of course the default value should be calculated at the time of the function call, not at compile time.
The AHK compiler should do what a C compiler does when it encounters a macro.
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

28 Dec 2020, 01:32

Delta Pythagorean wrote:
25 Dec 2020, 20:27
Technically you can do this already but it's very bad practice and only works for a handful of variables (that I can be bothered to try):

Code: Select all

my_func(file_name = "%A_ScriptName%") {
	return A_ScriptDir . "\" . file_name . ".ahk"
}

MsgBox, % my_func()	; Use default parameter.
MsgBox, % my_func("my_script") ; Use custom parameter.
That's an interesting idea, but it does not solve my problem. Because of course A_linenumber, when passed as string, will only be evaluated in the body of the function and will not contain the linenumber of the line where the function is called
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: Allow built-in variables as default function parameters

28 Dec 2020, 17:42

braunbaer wrote:
28 Dec 2020, 01:32
That's an interesting idea, but it does not solve my problem. Because of course A_linenumber, when passed as string, will only be evaluated in the body of the function and will not contain the linenumber of the line where the function is called
True, A_linenumber in particular is a tough one. You could save a few key strokes by doing below, though it's not quite what you want.

Code: Select all

X :=  "A_Linenumber"
Test =
(
This
Is 
Just 
Filler
)
MsgBox % Example5(Test, %X%)
Return

Example5(S, Y :="")
{
	Z := % S "`n" Y
	Return Z
}
Last edited by SOTE on 10 Jan 2021, 23:02, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Allow built-in variables as default function parameters

09 Jan 2021, 09:45

If parameters could have arbitrary expressions as their default value, I think it would be more useful if the expression was evaluated in function scope rather than call site. Consider,

Code: Select all

box(x, y := x)
For the particular case of A_LineNumber, you can use the Exception() function,
Exception wrote: If What is omitted, it defaults to the name of the current function. Otherwise it can be a string or a negative offset from the top of the call stack. For example, a value of -1 sets Exception.What to the current function, and Exception.Line and Exception.File to the line and file which called it.
Example,

Code: Select all

f(l:=""){
	if (l=="")
		l:=exception("",-1).line
	msgbox % l 
}
f()
f()
Cheers.
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

10 Jan 2021, 15:39

Thank you, that solves my problem in a more elgant way. I had a solution thanks to BoBo
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=85332&p=375106#p375106
which involved accessing of the listing of the last executed lines of the main AHK window

Maybe it should be added somewhere in the documentation that this way of calling "exception" should better not be used directly as function parameter, because it may produce garbage (it works sometimes, but sometimes it doesn't) :

Code: Select all

l:=exception("",-1).line
outputtodebugfile("The error occured here,l)"
correctly passes the line number of the call of the current function to outputtodebugfile, while if you write

Code: Select all

outputtodebugfile("The error occured here",exception("",-1).line)
a more or less random number may be passed instead of the line of the call of the current function, presumably dependent on whether the call stack has already been manipulated

It would still be nice if such an extended use of default values was possible, but the use of A_linenuber is the only tricky situation that you can't easily get around by other means
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: Allow built-in variables as default function parameters

10 Jan 2021, 23:05

Helgef wrote:
09 Jan 2021, 09:45
If parameters could have arbitrary expressions as their default value, I think it would be more useful if the expression was evaluated in function scope rather than call site...
For the particular case of A_LineNumber, you can use the Exception() function...
Cheers.
That's another good one to know, thanks again. Good to learn something new every day.
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: Allow built-in variables as default function parameters

30 Jan 2021, 04:02

braunbaer wrote:
10 Jan 2021, 15:39
Maybe it should be added somewhere in the documentation that this way of calling "exception" should better not be used directly as function parameter, because it may produce garbage (it works sometimes, but sometimes it doesn't) :
That would obviously not be intended behaviour, and so should not be added to the documentation.

If you can come up with a (preferably simple) standalone example which reproduces the behaviour, please post it in Bug Reports.

If I write

Code: Select all

outputtodebugfile("The error occured here",exception("",-1).line)
outputtodebugfile(a,s){
    MsgBox % s
}
I get 1.
braunbaer
Posts: 478
Joined: 22 Feb 2016, 10:49

Re: Allow built-in variables as default function parameters

30 Jan 2021, 04:55

I had the problem with very strange line numbers, not really reproduceable, and the problem disappeared after I moved all exception calls out of the function and assigned the value to a variable. I'll try to reproduce the error when I find the time to do so, but that promises to be rather time consuming. In simple examples, It always seems to work.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Allow built-in variables as default function parameters

30 Jan 2021, 09:27

Would this possibly be due to how AHK “compiles” the code in the more complex scenarios? How the reported line number doesn’t actually match up with the actual line number
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: Allow built-in variables as default function parameters

30 Jan 2021, 19:22

With continuation lines and continuation sections, the line number of the first physical line is used, which is correct but might not always meet expectations. When compiling with Ahk2Exe, the line numbers relate to the preprocessed code embedded in the exe, not the original source file(s). In all other cases the line number should be correct, as far as I can recall.

By the way @braunbaer, I hope you realize you do not need to pass the line number every time you call the debug function; the debug function can retrieve the line number of its caller, its caller's caller, and so on, though it is limited to function calls in the current pseudo-thread. (With outputtodebugfile("The error occured here",exception("",-1).line) being similar to debug(s,A_Linenumber), I suppose you would be using similar lines across the script, rather than there being just one call to the former inside some other debug function.)

Return to “Wish List”

Who is online

Users browsing this forum: No registered users and 51 guests