AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Better subroutines

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Wish List
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Thu Nov 25, 2004 6:04 pm    Post subject: Better subroutines Reply with quote

Hi!

I wonder if it would be possible to implement return parameters and local variables for subroutines. I think it should be relativelly easy to do so while maintaining backwards compatibility (and easy to add it to the current AutoHotKey code, too):

1) Return parameters:

- modify Return syntax to Return [, return_value]

- modify Gosub syntax to Gosub, label [, variable_name]

2) Local variables:

- new command: StartLocal. Will mark a start of a new local block

- new command: Local, variable_name. Will declare a variable as local, meaning that it will regain its original value once a current local block ends.

- new command: EndLocal. Will mark an end of a local block

- modify Return. It should end all local blocks started by the current subroutine.

How to add it to AHK:

- StartLocal: a new string array (SA) is allocated on heap, and its pointer is added to a list of local blocks of a current subroutine (GoSub/hotkey block)

- Local, XYZ: Current value of XYZ is stored into SA in a form of XYZ=%XYZ%

- EndLocal: For each string is SA of the active local block, modify the global variable to its stored value. Then remove the SA from a list of SA's and then dispose of it.

- Return: While active local block is linked to a current subroutine, perform EndLocal.

Pepak
Back to top
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10474

PostPosted: Thu Nov 25, 2004 7:06 pm    Post subject: Reply with quote

Thanks for describing the approach. At the moment, I'm much more interested in return values than I am in local variables. There is a question of whether to simply extend Gosub/Return the way you suggest, or to do something more expansive such as parameters and return values such as this example:

NewString := SomeFunction(%OldString%)

And this also introduces the area of expressions. I was thinking that perhaps the := operator could be used to assign the result of a function call and/or any math or string expression to the left-side variable. This idea needs quite a lot more development since there are many issues, such as how commas would be escaped in the parameter list, how exactly it would work internally, etc.

I'm going to refer to this topic again when the time comes. Feel free to reply or discuss more if you want.
Back to top
View user's profile Send private message Send e-mail
Guest






PostPosted: Fri Nov 26, 2004 7:29 am    Post subject: Reply with quote

Chris wrote:
There is a question of whether to simply extend Gosub/Return the way you suggest, or to do something more expansive such as parameters and return values

Well, I guess that is up to you. I suggested the extension to Gosub/Return mainly because it is (should be, anyway) easy to add to the current code and because it is fully compatible with current code.

Parameters would be nice, but as they can be easily implemented with the local variable approach I suggested above (StartLocal / Param1 = 123 / Param2 = 456 / Gosub, Function_with_Param_1_and_2 / EndLocal), I didn't give them much priority.
Back to top
pepak



Joined: 26 Nov 2004
Posts: 21

PostPosted: Fri Nov 26, 2004 7:33 am    Post subject: Reply with quote

Guess it's time to finally register :-)
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10474

PostPosted: Fri Nov 26, 2004 12:42 pm    Post subject: Reply with quote

Quote:
I suggested the extension to Gosub/Return mainly because it is (should be, anyway) easy to add to the current code and because it is fully compatible with current code.
Yes, and its a good suggestion. However, adding a new parameter to Gosub might break a few existings scripts because hotkey labels can contain commas, such as this example:

^!,::MsgBox You pressed Ctrl-Alt-Comma.
#Space::gosub, ^!,

The comma in the second line above would have to be escaped if additional parameters were added. I know this is pretty rare, so it's not a huge concern as long as it's documented in the changelog.

I guess the syntax could work like this:
Gosub, MyFunction, result, %var%
Gosub, MyFunction,, %var%

And to make labels easy, maybe they could be like this:
Code:
MyFunction(Param1):
if Param1 = 1
    return Yes
else
    return No

Quote:
Parameters would be nice, but as they can be easily implemented with the local variable approach I suggested above (StartLocal / Param1 = 123 / Param2 = 456 / Gosub, Function_with_Param_1_and_2 / EndLocal), I didn't give them much priority.
It's my impression that local variables aren't as desirable as parameter passing and return values (though as you pointed out, these concepts are related). We could have a poll to find out which one should be given a higher priority.

If this discussion interests anyone else, feel free to contribute ideas or comments.
Back to top
View user's profile Send private message Send e-mail
Rajat



Joined: 28 Mar 2004
Posts: 1718

PostPosted: Fri Nov 26, 2004 1:01 pm    Post subject: Reply with quote

i'd also wanted return values and it'd be nice if available.
_________________
Back to top
View user's profile Send private message
pepak



Joined: 26 Nov 2004
Posts: 21

PostPosted: Sat Nov 27, 2004 7:30 am    Post subject: Reply with quote

To prevent compatibility issues, the parameters and return code could also be handled by a new command:

Call, Label [, Return_Var [, Param1 [, param2 [...]]]

It would work exactly like Gosub does now, but if there was a return value, it would be stored into variable Return_Var. Param1, Param2 etc. would be passed to the called function as A_Param1, A_Param2 etc.

Return can have a return parameters added safely.
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10474

PostPosted: Sat Nov 27, 2004 12:49 pm    Post subject: Reply with quote

That's a good alternative. Thanks.
Back to top
View user's profile Send private message Send e-mail
Simpleton



Joined: 02 Nov 2004
Posts: 14

PostPosted: Sat Dec 11, 2004 8:39 pm    Post subject: Reply with quote

I was thinking maybe a simpler solution (at least simpler on your end) might be to just do the following:

create a new command called Call like pepak suggested except have it just be:

Call, Label, [Param1, Param2 ... ]

Then have it do a gosub to label and set built in variables to the args:

A_0 = number of args
A_1 = first arg
A_2 = second arg
...
A_%A_0% = A_0'th argument

return values can be handled by output arguments.

Example:
Code:

Call, GetFile, SettingsFile, settings.cfg

return

GetFile:
  ReturnVar = %A_1%
  FileName = %A_2%
  FileContents =
  loop, %FileName%
  {
    FileContents = %FileContents%%A_LoopReadLine%
  }
  %ReturnVar% = %FileContents%
return


Also it wouldn't directly interfere with a system where you could use := to get value returned by extending the return statement.
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10474

PostPosted: Sun Dec 12, 2004 1:46 am    Post subject: Reply with quote

Thanks, that's pretty nice. It has the advantage of allowing a varying quantity of parameters to be passed (though that is probably rarely needed in practice).

The main disadvantage is that it would make scripts less readable and harder to maintain than an approach where the parameters are given local names, such as:

MyLabel, InputColor, OutputX ByRef, OutputY ByRef:
...
return

Something like a "ByRef" keyword is probably needed to support output parameters, where a subroutine can alter the value of a variable passed to it by its caller.
Back to top
View user's profile Send private message Send e-mail
Simpleton



Joined: 02 Nov 2004
Posts: 14

PostPosted: Sun Dec 12, 2004 2:50 am    Post subject: Reply with quote

ya, that is a problem, though people may have trouble understanding the ByRef thing unless they have other programming experience. And adding references into the language in general makes things a lot more complicated.

Personally I would prefer the perl-like syntax (the one I suggested), which could be implemented quickly and easily, wouldn't make any major changes to the language at large, and at least in my opinion feels more consistant with the rest of AHK. It would also allow people to extend functions without having to worry about it breaking current calls.

The only thing I can think of to help readability and stuff is good use of comments, which isn't much of solution, so those are fairly large problems, but for me at least I think they are outweighed by the benifits.
Back to top
View user's profile Send private message
Jerry



Joined: 24 Jun 2004
Posts: 39

PostPosted: Tue Dec 14, 2004 5:40 pm    Post subject: Reply with quote

Moderator: Jerry had posted something long here which was accidentally deleted.
Back to top
View user's profile Send private message
Jerry



Joined: 24 Jun 2004
Posts: 39

PostPosted: Fri Dec 17, 2004 5:35 pm    Post subject: Reply with quote

Chris,

The previous post
Quote:
Posted: Tue Dec 14, 2004 5:40 pm


I think was your response to my post. But the post says it's from me!

The post you commented on which was from me, is not on.

Any ideas what happened?

Jerry
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10474

PostPosted: Fri Dec 17, 2004 10:41 pm    Post subject: Reply with quote

Most likely I pressed Edit instead of the "reply with quoted text". Embarassed If you don't have the original text of your post, I fear it is lost. Sorry about that.

I've edited the post above to reflect that something is missing, and below is my reply to avoid confusion about who wrote it.

Quote:
Code:

If :SomeFunction(%x%,%y%) = something
 { ...

This would give the ability to do 'OR' or 'AND' s as they could be programmed into the Function.
That's a good alternative. Right now, I'm leaning toward something like the following because of its simplicity and the fact that it makes scripts more readable and maintainable:
Code:
Gosub, FindColor, X, Y, Blue
...
FindColor, OutputX ByRef, OutputY ByRef, ColorToSearchFor
...
In the above, X and Y would be automatically treated as variable names rather than literal strings because the FindColor subroutine declares them as ByRef. By contrast, the word "Blue" is treated as a literal string because ColorToSearchFor is not declared as ByRef.

By the way, I don't know if ByRef is the best keyword to use. I thought maybe "output" or "ref" or something else might be better. Another way is to have any parameter whose name starts with Output to be treated this way. However, there are reasons other than passing back info to the caller that one would want to pass variables by reference, so the word output is probably not very good in that respect.

Quote:
If the function is not found (#include/typed in) in the script, Autohokey should try to find the function in an external library. I wouldn't expect GoSub to perform this activity.
That's more ambitious than what I had in mind, but it's something to think about for the future.

Quote:
If the person puts hotstring and or hotkeys in the function then Autohotkey should perform some kind of 'overloading' of the hotkeys. Again GoSub should not be expected to handle this idea.
For now, hotstrings and hotkeys will stay global because the complexity of having them be local doesn't seem to justify the limited uses of such a feature.

Quote:
If a GUI screen is placed in the function (I'm not sure of this) but would not it's controls or routines (eg. GuiClose:) have to be kept separate from the main script's GUI.
These are all good ideas, but their complexity (for now) is outside the scope of the project. This is partially based the goal of keeping AutoHotkey small in size.

Thanks for taking the time to comment.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Wish List All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group