Make bound funcs consistent with func objects

Propose new features and changes
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Make bound funcs consistent with func objects

26 Jun 2017, 13:36

I know how things are handled here so I will start in the ask for help forum before going for the bug section.
So does anybody have a valid reason as to why isfunc( boundfunc ) returns 0?
Recommends AHK Studio
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: boundfuncs and isFunc

26 Jun 2017, 15:25

Aren't they objects?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: boundfuncs and isFunc

26 Jun 2017, 15:27

boundfunc objects are not function names nor function references / func object, hence, as per the documentation,
it returns 0.
;)
What would you expect isFunc(boundFunc) to return? The number of parameters for the underlying function, or the number of parameters bound or left unbound? I do not think it is obvious.
I think it would be more appropriate to have a isBoundFunc(.) function, or type(.). And additional properties/methods of the bound func. Like,

Code: Select all

boundParamArray:=boundFunc.getBoundParams() ; You have to use your imagination here
funcName:=boundFunc.getFuncName()
; ...
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: boundfuncs and isFunc

26 Jun 2017, 22:28

A BoundFunc object is not a function. A function has a name, formally defined parameters and a body (in C++ or ahk). A BoundFunc object is the result of binding a function or method: it has an array of parameter values, a target object (such as a Func) and a method name (such as "Call").

Both are callable, but not all callable things are "functions".
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: boundfuncs and isFunc

27 Jun 2017, 04:18

just me wrote:Aren't they objects?
Im not asking where in the documentation it is stated that they return 0 for isFunc I'm asking for the considerationthat caused this behaviour.
Helgef wrote:boundfunc objects are not function names nor function references / func object, hence, as per the documentation,
it returns 0.
;)
What would you expect isFunc(boundFunc) to return? The number of parameters for the underlying function, or the number of parameters bound or left unbound? I do not think it is obvious.
I think it would be more appropriate to have a isBoundFunc(.) function, or type(.). And additional properties/methods of the bound func. Like,

Code: Select all

boundParamArray:=boundFunc.getBoundParams() ; You have to use your imagination here
funcName:=boundFunc.getFuncName()
; ...
Once again the same thing I said to just me applies to you too. You also seem to misunderstand my intentions. What I want is consistency with the FuncObject.
And it should be pretty obvious that, it returns the number of parameters left unbound ( "This function returns one plus the minimum number of parameters" ).
lexikos wrote:A BoundFunc object is not a function. A function has a name, formally defined parameters and a body (in C++ or ahk). A BoundFunc object is the result of binding a function or method: it has an array of parameter values, a target object (such as a Func) and a method name (such as "Call").

Both are callable, but not all callable things are "functions".
All things considered I think that - even if by that definition BoundFuncs were not functions - practical considerations overrule this definition
BoundFuncs define themselves formally against a function object ( which apparently is a function ) and derives it's name and it's code from that. The parameters are defined in difference towards the func object it defines itself against. That means it defines name, code and parameters - a function by your definition.
You have correctly figured that I used isFunc more like isCalleable. I think that if you were to ask most people would reply that they use it in a similar fashion after all it's probably the most used use case for isFunc.
i think it is more important to differentiate between calleables and non calleables then between functions and not functions according to formal definition.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: boundfuncs and isFunc

27 Jun 2017, 11:57

Hi nnnik.
Your original question can be interpreted in two ways, I didn't think for a second you didn't understand the parameter definition of the function, (hence the wink ;)) , my answer was simply a direct answer to the question. The second part of my reply was in response to what I thought you really asked, i.e., why isFunc(boundFunc) by design returns 0. I ask you what you want it to return because I wonder if you have really thought about it, and why isFunc should return anything but 0 for a boundfunc. I guess you didn't, because,
You have correctly figured that I used isFunc more like isCalleable
You forget that isFunc can be used for identifying a func object, eg

Code: Select all

if isobject(f) && isfunc(f)
	; use f  as func object
Adding boundFuncs ruins that. Hence, isboundFunc plus more methods/properties of boundFuncs would be much more consistent w.r.t. func objects. Or even, why couldn't boundFuncs just be func objects with bound parameters? :crazy:

A isCallable function would be nice too. :thumbup:

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

Re: boundfuncs and isFunc

27 Jun 2017, 13:27

Helgef wrote:Hi nnnik.
Your original question can be interpreted in two ways, I didn't think for a second you didn't understand the parameter definition of the function, (hence the wink ;)) , my answer was simply a direct answer to the question. The second part of my reply was in response to what I thought you really asked, i.e., why isFunc(boundFunc) by design returns 0. I ask you what you want it to return because I wonder if you have really thought about it, and why isFunc should return anything but 0 for a boundfunc. I guess you didn't, because,
You have correctly figured that I used isFunc more like isCalleable
You forget that isFunc can be used for identifying a func object, eg

Code: Select all

if isobject(f) && isfunc(f)
	; use f  as func object
Adding boundFuncs ruins that. Hence, isboundFunc plus more methods/properties of boundFuncs would be much more consistent w.r.t. func objects. Or even, why couldn't boundFuncs just be func objects with bound parameters? :crazy:

A isCallable function would be nice too. :thumbup:

Cheers.
I didnt forget that. I just don't see a single good reason why a person ever wants to differentiate between a boundfunc and a func object. I also did think about what isFunc should return instead of 0. ( it should just return true). The rest doesn't matter to me.
Also it seems you didn't fully understand my last post. If I want consistency with a func object then I want the minimum parameters that are needed to call the bound func.
Recommends AHK Studio
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 02:31

Func Object wrote:A reference to a Func object is also known as a function reference. To retrieve a function reference, use the Func function ...
BoundFunc Object wrote:Acts like a function, but just passes predefined parameters to another function.
In other words, a BoundFunc object is not a (direct) function reference. So why should IsFunc() return True? How would you use such a return value?
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: boundfuncs and isFunc

28 Jun 2017, 03:44

nnnik wrote:BoundFuncs define themselves formally against a function object ( which apparently is a function )
No. As I said, each BoundFunc has a target object and method name.

Actually, it has a target object, method name and internal flags.

Func.Bind() returns a BoundFunc which binds a function object to internal flags equivalent to the method name "Call".

ObjBindMethod() returns a BoundFunc which binds any object to the given method name and parameters. It doesn't have to be a function object, and usually isn't. It could be a function object with a method name other than "Call".

IsFunc is not intended to tell you whether the object can be called. It tells you whether the input is a function. It was originally added as a direct equivalent of IsLabel for functions, where %funcNameVar%() was analogous to gosub %labelNameVar%.
i think it is more important to differentiate between calleables and non calleables then between functions and not functions according to formal definition.
IsFunc has both an obvious meaning ("is function") and clearly defined behaviour ("Returns a non-zero number if the specified function exists in the script"). Under your proposal, IsFunc would return true for some things which are not functions, and false for some things which are callable. It's halfway between semantically correct and what you actually want, which makes it incorrect and misleading.

I have been thinking that v2 will replace IsFunc(o) with type(o) = "Func" and o.HasMethod("Call") will fill the need for "is callable".
I just don't see a single good reason why a person ever wants to differentiate between a boundfunc and a func object.
You don't see the reasons because you are looking the other way. ;)

Hypothetically, Func and BoundFunc could support the same methods and properties (or some could be eliminated so that both types have the same interface). But they don't. BoundFunc only supports Call. If you only want to know whether you can call it, "is this a function?" is the wrong question.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: boundfuncs and isFunc

28 Jun 2017, 04:51

just me wrote:
Func Object wrote:A reference to a Func object is also known as a function reference. To retrieve a function reference, use the Func function ...
BoundFunc Object wrote:Acts like a function, but just passes predefined parameters to another function.
In other words, a BoundFunc object is not a (direct) function reference. So why should IsFunc() return True? How would you use such a return value?
lexikos wrote:
nnnik wrote:BoundFuncs define themselves formally against a function object ( which apparently is a function )
No. As I said, each BoundFunc has a target object and method name.

Actually, it has a target object, method name and internal flags.

Func.Bind() returns a BoundFunc which binds a function object to internal flags equivalent to the method name "Call".

ObjBindMethod() returns a BoundFunc which binds any object to the given method name and parameters. It doesn't have to be a function object, and usually isn't. It could be a function object with a method name other than "Call".

IsFunc is not intended to tell you whether the object can be called. It tells you whether the input is a function. It was originally added as a direct equivalent of IsLabel for functions, where %funcNameVar%() was analogous to gosub %labelNameVar%.
I just don't see a single good reason why a person ever wants to differentiate between a boundfunc and a func object.
You don't see the reasons because you are looking the other way. ;)

Hypothetically, Func and BoundFunc could support the same methods and properties (or some could be eliminated so that both types have the same interface). But they don't. BoundFunc only supports Call. If you only want to know whether you can call it, "is this a function?" is the wrong question.
You can't argue with dosumentation and implementation when I want exactly that to change.
Lexikos you once said that it doesn't make any sense to look into what the script writers are doing. At first I really belived that. But now I think it is foolish not to do that. A language that doesn't look at it's users will never be useable without constant looks into the documentation. And to be honest I'm growing very tired of that. I don't think I will use v2 at all so that doesn't really matter to me. v1 has shown me that you are pretty much incapable of delivering syntax that does what is looks like or is easy to remember ( or not full of quirks ). I'll simply wait till someone else takes over.
Recommends AHK Studio
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 05:17

Topic: Make isFunc return 1 for bound funcs

My questions: So why should IsFunc() return True? How would you use such a return value?

Your answer: :?:
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Make isFunc return true for bound funcs

28 Jun 2017, 06:28

I've answered it several times before.
  • Consistency:I want the bound func object to be consistent with the func object
  • Intuitivity:Everyone I asked expected isFunc to return true for bound funcs
  • Compatability:Scripts that work with isFunc mostly use isFunc to determine, whether it is safe to call it with %var%() or not. BoundFuncs don't work with that and are therefore incompatible with old scripts.
  • Usefulness:I think that the way a function is used determs the way it should develop. I don't think it is used at all to find out the amount of parameters of the function - at least I don't think I have seen it being used that way. Also I don't think there should be any difference between bound funcs and func objects since most people use them synonimous.
Recommends AHK Studio
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: boundfuncs and isFunc

28 Jun 2017, 07:33

nnnik wrote:You can't argue with documentation and implementation when I want exactly that to change.
Lexikos you once said that it doesn't make any sense to look into what the script writers are doing. At first I really belived that. But now I think it is foolish not to do that. A language that doesn't look at it's users will never be useable without constant looks into the documentation. And to be honest I'm growing very tired of that. I don't think I will use v2 at all so that doesn't really matter to me. v1 has shown me that you are pretty much incapable of delivering syntax that does what is looks like or is easy to remember ( or not full of quirks ). I'll simply wait till someone else takes over.
Ok maybe I've been too harsh here. From my point of view you added syntax that was incompatible with old syntax. That itself is not a problem. Especially in languages like AutoHotkey it happens on a regular basis that things need to be rewritten. However I tend to avoid syntax like that. isFunc seemed like it would be able to stay consistent. bound Funcs are extremly useful for OOP with AutoHotkey. It would be nice if I don't have to rewrite a lot of scripts because of this new feature - especially it is a very simple solution. I doubt that either just me or Helgef use bound funcs on a regular basis so I doubt they understand the problem that I face.
I look forward to what you produce in v2.
Recommends AHK Studio
User avatar
runie
Posts: 304
Joined: 03 May 2014, 14:50
Contact:

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 08:10

I use boundfuncs extremely often and were honestly a bit surprised by how IsFunc handles it. In my eyes if a variable represents a function and can be called via .Call() then it should be considered a function by IsFunc, at least in my opinion.

Another solution might be adding IsCallable. That would however render IsFunc obsolete to me.
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 08:53

nnnik wrote:isFunc seemed like it would be able to stay consistent. bound Funcs are extremly useful for OOP with AutoHotkey. It would be nice if I don't have to rewrite a lot of scripts because of this new feature - especially it is a very simple solution.
I don't understand your reasoning.

BoundFunc objects were implemented more than two years ago (1.1.20.00 - March 8, 2015). IsFunc() hasn't been changed since Func objects were introduced with 1.1.00.00 - May 1, 2011.

Shortly after BoundFunc objects were implemented I changed some of my scripts moving external message handler functions into the belonging classes using ObjBindMethod(). But admittedly, I never had the need to check whether a BoundFunc object is 'callable'. I noticed that IsFunc() returns 0 for them some time ago, though.

It seems that you want to add BoundFunc objects to existing scripts which are using IsFunc() to determine whether a passed value represents a callable function. If so, it should be easy to replace IsFunc() with an own function, e.g.

Current AHK v1.1:

Code: Select all

IsFuncOrBoundFunc(P) { ; v1.1
   ; Extracted from Type() for v1 by Coco (as far as I remember)
   Static BF := NumGet(&(_ := Func("IsFuncOrBoundFunc").Bind()), "Ptr")
   Return (IsFunc(P) || (IsObject(P) && (NumGet(&P, "Ptr") = BF)))
}
Current AHK v2:

Code: Select all

IsFuncOrBoundFunc(P) { ; v2
   Static Valid := {BoundFunc: "", Func: ""} ; current alpha, might be changed
   Return Valid.HasKey(Type(P))
}
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 10:21

Nah for AutoHotkey v1 I will just put a file named isFunc.ahk in my standard library and redefine isFunc there.
No Editing required - might break external scripts but tbh I don't care. And if that doesn't work I'll fork my own version of AutoHotkey.
Also I do not understand why you keep arguing with me just me. It seems like you've never needed isFunc for anything before.
Recommends AHK Studio
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 11:03

I'm just wondering why you want to change a built-in function to support a feature which is available for more than two years. "I want to use a feature available for more than two years but I don't want to change my existing scripts, so AHK must be changed!" is a somewhat strange argument for me.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 12:14

just me wrote:
nnnik wrote:isFunc seemed like it would be able to stay consistent. bound Funcs are extremly useful for OOP with AutoHotkey. It would be nice if I don't have to rewrite a lot of scripts because of this new feature - especially it is a very simple solution.
I don't understand your reasoning.

BoundFunc objects were implemented more than two years ago (1.1.20.00 - March 8, 2015). IsFunc() hasn't been changed since Func objects were introduced with 1.1.00.00 - May 1, 2011.
Actually, now it makes me understand the reasoning ;). From the old user's perspective, nnnik, adding boundFuncs broke the way nnnik used isFunc, but from the new user's perspective, mine, not knowing the background of the language, your suggestion doesn't make sense, since for me, using isFunc(.) as isCallable(.) was either not an option or a mistake. The issue should have been raised when bound funcs where added, I think the best solution would have been not adding bound funcs, instead func objects should have been extended to being able to have bound params and a method / property to retrieve those params. That being said, I don't know anything about actual implementation so what I think might be completely irrelevant.
I just don't see a single good reason why a person ever wants to differentiate between a boundfunc and a func object.
I showed you in the post you quoted, I want to use func object methods / properties if applicable, I can't do that if it is a bound func. Again,

Code: Select all

if isobject(f) && isfunc(f)
	; use f as func object
People do all kinds of things neither one of us can think of, hence, I just don't see a single good reason why a person ever wants to use the arguement, I just don't see a single good reason why a person ever wants to... :P
Finally, I wonder how you deduce that I do not use bound funcs (on a regular basis)? I searched my ahk folder for bind and objbindmethod, it gave ~3400 hits, although, it includes some of your code :lol:

Please note that I am not arguing with you in a hostile matter here, you are entitled to your wish, and I think you highlight a problem with the language which needs to be considered, but I do not think isFunc is part of the solution. I see a better future in v2.

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

Re: Make isFunc return 1 for bound funcs

28 Jun 2017, 12:33

I should really have raised the matter when Lexikos implemented it, but I just didn't notice until now.
I guess a fork is the only way now.
Recommends AHK Studio
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: boundfuncs and isFunc

29 Jun 2017, 03:08

nnnik wrote:You can't argue with dosumentation and implementation when I want exactly that to change.
I can and will argue whatever I want, tyvm.

It's not just about the current wording of the documentation, but about the behaviour guaranteed by the documentation and retaining compatibility with scripts written with that in mind. Also, you failed to address my other points.
Lexikos you once said that it doesn't make any sense to look into what the script writers are doing.
I don't even know what you mean, so I have some doubt that you correctly understood whatever it was I actually said.
Compatability:Scripts that work with isFunc mostly use isFunc to determine, whether it is safe to call it with %var%() or not.
By your own admittance, that isn't the only use of IsFunc. It is not acceptable to break scripts that rely on previously documented behaviour just because they're in the minority.
I don't think it is used at all to find out the amount of parameters of the function
My original implementation returned only 0 or 1. Chris changed it that so that scripts could verify that the function accepts the right number of parameters (because "can call it with x parameters" is more useful to know than "it is a function" if you're always going to pass x parameters). This was obviously before objects or Func.MinParams.
Nah for AutoHotkey v1 I will just put a file named isFunc.ahk in my standard library and redefine isFunc there.
No Editing required
Go ahead. :HeHe:
Spoiler

Return to “Wish List”

Who is online

Users browsing this forum: No registered users and 21 guests