Page 1 of 1

Features I miss from other languages & syntax ideas

Posted: 21 Oct 2017, 02:04
by KuroiLight
:beard: Just a list of features, mostly convenience oriented, I frequently wish I had in AHK:

Named Parameter Assignment/Pass-By-Name:
passing values to optional parameters by name
[example]

Code: Select all

SampleFunction(var1, var2 := "default1", var3 := "default2") {
    Msgbox % var1 . var2 . var3
}

SampleFunction("required string", var3:"optional param var3")
Operator Overloading:
overload default operators for custom class objects

Code: Select all

Class Point {
    __New(X, Y) {
        this.X := X, this.Y := Y
    }
    ;maybe prefix with a symbol when declaring for clarification? like @+ or a word like operator+
    +(Point_obj) {
        return new Point(Point_obj.X + this.X, Point_obj.Y + this.Y)
    }
    ;operators ==, :=, -, ~=, !=... etc.
}
Function Overloading:
multiple functions of the same name, differentiated by param count

Code: Select all

Add(v1, v2) {
    return v1 + v2
}
Add(v1, v2, v3) {
    return v1 + v2 + v3
}
Defined Literals
read-only variables that visible to all and resolved/replaced with their values at script auto-execute time

Code: Select all

;must be declared in AutoExecute section
#Define VAR_CONST_HEX 0xF00DFEED
#Define VAR_CONST_STR "FoodFeed"
return
SampleFunction() {
    ;no global or % resolve needed because references to variable are resolved to its value before function is run
    Msgbox, VAR_CONST_HEX % VAR_CONST_STR
}
;would resolve to the following at runtime
SampleFunction() {
    Msgbox, 0xF00DFEED % "FoodFeed"
}
Lambda Expressions: (my most wanted feature)
functions that can be declared and called in active context

Code: Select all

SampleFunction() {
    var1 := 100
    sampleLammy := (x) => {return x++} ;maybe different syntax?
    var1 := sampleLammy(var1)
    ;or
    sampleLammy2 := (x) => {return x + var1} ;access to parent scope
    var1 :=  sampleLammy2(250)
    ;and multline and re-assignment
    sampleLammy2 := (x, y) => {
        new_var := x * y ;lambda scope, non-static
        return var1 / new_var
    }
    var1 := sampleLammy2(5, 2)
} ;once context falls out of scope, all lambdas are discarded
Switches: (i have a feeling most will consider these unnecessary, but i added it nonetheless)
should be obvious for most, select code path based on expression contents

Code: Select all

;obviously for such a small number of options an 'if' would be fine, but for a large number of codepathes switch would help read-ability and possibly help performance for high traffic code pathes
SampleFunction(x) {
    switch(x) {
        5:          ;maybe use [case 5:] instead
            return "five"
        "six":
            return 6
        "zero":     ;fallthrough
        default:
            return 0
    }
}
some syntax ideas that I haven't seen in other languages, maybe bad/good ideas
is value in range (compact), instead of using between and

Code: Select all

x := 55
if(x ~= 50..100 or x ~= 150..200)
	return true
is instance of type class

Code: Select all

Class myObj ...
x := new myObj()
if(x ~= myObj)
	return true
is value one of any values, shorthand for x == 4 or x == 6 or x == 10

Code: Select all

x := 5
if(x == 4,6,10)
	return true

Re: Features I miss from other languages

Posted: 21 Oct 2017, 02:16
by nnnik
I disagree with the switches due to several reasons:
A) Their main point is replacing long if/else constructions - however they fail to replace every if/else construct their is. They only replace a very specific rare case.
B) They are supposed to be more readeable but are so rare that when approaching them it will only make the reader confused and decrease readability.

I'm not particulary fond of defined literals either. Why not use a variable name instead and make it super global?

I perfectly agree with the rest though

Re: Features I miss from other languages

Posted: 21 Oct 2017, 02:37
by KuroiLight
I agree that I don't frequently find my self needing switches, but its one of those features that when handy is really handy. However that if possible their usability could be extended increasing their use.
image the following (with many more cases): ;)

Code: Select all

switch(mouseX, mouseY) {
    (100..1000), (50..500): ;evaluated and compared in the same order they are passed to switch
        return "x is between 100-1000 and y is between 50-500"
    (>1000), (<50):
        return "x is greater than 1000 and y is less than 50"
}
---
as for B, if you mean assume-global , I really don't like the idea of polluting the global scope, this could easily cause collisions, isn't memory efficient and imo hurts read-ability. And the use case I ment for #define would be like when declaring settings or const values that you want to use in more than one place without having to scope with global all over the place.

Re: Features I miss from other languages

Posted: 21 Oct 2017, 02:45
by nnnik
This switch would only be worse on the eyes. So if you don't mind hurting eyes I reccomend using Objects for that:

As for B no I don't mean assume global I explicitly meant super global:

Code: Select all

global I_ACT_LIKE_A_STATIC := 12
fn()
{
    Msgbox % I_ACT_LIKE_A_STATIC
}
Towards me I never understood the pollution argument for variables vs. statics since statics also pollutes every scope.

Re: Features I miss from other languages

Posted: 21 Oct 2017, 02:53
by KuroiLight
nnnik wrote:This switch would only be worse on the eyes.
Maybe, I may have been spoiled by Perl, I'm used to some weird looking code thats fun to write but later just as fun to read, lol.
I like the idea of multi-param switches and range comparisons though, maybe not the <> because its a bit confusing whats going on there.
nnnik wrote: As for B no I don't mean assume global I explicitly meant super global:

Code: Select all

global I_ACT_LIKE_A_STATIC := 12
fn()
{
    Msgbox % I_ACT_LIKE_A_STATIC
}
Towards me I never understood the pollution argument for variables vs. statics since statics also pollutes every scope.
Ah lol, didn't even realize (or forgot) global could do that.

EDIT**
Maybe just the ability to compare a value with ranges would be more useful, like:

Code: Select all

x := 55
if(x ~= 50..100 or x ~= 150..200)
	return true
instead of

Code: Select all

x := 55
if x between 50 and 100
	return true
if x between 155 and 200
	return true

Re: Features I miss from other languages

Posted: 21 Oct 2017, 03:30
by nnnik
KuroiLight wrote:Maybe just the ability to compare a value with ranges would be more useful, like:

Code: Select all

x := 55
if(x ~= 50..100 or x ~= 150..200)
	return true
Iactually support this idea:
~=[\c] is currently used in AutoHotkey to match a Regular Expression which in a very broad sense could be called the comparison between a string and a string range.
So if we add more stuff to more types I think this could become an extremly useful operator:

Code: Select all

instance~=class
number~=range
string~=regex
;...

Re: Features I miss from other languages & syntax ideas

Posted: 21 Oct 2017, 12:30
by jeeswg
I've done various scripts that parse text, and every new syntax notation is a nightmare to implement, so I would always guard against adding in new notational devices especially if they can be achieved by relatively short simple functions. I also like the idea of keeping AutoHotkey as simple as possible. Despite this I'm not against being decisive where necessary.

It would be good if you linked or provided workaround code for any of the features you want, so that people can be sure what you want.

One area where I, in principle, agree is that I think that AHK should have better, i.e. function, versions of Between/Contains/In/IsType.

Re. switches, one possibly interesting idea you've reminded me of, is that if an object doesn't have a key, to be able to return some value other than blank, cf. IniRead. Whether that should be a feature of standard arrays, or whether AutoHotkey could make certain object classes available as standard templates would be the secondary question.

Code: Select all

;custom functions:
if Between(x,50,100) || Between(x,150,200)
if In(x, "4,6,10")
if Add(v1, v2, v3)

Between(x,a,b)
{
	return (vNum >= vRange1) && (vNum <= vRange2)
}
In(x,L)
{
	if x in % L
		return 1
	else
		return 0
}
Add(*oArray)
{
	vSum := 0
	Loop, % oArray.Length()
		vSum += oArray[A_Index]
	return vSum
}

;currently doable
if (x ~= "^(4|6|10)$")
if RegExMatch(x, "^(4|6|10)$")

;switches
oArray[1:"one",2:"two",3:"three"]
if oArray.HasKey(vNum)
	vOutput := oArray[vNum]
else
	vOutput := "default"

Re: Features I miss from other languages & syntax ideas

Posted: 21 Oct 2017, 13:19
by nnnik
I think I have told you before that your solution for AutoHotkey parsing is not exactly optimal.
I doubt that AutoHotkey would stop evolving because a single one of it's users parsing scripts has stopped working.
I am pretty sure that I will develop my own AutoHotkey fork in time - I will use that to showcase my feature requests.

Re: Features I miss from other languages

Posted: 22 Oct 2017, 15:03
by KuroiLight
nnnik wrote: So if we add more stuff to more types I think this could become an extremly useful operator:

Code: Select all

instance~=class
number~=range
string~=regex
;...
The addition of is instance of type class sounds really good too. I will add it to OP.
jeeswg wrote:I've done various scripts that parse text, and every new syntax notation is a nightmare to implement
Currently the ~= operator has only one use and it really only applies when there is a string on the right, I don't really see how it would add much of a nightmare to add a check for a range on the right for range comparison.
jeeswg wrote:relatively short simple functions
having a dedicated function is kinda ugly, if I was just looking for shorthand alone i'd use regex 55 ~= "[50-150]" works just fine, but its likely more expensive than a builtin range operator.
This can get even worse when you want to use variable ranges 55 ~= "[" . lower_bound . "-" . upper_bound . "]" were you have several string ops and a regex op, instead of the proposed 55 ~= lower_bound..upper_bound or 55 ~= %lower_bound%..%upper_bound% (depending on how its implemented) were you have 2 derefs and a range op.
jeeswg wrote:It would be good if you linked or provided workaround code for any of the features you want, so that people can be sure what you want.
Click on the features name they are linked to wiki pages describing what they are, most of the proposed features don't have decent workarounds.
nnnik wrote:I am pretty sure that I will develop my own AutoHotkey fork in time - I will use that to showcase my feature requests.
If you do I would be happy to use it and (assuming I have time) contribute if you need. Do you have a list of features in one post so I can see all what your wish-list is?

Re: Features I miss from other languages & syntax ideas

Posted: 22 Oct 2017, 18:41
by guest3456
why are lambda's necessary? why not just extract into a separate function?

Re: Features I miss from other languages & syntax ideas

Posted: 22 Oct 2017, 22:59
by KuroiLight
guest3456 wrote:why are lambda's necessary? why not just extract into a separate function?
Because lambdas are fun. :lol:

They are good for situations where you need a quick one off function for a short amount time (e.g. loops); and situations where you need to generate, swap or store functions.
Wiki has some good examples of its uses >Anonymous Functions<.

Re: Features I miss from other languages

Posted: 23 Oct 2017, 19:34
by derz00
KuroiLight wrote:
nnnik wrote:I am pretty sure that I will develop my own AutoHotkey fork in time - I will use that to showcase my feature requests.
If you do I would be happy to use it and (assuming I have time) contribute if you need. Do you have a list of features in one post so I can see all what your wish-list is?
@nnnik are you basing off v2?

@KuroiLight it seems there are many threads, etc on this forum (In Wish List, Bug Reports, AutoHotkey v2 Development) with wishes, things to develop, etc. Someone should take the time to organize some of it ;)

Re: Features I miss from other languages

Posted: 24 Oct 2017, 10:17
by KuroiLight
derz00 wrote: @KuroiLight it seems there are many threads, etc on this forum (In Wish List, Bug Reports, AutoHotkey v2 Development) with wishes, things to develop, etc. Someone should take the time to organize some of it ;)
Yea it would be cool if we could get a community agreed upon wishlist organized into one post and stickied.

Re: Features I miss from other languages & syntax ideas

Posted: 24 Oct 2017, 11:16
by derz00
YES And I imagine nnnik also has a list somewhere too :P

Re: Features I miss from other languages & syntax ideas

Posted: 21 Jan 2018, 15:42
by jeeswg
For switches, you can get some good outcomes by using the ternary operator:
Switch/Case statement - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 86#p187486

Re: Features I miss from other languages & syntax ideas

Posted: 22 Jan 2018, 20:28
by KuroiLight
Pretty creative way of doing it, but it isn't immediately apparent what your doing there, which is why I think dedicated syntax is better.
I'm actually not that attached to switches anymore since the same thing could be accomplished using a function lookup table.
This could be further improved with the addition of an eval function (which executes a string of code), but this opens a whole 'nother can of worms.

Re: Features I miss from other languages & syntax ideas

Posted: 02 Dec 2022, 19:37
by lexikos
Current status:

Naming parameters in function calls - planned after v2.1.
Operator overloading - planned after v2.1.
Function overloading - planned after v2.1.
Defined literals - not planned as such, but constants are planned after v2.1.
Lambda expressions - implemented in v2, but limited to expressions; embedding statements within {} is planned after v2.1.
Switches - implemented some time ago (with differences in syntax).
Range check syntax - not planned, but I consider chaining operators such as a < b < c or a < b <= c etc. (I believe Python allows this.)
Is instance of type - implemented as value is class in v2.
Is value one of any values - not planned, but equivalent functionality is planned for Array in v2.x.
Eval - planned after v2.1, possibly in a more flexible form (returning a function or module, not evaluating it immediately).

Re: Features I miss from other languages & syntax ideas

Posted: 05 Dec 2022, 00:19
by iseahound
Interesting status update! I never thought you would come around to operator overloading for fear of cluttering the language. I wonder how function overloading would work - it seems difficult to create a system where a user could dynamically define functions taking different numbers of parameters.

Re: Features I miss from other languages & syntax ideas

Posted: 05 Dec 2022, 02:16
by lexikos
Operator overloading has been on my TODO list for over 10 years. I think the expression evaluator needs to be reworked before it will be feasible.

Users can't dynamically define functions.

I implemented method overloads in WinRT.ahk by creating a simple function object that maps the parameter count to a function. It could work like that. If you refer to the function by name, it has to have a value, and that value would be the function object which performs overload resolution. Non-dynamic calls can be resolved to the appropriate function at load time.