Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

Propose new features and changes
Helgef
Posts: 4018
Joined: 17 Jul 2016, 01:02
Contact:

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

22 May 2019, 11:53

Hi.
why is it important to know whether the thing im calling is a callback or a hardcoded function
Because knowing what is what generally makes writing and understand code easier.
lexikos made more points :arrow: in this post.
thats exactly it
I do not think that is sufficient reason to scrap dynamic calls being visually distinguishable from non-dynamic calls, it would only be sufficient reason for changing the syntax imo.

Cheers.
User avatar
nnnik
Posts: 4283
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

22 May 2019, 13:05

its only intuitive if uve spent most of ur time writing AHK Basic scripts
You never used %% to call functions in v1?
Recommends AHK Studio
swagfag
Posts: 3006
Joined: 11 Jan 2017, 17:59

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

22 May 2019, 14:56

no, i primarily use .Call()
the only place where i ever used %% was #Include %A_LineFile%.... i think cause its the only thing it supports
User avatar
nnnik
Posts: 4283
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

23 May 2019, 01:34

Then you're doing it wrong. In most cases %% is preferable over .call().
Recommends AHK Studio
Helgef
Posts: 4018
Joined: 17 Jul 2016, 01:02
Contact:

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

23 May 2019, 02:13

As long as you know what you are doing, using .call is perfectly fine imo. I think it looks better too, even if it requires more typing.
User avatar
nnnik
Posts: 4283
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

23 May 2019, 04:58

%% is less restrictive and should be the standard.
Recommends AHK Studio
swagfag
Posts: 3006
Joined: 11 Jan 2017, 17:59

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

23 May 2019, 09:34

the only thing %% allows u to do that .Call() does not is call a function if all u were given was its name, a string.
i cant recollect ever having to do that, but even if i had to, id have probably just written Func(funcName).Call() anyway
lexikos
Posts: 6653
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

23 May 2019, 18:50

The array of parameters may contain named items when calling a user-defined function; in any other case, named items are not supported.
Source: Functions - Definition & Usage | AutoHotkey

Code: Select all

Random n, 1, 2
f := Func("Fun" n)
%f%({first: 1, third: 3, second: 2}*)
; f.Call({first: 1, third: 3, second: 2}*) ; Fails silently on v1.
Fun1(first, second, third) {
    MsgBox % first ", " second ", " third
}
Fun2(first, second, third) {
    MsgBox % first "; " second "; " third
}
Func.Call() is not a user-defined function, therefore you cannot use named items.

There is also less overhead for %%, partly because it does not need to push the word "Call" onto the stack. Currently all method calls pass through an internal "built-in" function, whereas dynamic function calls are evaluated more directly. (This also means that you cannot use named items with calls to user-defined methods.)
swagfag
Posts: 3006
Joined: 11 Jan 2017, 17:59

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

25 May 2019, 10:11

right then, in that case @nnnik is correct

Code: Select all

global n := 100000

out := string_lookup_percent()
out .= string_lookup_call()
out .= func_reference_percent()
out .= func_reference_call()

MsgBox out

/*
87814	string_lookup_percent
135555	string_lookup_call
72145	func_reference_percent
94404	func_reference_call
*/

f() {
}

string_lookup_percent() {
	fn := 'f'
	start := qpc()

	Loop n
		%fn%()

	return (qpc() - start) '`t' A_ThisFunc '`n'
}

string_lookup_call() {
	fn := 'f'
	start := qpc()

	Loop n
		Func(fn).Call()

	return (qpc() - start) '`t' A_ThisFunc '`n'
}

func_reference_percent() {
	fn := Func('f')
	start := qpc()

	Loop n
		%fn%()

	return (qpc() - start) '`t' A_ThisFunc '`n'
}

func_reference_call() {
	fn := Func('f')
	start := qpc()

	Loop n
		fn.Call()

	return (qpc() - start) '`t' A_ThisFunc '`n'
}

qpc() {
	DllCall('QueryPerformanceCounter', 'Int64*', c) 
	return c
}
so to recap, %% pros:
• can call strings without having to Func() beforehand
• marginally faster
• supports named parameters, a feature im not even sure many people are aware exists

cons:
• ugly as all hell

tough choice
User avatar
nnnik
Posts: 4283
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

26 May 2019, 17:05

.call also has different behaviour when it comes to objects.

Code: Select all

class Functor {
	
	static info := "Functor class"
	info2 := "Functor instance"
	
	__call(functionName, parameter) {
		global instance
		Msgbox % "this pointer:`t`t" &this . "`nfunctor instance pointer:`t" . &instance . "`ncalled method:`t`t" . functionName . "`nparameter passed:`t`t" . parameter
		if ObjhasKey(this, "call") {
			target := this.call
			%target%()
		}
			
	}
}


instance := new Functor()
%instance%("Hello World")
instance.call("Hello World")
instance.call := "callMe"
%instance%("Hello World")
instance.call("Hello World")

callMe() {
	Msgbox success
}
Of course there is a reccomendation in the docs that you should use a specific pattern that is similar to what I do here.
However I do not think that even half of the people using these techniques know of that pattern.

This is not a matter of preference. object.call() is not %object%() the 2 are neither interchangeable nor equivalent.
%%() follows most of the established standards AHK has to offer. .call is an alternative that imo does more harm than good since its incompatible with a few aspects of the language.
.call is not a valid option for the general use of calling callables.

Use an objectively worse alternative due to personal bias or grow up and do the right thing - your choice.
Recommends AHK Studio
lexikos
Posts: 6653
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

26 May 2019, 22:09

For reference, in v2...
User-defined function objects must define a Call method containing the implementation of the "function".

Code: Select all

class YourClassName {
    Call(a, b) {  ; Declare parameters as needed, or an array*.
        ;...
        return c
    }
    ;...
}
In v2, the method name passed to __call by %instance%() is "Call", not "".

In the next v2 alpha,
  • __call will be bypassed for %instance%(), just as instance[] bypasses __get/__set and invokes __item.
  • Meta-functions will not be called if the method/property is defined anywhere, even in a base object, so Call would take precedence over __call if defined, even for instance.call().
  • Assigning a property, such as instance.call := "callMe", will do nothing other than assign a property. Methods must be defined explicitly (see Object.ahk), and must be objects, not names.
swagfag
Posts: 3006
Joined: 11 Jan 2017, 17:59

Re: Callable Func, BoundFunc, lambdas, custom user objs(ie no %%)

27 May 2019, 15:56

@nnnik great case for why one should prefer %% over .Call()... in v1(it blows up in v2, instantly).

regardless, in light of recent developments, %% spam is shaping up to become even more pervasive:
Added support for obj.%name% and similar.
Do not use x[y] to access properties or methods. Use x.%y% instead.
i might just have to let this one go

Return to “Wish List”

Who is online

Users browsing this forum: No registered users and 8 guests