Page 1 of 3

v2-thoughts Discussion

Posted: 15 Feb 2014, 13:41
by fincs
Discuss v2-thoughts here in an organized way; I propose this template:

Code: Select all

[list]
[*][b]Commands with subcommands[/b]:
[*][b]Other Commands[/b]:
[*][b]Errors in math ops[/b]:
[*][b]Errors in math funcs[/b]:
[*][b]Errors in COM[/b]:
[*][b]Errors in RegEx funcs[/b]:
[*][b]Objects[/b]:
[*][b]Classes[/b]:
[*][b]Misc[/b]:
[/list]
---------------------------------

My opinions:
  • Commands with subcommands: Yes to everything except merging Gui with non-Gui commands. The GUI API should be separate, and preferably it should be redesigned to follow OOP (volunteers?)
  • Other Commands: Rename MouseClickDrag to MouseDrag. Remove MouseClick. Expand Click with Speed option.
  • Errors in math ops: Treat non-numerics as 0 and optionally provide warning.
  • Errors in math funcs: Throw exceptions in all cases.
  • Errors in COM: Throw exception on COM error in all cases (except for E_NOINTERFACE in ComObjQuery)
  • Errors in RegEx funcs: Throw exception on PCRE failure.
  • Objects: Introduce dedicated Array type. Keep meta-functions. Do not remove Integer keys, as that would significantly decrease performance in sparsely populated arrays (i.e. NOT sequential arrays, which would be covered by the Array type) by adding unnecessary string conversions. Yes to all proposed Object methods and properties.
  • Classes: Make base a reserved in class methods. Add partial class support: partial class Whatever. Replace default base object with Value, String, Integer, Float and Object classes.
  • Misc: Yes to proposed address-of operator change, and to VarSetCapacity() returning 8 for variables containing integers.
Pre-a046 opinions

Re: v2-thoughts Discussion

Posted: 16 Feb 2014, 05:16
by just me
My opinions:
  • Errors in math ops:
    Should throw an exception. Empty variables contain empty strings, which never should be treated as 0.
  • Errors in math funcs:
    Same as above.
  • Classes:
    Make base a reserved word in classes. So the following will set the base for Dummy:

    Code: Select all

    Class Dummy {
       ...
       ...
       Class Base {
          ...
          ...
       }
    }
    
  • Settings:
    Maybe changing of such settings could be treated as local when used in functions?

Re: v2-thoughts Discussion

Posted: 16 Feb 2014, 05:36
by vasili111
I think AutoHotkey v2 should more focus on improvements than on compatibility with old code. Focus on compatibility very often brings unnecessary complexity.
I think that AutoHotkey v2 should use ether command syntax for calling commands or function syntax, but not both. I think function syntax is preferable.
I also like the idea to produce "NaN" value in invalid math operations. I think production of empty string is not right. Also to asume that empty space is 0 is not right.
I also like the idea to have dedicated array type which is not object type.

Re: v2-thoughts Discussion

Posted: 16 Feb 2014, 06:08
by fincs
lexikos wrote:There are two mutually-exclusive possibilities presented under the Standard Library heading. You can't have everything.
Oh really? You could both remove the File*Shortcut functions and replace them with a scripted function that returns a ShellLinkObject. Portability is a non-issue as the compiler can be made to output the preprocessed/bundled script (and this is already implemented in the Preview version of Ahk2Exe). A special mode that doesn't remove whitespace/comments/etc can be added if readability is an issue.
lexikos wrote:What is your view on reserving these names for this purpose? I am against it.
Ok, in that case they could have an A_ prefix, that is, A_Value, A_String and so on.

Re: v2-thoughts Discussion

Posted: 16 Feb 2014, 06:45
by lexikos
just me wrote:So the following will set the base for Dummy:
Those are two completely separate issues. The point about the base keyword was specifically about base.method(), not this.base nor any other context. What you want is for class base to behave similarly to this.base := .... I will consider it.
just me wrote:Maybe changing of such settings could be treated as local when used in functions?[/list]
I think the cost would be too high. As a workaround, you can create an object which restores the settings when it is destroyed, then store that object in a local variable.
fincs wrote:Oh really?
Yes. Removing the two commands completely, and replacing the two commands with a built-in function are mutually exclusive possibilities. Perhaps I was too vague.
fincs wrote:Portability is a non-issue as the compiler ...
A portable compiled script is a completely different thing to AutoHotkey itself being portable.

Re: v2-thoughts Discussion

Posted: 17 Feb 2014, 01:15
by just me
lexikos wrote:
just me wrote:Maybe changing of such settings could be treated as local when used in functions?[/list]
I think the cost would be too high. As a workaround, you can create an object which restores the settings when it is destroyed, then store that object in a local variable.
One of my thoughts for v2 is to make all of the built-in 'A_' variables to be properties of one super-global object named AHK (or something like that); e.g. AHK.WorkingDir. Command line parameters could be stored in this object too as AHK.Args.

Re: v2-thoughts Discussion

Posted: 17 Feb 2014, 04:31
by lexikos
That would add overhead and has no apparent purpose.

Re: v2-thoughts Discussion

Posted: 17 Feb 2014, 12:06
by tank
lexikos wrote:That would add overhead and has no apparent purpose.
I might add its a little programmer centric as well. objects are in general difficult enough for non programmers to grasp lets not do things just for the sake of oop

Re: v2-thoughts Discussion

Posted: 18 Feb 2014, 01:20
by just me
Apparently it would reduce the number of reserved names in the global namespace from 100+ to 1.
Apparently (for me) it would be more adequate for a language supporting objects to use object syntax instead of 100+ single variables.
Apparently it would be a built-in 'object' which doesn't have to follow common object design and behaviour mandatory, so the overhead would depend on the implementation. In the simplest case it could be treated as 'syntax sugar', changing the special handling of A_ variables to use AHK. instead.

Them be my thoughts. ;)

Re: v2-thoughts Discussion

Posted: 18 Feb 2014, 02:55
by lexikos
So reserve 100+ names beginning with "AHK." instead of 100+ names beginning with "A_"? Like I said, it serves no real purpose.

I'm not going to change anything to use object syntax just because we have it. There has to be some real justification, like added convenience or flexibility. 100+ single variables within a global object is no better than 100+ single global variables. If it's just syntax sugar, there can't possibly be any justification; it's just lengthening the naming prefix from "A_" to "AHK.".

Runtime overhead could be avoided, true, but the cost would be more compile time overhead. There's also development-time overhead and the overhead of users learning the new syntax.

Re: v2-thoughts Discussion

Posted: 18 Feb 2014, 05:32
by Zelio
Why not, it can be very elegant.

But in priority I prefer a second alternative shortcut of a_index with a_i than a long ahk.index
And to rename errorlevel to a_lasterror or anything more appropriate
And to rename args to a_scriptargs or anything more appropriate
And to have a_clipboard and a_clipboardall for convenience

Re: v2-thoughts Discussion

Posted: 19 Feb 2014, 02:04
by lexikos
Zelio wrote:Why not,
All of the reasons I mentioned.
it can be very elegant.
I strongly disagree.

Renaming ErrorLevel: I think there isn't anything more appropriate. A_LastError is already taken - it contains the last Win32 error code for certain commands/functions.
Renaming Args: I'll consider it, but Args isn't a built-in variable; it's just a global variable which is set on startup.
Renaming Clipboard: I'm not particularly against it (as it would be more consistent), except that it is less convenient than omitting the A_ prefix. I wonder what you mean by "for convenience".

Re: v2-thoughts Discussion

Posted: 19 Feb 2014, 11:29
by Zelio
Yes, I think you understood me (sorry for my poor english), homogeneous concept (a_args, a_errorlevel, a_clipboard, a_clipboardall) like a visual tag.

Still about built-in variable I wonder if we can have a serious alternative of a_index, I mean somethings like for get and set iteration of whatever loops.
Currently, Autohotkey have not a oneline shortcut for (i:=1, i<10, i++) { }, we can get and set a_index, it is a cool shorcut, but more usefull should be (pseudo code, whatever name) a_iteration[currentloop] = a_index[currentloop] = a_loop[n] = a_loop[1] = a_loop1 = a_i[1] = a_index.

It seems that the old version already store loops informations somewhere (less work to implement, I guess)

Code: Select all

test:
loop
{
			msgbox loop #3 index %a_index%
	loop
	{
			msgbox loop #2 index %a_index%
		loop
		{
			msgbox loop #1 index %a_index%
			a_index := a_index + 9
;			break test
;			break 3
;			break 2
;			break 1
		}
		return
	}
}
return

esc::exitapp
For example, when we work on coordinate (table, square, cube,...) then we will use X = iteration[ofloopX], Y = iteration[ofloopY], Z = iteration[ofloopZ], also a lot of algorithm can use this shortcut...
Therefore if we can GET and SET "index" with a_loop[1], a_loop[2], a_loop[3] then users haven't to store them in a variable (more speed) and haven't to write extra line (can be more readable if we don't need a naming)... Object or not, nevermind, like a_ipaddressN, a_loopN is enough (maybe a_ipaddress has to be an object for V2? )

Code: Select all

loop 10
	loop 10
		loop 10
		{
			msgbox % "xyz : " a_loop[3] "," a_loop[2] "," a_loop[1]
			;...
			if true
				a_loop[2] += 1
			;...
			;...
			;...
		}
esc::exitapp
Also why we haven't a traditonal for (i:=1, i<10, i++) { } ?
However thanks for this toy, I can see potential and some clever use to restart a limited loop like this.

Code: Select all

loop 1
{
	msgbox %a_index%
	a_index := 0
}

Re: v2-thoughts Discussion

Posted: 19 Feb 2014, 14:47
by joedf
lexikos wrote:That would add overhead and has no apparent purpose.
+1 true. Object are just an easier way of organizing your "info". And this "organization" costs. For these global vars, it's not worth it.
vasili111 wrote:... Focus on compatibility very often brings unnecessary complexity...
+1 true. Just avoid AutoHotkey of become an "AutoIt" wanna be. AutoHotkey is more user-friendly than AutoIt will ever be.

I don't want to sound like a pessimist. There is great ambition here.

Re: v2-thoughts Discussion

Posted: 20 Feb 2014, 03:19
by just me
tank wrote:
lexikos wrote:That would add overhead and has no apparent purpose.
I might add its a little programmer centric as well. objects are in general difficult enough for non programmers to grasp lets not do things just for the sake of oop
Well, this might be a good point.

Re: v2-thoughts Discussion

Posted: 12 Apr 2014, 06:04
by fincs
I updated the OP to match the v2-a046 v2-thoughts update, as well as my opinions.

Re: v2-thoughts Discussion

Posted: 12 Apr 2014, 18:04
by lexikos
fincs wrote:Keep meta-functions.
The question wasn't whether to keep them, but how can they be improved or simplified to make them easier to understand/use? For example, returning true/false (handled/not handled) and using ByRef to return the value would allow scripts to call them and be able to properly handle the result. Other changes (that I haven't thought of) might be able to reduce the chance of an error causing infinite recursion, or remove the need for every meta-function to explicitly exclude "base" and built-in methods. Subtle changes to the way object invocations work might allow x[y] to be mapped without affecting x.y (if the script or built-in class chooses).
Do not remove Integer keys, as that would significantly decrease performance in sparsely populated arrays
Do you have any hard facts to back up that claim? Last I checked (years ago), the margin between associative arrays with integer keys and psuedo-arrays was small, despite that pseudo-arrays required string conversions. I suspect that the binary search integer comparisons vs string comparisons makes a bigger difference. Associative arrays with string keys were slightly slower than pseudo-arrays, and yet we don't prioritize pseudo-arrays. (Anyway, I had no intention to remove integer keys and don't recall suggesting otherwise.)
Yes to all proposed Object methods and properties.
These make the dedicated array type unnecessary, except for performance (in theory! and yet, performance is fine as is), which is completely not my concern for v2. Even that concern can possibly be solved by optimizing objects to automatically choose between methods of storage, as Lua's tables do. That would avoid the loss of flexibility and need for re-training users.

A dedicated array type would also cost (considerably more) time for development, testing and documentation, and in the end, it feels like a compromise that I can't justify.

Re: v2-thoughts Discussion

Posted: 12 Apr 2014, 18:38
by fincs
lexikos wrote:The question wasn't whether to keep them, but how can they be improved or simplified to make them easier to understand/use?
Oh OK then. In that case, I'd say that I find the behaviour you proposed clumsier to use, and who directly calls meta-functions anyway? I think that most of the confusion with meta-functions stems from not having a proper way for introducing property handlers in classes (or base objects), instead having to rely on adding __Get/__Set meta-functions that consist of a huge if ladder (or instead using the class-based workaround you added to the helpfile). I suggest adding __GetProp and __SetProp meta-functions that are attempted to be invoked (for string properties) before __Get and __Set proper are tried. That way it is not necessary to deal with meta-functions at all in most object-based code. Having obj[key] behave differently than obj.key is IMO inconsistent, because then two different types of 'Get' operations would need to be handled.
lexikos wrote:(Anyway, I had no intention to remove integer keys and don't recall suggesting otherwise.)
It looks like I misread the corresponding line in the document: "For greater flexibility, perhaps numeric string keys should be stored as strings and never as pure integers." (I skipped the word in bold). So, disregard my statement then. Numeric string keys should indeed be stored as strings and never as pure integers.
lexikos wrote:These make the dedicated array type unnecessary, except for performance (in theory! and yet, performance is fine as is), which is completely not my concern for v2. Even that concern can possibly be solved by optimizing objects to automatically choose between methods of storage, as Lua's tables do. That would avoid the loss of flexibility and need for re-training users.
Now that you suggest it, auto-detecting the method of storage like Lua does may be a better option than introducing a separate Array type.

Re: v2-thoughts Discussion

Posted: 12 Apr 2014, 19:50
by lexikos
fincs wrote:... and who directly calls meta-functions anyway?
The point is that having the behaviour depend on whether the function uses 'return' or not (as opposed to depending on the actual value) is a foreign concept. Secondary to that, anyone who overrides a class which uses meta-functions would directly call a meta-function (in the base class), if that was the preferred way to inherit meta-functionality.
I think that most of the confusion with meta-functions stems from not having a proper way for introducing property handlers in classes ... That way it is not necessary to deal with meta-functions at all in most object-based code.
I would agree with that; however, what you're basically saying is that the confusion comes from having to use the meta-functions at all. Avoiding the need to use them doesn't solve the problem that they're confusing.
I suggest adding __GetProp and __SetProp meta-functions that are attempted to be invoked (for string properties) before __Get and __Set proper are tried.
I am more inclined to implement properties as syntax sugar in the class syntax without implementing new meta-functions as such. For example, it is very simple to change x.foo to call the method defined by y.foo when x extends y and y.foo is a function. There's little or no performance loss since y.foo is already looked up. With a little more work, get foo and/or set foo(value) could be added without sacrificing compatibility or the ability to get method references:
  • Defining get foo in class y creates a Property and stores the getter method in y.foo.get.
  • x.foo recurses into y, which sees that y.foo is a Property, so invokes it.
  • Since this is a "get" invocation, the Property calls y.foo.get.
Having obj[key] behave differently than obj.key is IMO inconsistent,
Isn't that the whole point? If they behave differently, they are inconsistent by definition. In C#, the two syntaxes are used for completely separate purposes; x[y] is typically used for accessing items in a collection, whereas x.y only accesses properties. Properties generally don't need to be accessed dynamically, so separating the two would conveniently avoid any conflicts such as x[foo] := bar accidentally changing the object's "class" because foo = "base". That wasn't really the point though; the idea (just an idea) was to allow this opt-in functionality (or change the meta-function interface to allow for such things to be added later), for flexibility.

Re: v2-thoughts Discussion

Posted: 13 Apr 2014, 10:28
by fincs
lexikos wrote:The point is that having the behaviour depend on whether the function uses 'return' or not (as opposed to depending on the actual value) is a foreign concept.
This happens because there is no true separate Null value. Currently SYM_MISSING conceptually works in a similar way like a Null value, but it's only used as a placeholder for omitted parameters in function calls.
lexikos wrote:With a little more work, get foo and/or set foo(value) could be added without sacrificing compatibility or the ability to get method references
This approach could indeed work (BTW, parametrized properties should also be supported). Objects of the kind {get: Func("..."), set: Func("...")} are rare enough to lose the ability to get references to them. Alternatively something like __PropName could be looked up instead of Name itself for property handling, but it would involve one extra field lookup. Another alternative would be to add an internal flag to the Object class to indicate that an object is a property definition.
lexikos wrote:Isn't that the whole point? If they behave differently, they are inconsistent by definition. In C#, the two syntaxes are used for completely separate purposes; x[y] is typically used for accessing items in a collection, whereas x.y only accesses properties. Properties generally don't need to be accessed dynamically, so separating the two would conveniently avoid any conflicts such as x[foo] := bar accidentally changing the object's "class" because foo = "base". That wasn't really the point though; the idea (just an idea) was to allow this opt-in functionality (or change the meta-function interface to allow for such things to be added later), for flexibility.
My point was that adding separate handling of x[y] and x.y would increase the complexity of the rules and of the documentation. Plus, losing the ability to dynamically access properties is IMO undesirable.