Jump to content

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

AutoHotkey_L v1.0.90 and Roadmap


  • Please log in to reply
48 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
AutoHotkey_L v1.0.90.00

Fixed: UrlDownloadToFile in Unicode builds on Windows < 7.
Fixed: Upper-ANSI characters were sent as Alt+0 in ANSI build.
Fixed: File.Pos was incorrect after attempting to read past EOF.
Fixed: Escape sequences in #If expressions and static initializers.
Fixed: ClipboardAll sometimes crashed the script with certain formats.
Fixed: Transform HTML calculated length incorrectly for &#NNN; entities.
Fixed: VarSetCapacity now correctly ignores #MaxMem for ByRef variables.
Fixed: FileAppend,,file.txt set ErrorLevel=1 even on success.
Fixed: Match length was miscalculated for RegEx callouts with the P) option.
Fixed (Ahk2Exe): InputBox in x64 scripts.
Fixed (Ahk2Exe): #Include <Lib>.
Integrated Sean's improvements to number handling in COM interop.
Optimized RegExReplace and RegExMatch in Unicode builds.
Downloads etc.
Version Numbering

As you may notice by the title of this post, I've changed the version numbering scheme; dropped .Lnum and bumped the version number up quite a bit. My intention is for the version number to reflect the status; something like v1.0.features.bugfixes. Some users suggested AutoHotkey_L be v1.1 or v2, but as I consider the project somewhat incomplete in its current state, I've opted to save v1.1 for later.

Other Changes

In an attempt to solve the anti-virus false positives, I've removed mpress.exe from the installer and have not compressed the other executables. To compress compiled scripts (which also adds a degree of protection), you may need to download MPRESS and place it in the Compiler directory. If you've installed a previous version of AutoHotkey_L, you probably already have mpress.exe.

Roadmap

I have also reviewed my ever-changing TODO list and turned it into a roadmap of sorts. Feel free to comment on anything in that document, but please don't post feature requests here. I don't have a timeline, but I'll probably work on v1.1 and v2 in parallel, depending on what takes my interest.



aSEioT
  • Members
  • 87 posts
  • Last active:
  • Joined: 31 Oct 2010
Great, Thank you! :D

jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009
Excellent - & thank you for the roadmap :D

I've removed mpress.exe from the installer and have not compressed the other executables.

NOTE - this increased the Unicode x86 version from 364 -> 855 KB.

[*:3kdq4lbt]RegExReplace callback functionality - needs a lot more thought.

I'm not sure what your current thoughts are here, but one thought might be a conditional/dynamic replace value:
MsgBox, % RegExReplace("autohotkey", "(a|h)(?CFunc)", ReplaceValue)
Func(M, C, F, H, N, ByRef ReplaceValue) {
      ReplaceValue := (M="a"? "A":"H")
}

[*:3kdq4lbt]Object default value ...

I really like this idea. Not requesting anything here (just thoughts), but would dynamic creation of objects (arrays specifically) be an option?
val = AHK
val[1] := "value" ; w/o defining an object
MsgBox, %val% ; shows "AHK"
MsgBox, % val[1] ; shows "value"
*The primary (noobish) benefit being that array[n] would be similar to array%n%

Auto-concat: It might be best to eliminate automatic concatenation ...

Personally, I strongly oppose this. This is one of my favorite features in AHK, & IMO it makes simple coding more enjoyable.

And of course, thank you for you continued efforts in developing AHK :)

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Thx Lexikos for update.

I'm not sure what your current thoughts are here, but one thought might be a conditional/dynamic replace value:

This was asked by me and maybe others already. I also released a script that can do that.

AFAIK, the PCRE doesn't support it.

Named parameters: func(x, y, foo: bar).
Meta-operators: allow an object to define what happens when a given operator is used on it and another object or non-object value.
Object default value.

This is awesome. Thanks for changing your stance on it.
Posted Image

IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007
val = AHK
val[1] := "value" ; w/o defining an object
This is IMHO the wrong direction, as it makes very hard to follow the code logic.

I miss some informations about the OOP future. Regarding at this example, I have the basic request, that defining Objects should be possible.

This approach could be solved by precompiler, as fincs already shown, but I would appreciate a offical, native implementation.

For the moment I dont request any kind of Data-Encapsulation - just new keyword/block type for defining classes and automated loading of this "base" Objects, so the following should be possible:

Progress, m2 b zh0, Collectiing dlls...
dlls := CollectDLLs()

for k,dll in dlls {
   Progress, m2 b zh0, % "registring " dll.FileName()
   dll.Register()
}
MsgBox % "Registered " dlls.Count() " dlls!"

exitapp

CollectDLLs(){
global
   dlls := new Collection()
   loop, %a_scriptdir%\*.dll
      dlls.Insert(new Dll(A_LoopFileFullPath))
   return dlls
}



class Collection
{
   Collection.Count := "Collection_Count"

   Collection_Count(this){
      i := 0
      for e in this
         i++
      return i
   }
   
   Collection(){ 
      ; void constructor
   } 
}

class Dll
{
   Dll.Register := "Dll_Register"
   Dll.FileName := "Dll_FileName"
   Dll.Path := ""
   
   Dll_Register(this){
      run, % "regsvr32 /s""" this.Path """"
   }
   Dll_FileName(this){
      fullPath := this.Path
      SplitPath, fullPath, fileName
      return fileName
   }
   Dll(this){ ; Constructor
      this.Path := path
   }
}

any change for this direction?

fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007
[quote name="jethrow"]Personally, I strongly oppose this. This is one of my favorite features in AHK, & IMO it makes simple coding more enjoyable[/quote]
+1
[quote name="IsNull"]just new keyword/block type for defining classes and automated loading of this "base" Objects, so the following should be possible:
[i][color=gray][code snippet omitted for brevity][/color][/i][/quote]
I think there is too much redundance (the "class" name is repeated too many times). I propose this:
[code]class Collection
{
Count() ; implicit this parameter
{
i := 0
for e in this
i++
return i
}

Collection(){ ; or even this() in order to avoid duplicating the class name
; void constructor, which is actually optional
}
}

class Dll
{
Register()
{
run, % "regsvr32 /s""" this.Path """"
}
FileName()
{
fullPath := this.Path
SplitPath, fullPath, fileName
return fileName
}
Dll()
{
this.Path := path
}
}
[/code]
This would work like my preprocessor, except that code generation/tweaking is done at parse time instead.

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

I'm not sure what your current thoughts are here, but one thought might be a conditional/dynamic replace value:

That was the whole point. See [AHKL] RegExReplace Callout.

Not requesting anything here (just thoughts), but would dynamic creation of objects (arrays specifically) be an option?

Your example might be possible since it could allow the array val to have a default value "AHK", but it would not happen automatically. See Default Base.

Personally, I strongly oppose [removing auto-concat]. This is one of my favorite features in AHK, & IMO it makes simple coding more enjoyable.

I also feel that way. However, I make a habit of avoiding auto-concat where neither operand is a literal string, so I had considered enabling it only in cases like foo "bar" and "item" x+1, where a literal string is involved.

AFAIK, the PCRE doesn't support it.

Whether or not PCRE directly supports it is irrelevant. PCRE only handles matching; all of the replacing is done by RegExReplace.

I have the basic request,

please don't post feature requests here.

AutoHotkey_L objects are prototype-based, not class-based. I think that using the "class" keyword encourages users to think inside the box, so to speak, which is more restrictive. My objection isn't a strong one, but there would have to be community consensus before I implement anything further than what I've written in the roadmap.

Syntax sugar for defining object methods; perhaps something simple like Type.Method(params) { … } which would define a function, create an object Type if necessary and store a function reference in Type.Method (all at load time). Type would typically be used as a base for other objects at run time.

This has the advantage of simplicity, as well as being more directly analogous to the actual implementation. I believe Lua similarly supports function Type:Method(params) … end, but it's probably equivalent to Type.Method = function(params) … end. Inline functions aren't really an option with the current architecture.

Additionally, I thought about the new keyword but was unable to think up any practical benefit of it over simply calling the function and allowing it to create the object. This is how your example might look if I implement only what's on the roadmap:
Progress, m2 b zh0, Collectiing dlls...
dlls := CollectDLLs()

for k,dll in dlls {
   Progress, m2 b zh0, % "registring " dll.FileName()
   dll.Register()
}
MsgBox % "Registered " dlls.Count() " dlls!"

exitapp

CollectDLLs(){
global
   dlls := Collection()
   loop, %a_scriptdir%\*.dll
      dlls.Insert(Dll(A_LoopFileFullPath))
   return dlls
}


Collection() {
   global Collection   ; Ideally this wouldn't be necessary.
   return { base: Collection }
}

Collection.Count(this) {
   i := 0
   for e in this
      i++
   return i
}


Dll(path) {
   global Dll
   return { Path: path, base: Dll }
}

Dll.Register(this) {
   run, % "regsvr32 /s""" this.Path """"
   ; Ideally:
   ;    run, regsvr32 /s"%this.Path%"
}

Dll.FileName(this) {
   fullPath := this.Path
   SplitPath, fullPath, fileName
   return fileName
}
This would also be an option:
c := Collection.New()

Collection.New() {
   global Collection
   return { base: Collection }
}


jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009

AutoHotkey_L objects are prototype-based, not class-based. I think that using the "class" keyword encourages users to think inside the box, so to speak, which is more restrictive.

I agree that Prototype-based is better for AHK, but I would like to see the ability to completely define an object & all it's members in one block. polyethene had mentioned the concept of defining functions within functions. Would something like this be a reasonable option:
MyObj := SomeObject()

MyObj.func()



SomeObject() {

      obj := {}

      obj.func(this) {

            MsgBox, Message from SomeObject

      }

      return, obj

}


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

I would like to see the ability to completely define an object & all it's members in one block.

I don't see what the fuss is about. If you just lump the function definitions together, what's the difference?

Would something like this be a reasonable option:

SomeObject() {
      obj := {}
      obj.func(this) {
            MsgBox, Message from SomeObject
      }
      return, obj
}

That does seem logical, though perhaps more difficult to implement. I'd say it should be feasible, but I'm concerned that users would expect to be able to access local variables of the outer function from within the inner function, as in languages like JavaScript. I don't think closures are feasible with the current architecture, but on the other hand I wouldn't want to allow functions-in-functions now (merely for "tidy" code) then later be forced to break compatibility if closures become possible.

I'll have to reconsider what is needed to allow functions-in-functions; beyond that I think your proposal could work simply by generating a private function definition and assignment, equivalent to this:
SomeObject() {
      obj := {}
      [color=darkred]obj.func := "SomeObject_obj_func"
      SomeObject_obj_func[/color](this) {
            MsgBox, Message from SomeObject
      }
      return, obj
}
This reminds me of something else I have thought about but haven't really planned: function references. If a function reference can be assigned to a variable and called naturally as var(), that would solve any name-spacing issues for functions-in-functions. However that likely has other implications for compatibility, so should be considered thoroughly for v2.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

I believe Lua similarly supports function Type:Method(params) … end, but it's probably equivalent to Type.Method = function(params) … end. Inline functions aren't really an option with the current architecture.

Its not equivalent. In Lua, : are used as syntax sugar for object creation, i.e. to avoid specifying first argument (i.e. this). The same can be done in AHK, or, you don't even have to differentiate between two cases Lua has (: and . ). You can simply use . the way Lua uses :.

The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, the statement

function t.a.b.c:f (params) body end
is syntactic sugar for

t.a.b.c.f = function (self, params) body end



This reminds me of something else I have thought about but haven't really planned: function references. If a function reference can be assigned to a variable and called naturally as var(), that would solve any name-spacing issues for functions-in-functions. However that likely has other implications for compatibility, so should be considered thoroughly for v2.

+1

Personally, I strongly oppose this. This is one of my favorite features in AHK, & IMO it makes simple coding more enjoyable

+1

I don't think closures are feasible with the current architecture,

Isn't form of closure already achievable using _LowLevel and assume static ? One more point IMO, for lowlevel to become part of AHK, apart from other great benefits this library would provide.

I also agree with Lexikos that AHK doesn't need full blown class syntax support. The things already in the roadmap should be enough.
Posted Image

IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

I also agree with Lexikos that AHK doesn't need full blown class syntax support. The things already in the roadmap should be enough.

Did you mean You don't need it? ;) Thats really the same bad reason as I say I want it.

My objection isn't a strong one, but there would have to be community consensus before I implement anything further than what I've written in the roadmap.

I agree. But the problem actually is, AHK Community has really a lot of people who don't care about any OOP and just want things easy. On the other hand, if the Language provides more experienced design features, the community might grown/change.

To be serious, I don't have experience with prototype-based OOD. However, I like to learn new things, but for now any interesting AHK_L Objects which I found try to imitate class design.

As I think at least you, Lexikos, should be experienced in prototype-based Design, can you provide some reference AHK_L OOD examples? I mean there are reasons why I like the class Design - but I dont see any for the prototype-based Design - and before I fight against something, I want to know the motivation.

please don't post feature requests here.

This was just the basic future question for me, and it's the core point for my decision using AHK(_L) or not. I just wanted to hear "Forget it" or "There may be possibities" :wink:

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

Did you mean You don't need it? Thats really the same bad reason as I say I want it

No, I don't mean that. I prefer effort to be used on appropriate place that would actually give some new functionality. The other reason is that imposes some limitations on how AHK "objects" could be used. Lets not forget that AHK is script language and its used to create tools, gedgets, admin scripts etc. While those can be large applications they benefit more from "less strict" and "open" environment.

I mean there are reasons why I like the class Design - but I dont see any for the prototype-based Design

This is personal preference. There are many prototype based languages around, mostly those used for scripting which leads one to believe its actually good thing since so many different scripting languages adopted it. I personally prefer dynamic languages over those that follow strict protocols because you can "reconfigure" particular "instance" of an object on the fly.

In short I believe that AHK should follow Lua in this regard since it is already hardly influenced by it. Lua concept is proven good as it is used in large object oriented systems, for instance World of Warcraft (this use case proves its OO capabilities are good enough for hard core scenarios like MMO gaming, hence they must be good enough for other uses).
Posted Image

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

Isn't form of closure already achievable using _LowLevel and assume static ?

I don't see why you think assume-static allows anything even close to a closure. Do you mean because it allows one to access variables of another function? Only the variables of the top-most instance of the function are available, and only while it is running.

But the problem actually is, AHK Community has really a lot of people who don't care about any OOP and just want things easy.

Well, consensus among the community members that have an opinion, then.

As I think at least you, Lexikos, should be experienced in prototype-based Design,

When I added object support, my first and foremost objective was to get it done quickly, and a prototype-based design seemed the easiest to implement while also being flexible. Secondly, I wanted to support COM objects, where AutoHotkey doesn't necessarily know which members it has before they are invoked, therefore the meta-function approach fit best. Finally, I had read about Lua's meta-functions __index and __newindex and therefore knew it could work. However, at that time I had no actual experience with Lua and very little with JavaScript. As for "prototype-based OOD", I'm always more focused on building functionality than following or discussing abstract concepts; maybe that's why I'm interested by this scripting language originally intended for non-programmers.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Personally I would vote for allowing class syntax, as it helps making the code appear more readable. Apart from that, I think I like where it's going! Especially full operator support for objects is a much needed thing IMO, since one would expect this to work naturally.

Frankie
  • Members
  • 2930 posts
  • Last active: Feb 05 2015 02:49 PM
  • Joined: 02 Nov 2008
Thanks for the info and roadmap!

Also, I like Jethrow's idea of not having to declare arrays. For backwards compatibility they should still be allowed to be declared (at least until v2).

Another note: It would be nice if you included a copy of the 32 bit compiler in the 64 bit install. I have a 64 bit computer and downloaded the 32 for that reason.
aboutscriptappsscripts
Request Video Tutorials Here or View Current Tutorials on YouTube
Any code ⇈ above ⇈ requires AutoHotkey_L to run