Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AutoHotkey v2 Alpha Release


  • Please log in to reply
870 replies to this topic
trueski
  • Members
  • 121 posts
  • Last active: Jun 25 2014 09:12 PM
  • Joined: 08 Apr 2008
On the topic of dynamic variables, I think they should be allowed in ahk v2. To make the syntax more legible, the php syntax could be used (or a twist on it could be done)

AHK v1:
DynamicVar := %var%

PHP:
$DynamicVar  = ${$var};

The text between the curly braces is evaluated like an expression.

AHK v2:
DynamicVar  := %{%var}
DynamicVar  := %{"Variable" . %var}

On another topic, I think a new directive should be created to allow statements to be terminated with a character other than a newline.
-trueski-

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
I am not an expert on programming languages, and my "opinion" should not influence the direction of development.
That said, could someone show me how to do this without dynamic variables as easily. I would like to change it to be compatible with the new version. I have already removed all the $'s from my code :).

LoadDefaultButtons(Byref btns) {
  global hIL
  
  Loop, %A_ScriptDir%\res\Icons\*.* ;loop through all icons in folder
  {
    StringTrimRight,iIcon,A_LoopFileName,4  ;remove the extension
    icon_%iIcon% := IL_ADD(hIL, A_LoopFileFullPath,0x0,1) ;add them to imagelist and get IL number
  }
  
  icon_cut := IL_Add(hIL,A_ScriptDir . "\Res\toolbar.bmp",0xC0C0C0,0) ;add another bitmap to IL with multiple icons, first one cut
  iIcon := "copy|paste|undo|redo|delete|new|open|save|preview|properties|help_arrow|find|find_again|print"
  Loop, Parse, iIcon,| ;get the other names
    icon_%A_LoopField% := icon_cut + A_Index ;and assign number
  
  btns =  ;caption,iconNumber,states,styles,ID - majkinetors toolbar control buttons
    (LTrim
      New    , %icon_new%
      Open   , %icon_open%,,DROPDOWN
      Save   , %icon_save%,,DROPDOWN
      -
      Cut    , %icon_cut%
      Copy   , %icon_copy%
      Paste  , %icon_paste%
      Undo   , %icon_undo%
      Redo   , %icon_redo%
      Delete , %icon_delete%
	  -
      Bold   , %icon_bold%
      Italic , %icon_italic% 
      Underline,%icon_underline%
    )
}

For those who dont know, this code is shortened from my live project WYSIWYG BBCode Editor
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Named parameter support is on the roadmap. However, it's not a v2 goal, and it probably won't be supported with command syntax due to ambiguity.

I don't intend to remove dynamic variables, but I'm interested to hear the arguments for and against.

At the moment I'm working on changing the way variable declarations are stored so that "global" declarations persist after the closing brace of the function has been parsed. This has a few benefits:
[*:3cn4u552]Double-derefs in assume-local functions will only deref locals or declared globals, eliminating a common source of confusion.
[*:3cn4u552]Parsing of derefs in expressions can be postponed until the full expression-parsing stage, simplifying the implementation.
[*:3cn4u552]"Static x" won't put assume-local mode into effect, so the following (which currently causes a load-time error) will be allowed:
Func() {
    static x
    local y ; Previously had to be ABOVE static x.
    z := 1 ; Global.
}
As a side-effect of the second point, questionable things like the following will not be possible:
Func(){
    global
    x := 1 ; Set global x.
    local x := 2 ; Set local x.
}
In my current build, these cases are detected as errors. However, depending on how things work it, the earlier x might be treated as a local. Declaring the same static twice or redeclaring a previously declared variable as a different type of variable (e.g. local x ... static x) will be considered an error. Declaring the same global or local twice won't be considered an error, to allow things like this:
Func(x){
    if Foo(x)
        global y := Bar(x)
    else
        global y := Baz(x)
}
This will lead on to super-globals and #MustDeclare. My current plan is for "global x" outside of any function to be essentially equivalent to declaring that global inside every assume-local function, while its usage inside functions will remain the same. Ordinary global variables will be declared with "var name". A function beginning with the line "global", "static" or "local" will be exempt from #MustDeclare. Conversely, a function with both "global x" and "local y" (which is not assume-static) will have #MustDeclare behaviour applied to it regardless of whether the directive was used.

Sorry but for #Delimiter you are wrong. There are guys who use it, I am one of them. For Unichars (http://unichars.sourceforge.net) it is mandatory otherwise the character | cannot be used in codes. I replaced the delimiter by chr(1)

I intended to reply to this sooner but it slipped my mind. It sounds like you've confused the #Delimiter directive with something else. #Delimiter changes the command arg delimiter from comma (,) to a character of your choosing, and has nothing to do with |. The only advantage to using it might be that you wouldn't need to escape commas in literal text.

To make the syntax more legible, the php syntax could be used

My current plan is to support %(expression returning a variable name)% in expressions and %(expression returning a string)% with commands.

I think a new directive should be created to allow statements to be terminated with a character other than a newline.

I've already said 'I will not add any new directives aimed at "customizing" the language.'

IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007
@shajul:
Something like this:
LoadDefaultButtons(Byref btns) {
  global hIL
  
  iconMap := {} ; Define a simple Array (Object)
  
  Loop, %A_ScriptDir%\res\Icons\*.* ;loop through all icons in folder
  {
    StringTrimRight, iIcon, A_LoopFileName, 4  ;remove the extension
    iconMap[iIcon] := IL_ADD(hIL, A_LoopFileFullPath,0x0,1) ;add them to imagelist and get IL number
  }
  
  iconMap.Cut := IL_Add(hIL,A_ScriptDir . "\Res\toolbar.bmp",0xC0C0C0,0) ;add another bitmap to IL with multiple icons, first one cut
  
  iIcon := "copy|paste|undo|redo|delete|new|open|save|preview|properties|help_arrow|find|find_again|print"
  Loop, Parse, iIcon,| ;get the other names
    iconMap[A_LoopField] := iconMap.Cut + A_Index ;and assign number
  
  
  
  btns := "New," iconMap["new"] "`n"
  btns .= "Open," iconMap["open"] "`n"
  btns .= "Save," iconMap["save"] "`n"
  btns .= "-"
  btns .= "Cut," iconMap["cut"] "`n"
  ;...
}
Mapping always requires something like a "Dictionary" Object/Array. For more detailed discussion on that I recommend to create a separate thread ;)


@Lexikos: Those planed changes in AHKs weird scoping syntax sounds very promising.

The only thing I miss are some syntax sugars when defining Objects (the definition of Methods from Objects could be more intuitive/more readable), also, if you plan some scoping changes, it might be possible to make Functions just visible for classes which actually declaring them?

Here some thougts to bring your prototyping ideas compatible to some class logic, which primary would spare some typing:


; Current AHK_L Code
Car := Object()
Car.Name := "woot"

Car.Run := "car_run"

car_run(this){
	msgbox % this.Name ; this is avaiable in this context
}

; Requiered Changes in current AHK_L Code:

Car := Object()
Car.Name := "woot"
[color=red]Car.Run(){[/color] ; Allow Functiondefinition directly for a Member
	msgbox % this.Name ; this is avaiable in this context
}

; Above syntax even could support some class system by easily preparse following constructs:
class Car
{
	Name := "woot"

	Run(){
		msgbox % this.Name ; this is avaiable in this context
	}
}

; 1. the class keyword is replaced with  := Object()
; 2. Everything in braces in a class definition is in the Context of the given class;
;	Name := "woot" is replaced with Car.Name := "woot"
;   Run(){...} is replaced with Car.Run(){...}
; "this" keyword is avaiable in those methods


shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
Thanks IsNull, I know about dictionary objects..

That said, could someone show me how to do this without dynamic variables as easily.

But multiple assignments where only one was required before is not as easy Posted ImagePosted Image

I don't intend to remove dynamic variables, but I'm interested to hear the arguments for and against.

So I am not worried now. Anyway, no more polluting this thread by me!
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
IsNull, I've started a separate topic to discuss class definition syntax, since it seems largely irrelevant to the main theme of v2.0, which is making any compatibility-breaking changes deemed necessary to improve the language.

There is, however, one part that seems relevant:

I know that the current behaviour of the semi-automatic "this" parameter confuses some users, and it also imposes certain limitations. For instance, you might think to call this.base.Method(this) to pass control to an overridden version of the method. Unfortunately, this will only work if this.base.HasKey("Method"), not if it is inherited from this.base.base.

As part of a solution, I've been considering implementing "this" as a built-in keyword. [...]

This (probably compatibility-breaking) change may need to be made in v2.

One drawback that I can see is that the current behaviour of passing the target object as the first parameter can be convenient in some (probably few) cases. Another possible issue is that some users might object to "this" being a reserved keyword.

tank
  • Administrators
  • 4345 posts
  • AutoHotkey Foundation
  • Last active: May 02 2019 09:16 PM
  • Joined: 21 Dec 2007

object to "this" being a reserved keyword.

WELL... I have and do always feel like Not having many(any?) reserved words was bad. Lest we forget the debacle with "if" functions and the intro to the while loop. I think version 2 has room even for the noobs to come to understand reserved words. Sure they should be judisciously allocated but i think its time...... my 3 cents
Never lose.
WIN or LEARN.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I found the handling of object methods weird to begin with, because they work differently depending on whether the function reference was made in the object or in its base object. I really suggest getting rid of this behavior. Either keep the "this" object in the first parameter or make it a reserved keyword that can be used without declaring it in the function parameters.

Not knowing about this behavior has caused me a few hours of headaches, because it was quite unexpected for me.

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Suggestion: Make "P" the default for GetKeyState (Both the function and the command, if the command is kept)

I don't think I've seen anyone use GetKeyState without it (on purpose).
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I found the handling of object methods weird to begin with, because they work differently depending on whether the function reference was made in the object or in its base object.

That was my point.

Either keep the "this" object in the first parameter ...

That would make it impossible to use an array of functions without having the array passed to each function. For example, an array of event handlers - each handler might be written by a different author, and none of them should see the array itself.

I don't think I've seen anyone use GetKeyState without it (on purpose).

I have on many occasions. Also, the logical keystate is consistent, whereas "P" differs depending on whether the keyboard hook is installed.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009

I found the handling of object methods weird to begin with, because they work differently depending on whether the function reference was made in the object or in its base object.

That was my point.

Good to know, one more step towards a better AHK :)

  • Guests
  • Last active:
  • Joined: --

Conversely, a function with both "global x" and "local y" (which is not assume-static) will have #MustDeclare behavior applied to it regardless of whether the directive was used.

...I have no intention of using #MustDeclare & would NOT want it auto-arming itself.

I only "declare" vars when I want to change their scope, the fact that I declare a couple vars as global & some as local, should NOT engage full #MustDeclare behavior for other vars...(if I wanted it, I'd turn it on!).

This should NOT create a #MustDeclare warning...

function() {
	global globalvar
	local localvar
	msgbox, (%unknown_var_is_not_an_error%)
}
...without me specifically turning on #MustDeclare any undeclared var should NOT be an error, even if I declare some of my other vars.

jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006
Your code is ambiguous. There's no way to tell which scope the unknown variable should have in that case. I would guess it's a static based on that snippet alone; but that's just a guess (and compilers can't guess).

P.S. Have you tried running that code in a current version of AHK?

MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009

Suggestion: Make "P" the default for GetKeyState (Both the function and the command, if the command is kept)

I don't think I've seen anyone use GetKeyState without it (on purpose).

+1

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio França -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


jaco0646
  • Moderators
  • 3165 posts
  • Last active: Apr 01 2014 01:46 AM
  • Joined: 07 Oct 2006

I always use #UseHook,

I should've explained this a bit more. What I meant is that I don't think there is enough distinction between #UseHook and #InstallKeybdHook that we need both. Perhaps eliminating the latter is a better idea.

Edit:

Thus, I suppose that "Tab2" should become the new "Tab".

I knew there was a reason I said merge rather than replace, but couldn't find it right away. It was this: BackgroundTrans has no effect inside a Tab2 control. It wouldn't be a bad idea to run through the Bug Reports forum and address anything related to Tabs before any consolidation happens. I can do that and report back, if this change is going to be implemented.

Blanks in math operations should be consistently treated as zeros.

I disagree, for many of the reasons Laszlo mentioned when that discussion took place.

But previous discussions took place before we had the #Warn directive, which should detect uninitialized variables in math expressions. It would be so much more flexible to let this directive manage the behavior.

I'm in favor of directives that change the warning level such as #MustDeclareVars and #ShowWarnings...

Let's allow the directive to do its job, and allow the programmer to decide whether to use it.