blanks in ternary operator Topic is solved

Discuss the future of the AutoHotkey language
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

blanks in ternary operator

19 Dec 2017, 10:36

- I used to use illegal ternary operator lines in AHK v1 to achieve 'if a then do b else do nothing'.
(cond) ? (action) ;not allowed in AHK v2
I've been changing these to one of:
(cond) && (action)
(cond) ? (action) : 0
(cond) ? (action) : () ;not allowed in AHK v2
However, it seems that using () is illegal in AHK v2 (but not in AHK v1).
- I can just use 0 every time. But, out of interest, I'm not sure exactly why the lines marked below don't work.
- The reason I might use parentheses, is to indicate that literally nothing would happen (cf. 0 being assigned to something), or, to be able to quickly type something there at a later date.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

guest3456
Posts: 2313
Joined: 09 Oct 2013, 10:31

Re: blanks in ternary operator

19 Dec 2017, 10:47

i'm sure theres a reason, but i too would prefer to be able to omit the : clause and just do (cond) ? (action)

coffee
Posts: 56
Joined: 01 Apr 2017, 07:55

Re: blanks in ternary operator

19 Dec 2017, 11:42

Code: [Select all] [Download] GeSHi © Codebox Plus

(var = 1) ? (var:=2) : ("")

("") can be used anywhere as the "do nothing" expression, which to me looks better than assigning a 0. That makes it kind of clearer to be honest than having no :. Otherwise I would just rewrite the ternary and simply assign it to itself if using it as a subexpression and dont want an empty value.

You can use the AND to simulate if then and OR to simulate elses, under some circumstances, but sometimes that may end up making the code obtuse when plastered everywhere.

edit:
To move on a bit further, not sure how broad this would apply to autohotkey, the ternary if is not a control flow statement, it is an expression, an expression needs to evaluate to something, it has to have a result be it empty or something else. Ternary implies 3, it's a "ternary" operator, that needs 3 items, using the operator means it will expect a result, you need an else for the if in a ternary. If you do c:=(a) ? (1), then what exactly does it evaluate to when a is false? null? empty? 0? random characters? a_ahkversion? it needs to evaluate to something. Is it still ternary? or let's say, wouldn't it be a binary if? and if so, you still have to deal with what happens when it's not true.
Think of skipping the : in ternary as something along the lines of

Code: [Select all] [Download] GeSHi © Codebox Plus

a:= 1 +
b:= 2 *
Last edited by coffee on 19 Dec 2017, 14:18, edited 2 times in total.
Helgef
Posts: 2992
Joined: 17 Jul 2016, 01:02
Contact:

Re: blanks in ternary operator

19 Dec 2017, 14:05

it seems that using () is illegal in AHK v2 (but not in AHK v1).

V2 produces an error message, but just because v1 doesn't produce an error message, doesn't mean there isn't an error. Parentheses may be used to enclose a sub-expression to change the preceedence order, as per the documentation. Saying that nothing is an invalid expression might be incorrect, but it certainly isn't a valid expression, not in v1 and not in v2. Ternary is expr_cond ? expr_cond_true : expr_cond_false, and returns the result of the evaluated expression, hence, if one of the expressions or one of the symbols are omitted, it isn't a valid ternary.
Consequently, this,

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : ()

doesn't work in either v1 or v2. If you want nothing, "" is fine in both v1 and v2.

Cheers ☕.
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

19 Dec 2017, 14:33

- @coffee: I liked this quote:
it is an expression, an expression needs to evaluate to something

Based on that logic, I thought that (,0) would actually work. I.e. the last parameter in parentheses would be returned.

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : (0,) ;doesn't work
var := (var = 1) ? (0,) : 3 ;doesn't work

var := (var = 1) ? 2 : (,0) ;doesn't work
var := (var = 1) ? (,0) : 3 ;doesn't work

This doesn't even work in AHK v1 it turns out.

Code: [Select all] [Download] GeSHi © Codebox Plus

q:: ;test items in parentheses (AHK v1)
MsgBox, % (,1) ;blank
MsgBox, % (1,) ;blank (thought it might show 1)
MsgBox, % (0,1)
MsgBox, % (1,0)
return

- This simple point only recently became clear to me:
a binary operator: (a OP b)
a ternary operator: (a OP1 b OP2 c)
e.g. (a ? b : c)
- @Helgef:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


- I'm getting two different errors in AHK v2:

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2
;Error: A "?" is missing its ":"
;Specifically: ? 2

var := (var = 1) ? 2 : ()
;Error: Syntax error.
;Specifically: )

- I have workarounds, this is more about understanding what's going on re. errors. Cheers.
coffee
Posts: 56
Joined: 01 Apr 2017, 07:55

Re: blanks in ternary operator

19 Dec 2017, 14:41

I'm not sure why this would evaluate to anything because it's not a function call?

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : (0,) ;doesn't work
var := (var = 1) ? 2 : (,0) ;doesn't work

It should be

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : (0,"") ; for false, in v1 result is 0, in v2 result is ""
var := (var = 1) ? 2 : ("",0) ; for false, in v1 result is "", in v2 result is 0

Having nothing between parenthesis or in a subexpression is not proper syntax for v2 unless it's a function parameter where you can skip it func(,param2). Otherwise, it's not a valid expression. ("") is the blank in v2 and works for v1. I never used () in v1, didn't even know it validated and considering the inconsistency of it in v1, i'm not sure it's proper either.

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : ()

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ? 2 : ("")

I suggest sticking to consistent and valid code and go with ("") and use ternary for what it is. If you need it to be blank, then specify it as so.
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

19 Dec 2017, 16:58

I wasn't sure how AHK would handle these blank items in 'lists'/multi-statements:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Last edited by jeeswg on 19 Dec 2017, 16:58, edited 1 time in total.
Helgef
Posts: 2992
Joined: 17 Jul 2016, 01:02
Contact:

Re: blanks in ternary operator

19 Dec 2017, 16:58

jeeswg, you are unlucky, the expression, (var = 1) ? 2 : (), fails when it reaches (), and instead of producing a run-time error (v2 yields a load-time error :thumbup: ) it returns blank, which indeed is assigned to var. There are many ways to realise this, and you have already shown us an example in your first post with (,0). That is, it fails because there is isn't a valid expression between the ( and ,. Hence, it doesn't return 0, it returns blank. In summary,
coffee wrote:I suggest sticking to consistent and valid code and go with ("") and use ternary for what it is. If you need it to be blank, then specify it as so.
:thumbup:

Cheers.
guest3456
Posts: 2313
Joined: 09 Oct 2013, 10:31

Re: blanks in ternary operator

19 Dec 2017, 21:51

coffee wrote:edit:
To move on a bit further, not sure how broad this would apply to autohotkey, the ternary if is not a control flow statement, it is an expression, an expression needs to evaluate to something, it has to have a result be it empty or something else. Ternary implies 3, it's a "ternary" operator, that needs 3 items, using the operator means it will expect a result, you need an else for the if in a ternary. If you do c:=(a) ? (1), then what exactly does it evaluate to when a is false? null? empty? 0? random characters? a_ahkversion? it needs to evaluate to something. Is it still ternary? or let's say, wouldn't it be a binary if? and if so, you still have to deal with what happens when it's not true.
Think of skipping the : in ternary as something along the lines of

Code: [Select all] [Download] GeSHi © Codebox Plus

a:= 1 +
b:= 2 *


very good point.

User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator  Topic is solved

20 Dec 2017, 06:07

So in conclusion, AHK doesn't like blanks in lists:

Code: [Select all] [Download] GeSHi © Codebox Plus

;none of these work
var := ()
var := (,)
var := (1,)
var := (,1)
var := (1,,1)
var1 := 1, var2 := 1,, var3 := 1

And something that was already known. A ternary operator should have 3 items:
binary operator: a op b
ternary operator: a op1 b op2 c

Code: [Select all] [Download] GeSHi © Codebox Plus

(a) ? b ;doesn't work
(a) ? b : c ;works

Note: depending on the function, and the parameter, AHK does allow blanks in functions.
Helgef
Posts: 2992
Joined: 17 Jul 2016, 01:02
Contact:

Re: blanks in ternary operator

20 Dec 2017, 06:31

ternary operator: a op1 b op2 c

It is 1 operator, with three operands. ?: is the syntax of one operator, just like ++ is the syntax of a unary operator, that is, one operator that takes one operand, eg i++.

Cheers.
coffee
Posts: 56
Joined: 01 Apr 2017, 07:55

Re: blanks in ternary operator

20 Dec 2017, 11:01

jeeswg wrote:Note: depending on the function, and the parameter, AHK does allow blanks in functions.

The reason it allows "blanks"/"nothing" in function parameters is because the value has already been preset, in the function definition.

Code: [Select all] [Download] GeSHi © Codebox Plus

function(param1:="bop", param2:="hello")
{
msgbox(param1 . param2)
}
; we call
function(, "bye")

And so it goes for every command and function where you can skip a parameter. It's not because autohotkey likes it, but because it has a default value. Because you can't use "nothing" as a parameter if it has not been given a default, in which case, if you want it blank, you have to use "".

Code: [Select all] [Download] GeSHi © Codebox Plus

function(param1, param2:="hello")
{
msgbox(param1 . param2)
}
; we call
function(, "bye") ; not gonna work
function("", "bye") ; gonna work
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

20 Dec 2017, 11:41

- This reminded me of 2 things re. functions and blank parameters:
- It seems that AHK v2 lets you use blank trailing parameters in custom functions, whereas AHK v1 doesn't. Please point to any documentation on this.

Code: [Select all] [Download] GeSHi © Codebox Plus

;MyFunc(111,,) ;AHK v1: doesn't work ;Error:  Blank parameter
;MyFunc(,222,) ;AHK v1: doesn't work ;Error: Blank parameter
MyFunc(,,333)
MyFunc(a:=1, b:=2, c:=3)
{
;MsgBox, % a " " b " " c
MsgBox(a " " b " " c)
}

- [EDIT:] I didn't find any mention of this in the links:
Functions
https://lexikos.github.io/v2/docs/Functions.htm
v2-changes
https://autohotkey.com/v2/v2-changes.htm
- You can't specify a blank parameter in FileAppend when creating a new file in AHK v2, unlike in AHK v1. I found this out while converting/running some scripts.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Helgef
Posts: 2992
Joined: 17 Jul 2016, 01:02
Contact:

Re: blanks in ternary operator

20 Dec 2017, 12:42

So in conclusion, AHK doesn't like blanks

You have asked the wrong question, and drawn the wrong conclusion, () isn't blank and it doesn't relate to ternary. You said in your first post,

Code: [Select all] [Download] GeSHi © Codebox Plus

var := (var = 1) ?   : 3 ;doesn't work (understandable)

Why is that understandable, and not ()? The documentation explains what (expr) is for, and there is no reason to believe () is valid. Just because the documentation doesn't explicitly states that something is incorrect, doesn't mean it is correct.

It seems that AHK v2 lets you use blank trailing parameters in custom functions, whereas AHK v1 doesn't. Please point to any documentation on this.

[v1.0.90+]: Optional parameters may be omitted from the middle of the parameter list when calling the function, as shown below
src
It doesn't say you can omit from the end, so you shouldn't belive you can. v2 docs says the same thing, so I'm not going to believe I can do f(x,) in v2 until it says you can, and then I will still not do it, I do not see any reason to allow it. It is more likely to cause errors than have any other value. Imho :D. Ofc, leaving out parameters in function calls has nothing to do with this topic either, but you should be able to guess the outcome of this f(()).

Cheers :wave:
coffee
Posts: 56
Joined: 01 Apr 2017, 07:55

Re: blanks in ternary operator

20 Dec 2017, 12:56

jeeswg wrote:- This reminded me of 2 things re. functions and blank parameters:
- It seems that AHK v2 lets you use blank trailing parameters in custom functions, whereas AHK v1 doesn't. Please point to any documentation on this.

Code: [Select all] [Download] GeSHi © Codebox Plus

;MyFunc(111,,) ;AHK v1: doesn't work ;Error:  Blank parameter
;MyFunc(,222,) ;AHK v1: doesn't work ;Error: Blank parameter
MyFunc(,,333)
MyFunc(a:=1, b:=2, c:=3)
{
;MsgBox, % a " " b " " c
MsgBox(a " " b " " c)
}

- [EDIT:] I didn't find any mention of this in the links:
Functions
https://lexikos.github.io/v2/docs/Functions.htm
v2-changes
https://autohotkey.com/v2/v2-changes.htm
- You can't specify a blank parameter in FileAppend when creating a new file in AHK v2, unlike in AHK v1. I found this out while converting/running some scripts.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


There's no reason whatsoever to do that type of call if you are not going to use trailing parameters, you just omit them. That it is handled properly in v2 to match the function and prevent failure is irrelevant here, because you don't need to do it and again, it works for the function because there are defaults set. It's not really passing a "blank", it's telling the call to use the default value defined in the function. You can just call the function omitting the trailing parameters you are not going to use. This looks more like handling errors properly than a feature, since apparently, someone somewhere will try to omit trailing parameters for no reason.

Code: [Select all] [Download] GeSHi © Codebox Plus

; This type of function call is not needed, at all...
; MyFunc(111,,) ;AHK v1: doesn't work ;Error: Blank parameter

MyFunc(111) ; the defaults will still be used

If you read the v2 documentation, fileappend's text is not an optional. In v1, it shows as optional. There's no explaining here. The behavior was changed.
Non optional parameters can't be skipped, you can't skip the text of fileappend because it's not optional. If you need something to be blank, then STATE it as so unless you are completely sure the function will handle that for you, i.e it's an optional/skippable/omitable parameter. Typing nothing/skipping a mandatory parameter DOESNT mean blank, "" MEANS guaranteed blank. This should be more than clear already. It should also be clear v2 tries to move away from the clusterfuck of inconsistency that is v1.
https://lexikos.github.io/v2/docs/comma ... Append.htm
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

20 Dec 2017, 14:02

- @Helgef: Yes, I noticed a problem in the context of ternary operators, but the problem was a more general one. The problem appeared to relate to lists of items between parentheses, and so functions were also worth investigating.
- Admittedly various things that worked in AHK v1 may have given me false expectations of AHK v2.
- However, things like var := 1,, var:=2 or var := (1,,1), that don't work, you may have thought they might work.
- To be clear, () v. nothing gave *different errors*, see 'two different errors' above, the error wasn't simply that the third item in a ternary was missing, there was some other problem. I was trying to work out what it was.
- Thanks for the 'may be omitted from the middle' quote, I saw it in both the AHK v1 and v2 documentations, but it doesn't mention trailing parameters.
- f(()), I guessed right, cheers. (It gives an error.)

- @coffee: FileAppend's Text parameter being optional does come as a surprise. RegWrite's Value parameter is stated as mandatory in the AHK v2 documentation, but appears to be optional.
- AHK itself uses the error message: 'Error: Blank parameter'. Admittedly 'blank' is ambiguous, although it's hard to improve on this term. Potentially it means: no parameter, or, a blank string.
- Btw I believe you may have some interesting recollections on the source code, you seem to have looked at it quite carefully. I'd be most interested on any comments you might have re. parsing scripts, SendInput v. ControlSend, and, hotkey handling, for example. If you wanted to start a new post on any source code views.
- Concerns re. trailing parameters aren't purely academic/imaginary:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



- @Helgef and @coffee: It's true that being able to omit trailing parameters like that, isn't really needed. I was trying to establish what was/wasn't possible with functions. The fact is, that, over the time I've been using AHK, the possibilities have been continually shifting.
- Also, I'm working on a functions tutorial, and it seemed a simple proposition to begin with, but it keeps getting fiddlier and fiddlier, as further nuances emerge.
- Two key points I was looking for:
[when could parameters be omitted in custom functions]
Functions
https://autohotkey.com/docs/Functions.htm
[v1.0.90+]: Optional parameters may be omitted from the middle of the parameter list when calling the function, as shown below. For dynamic function calls and method calls, this requires [v1.1.12+].

[when could parameters be omitted for use with objects][re. ComObjMissing:]
ComObjActive()
https://autohotkey.com/docs/commands/ComObjActive.htm
[v1.1.12+]: This function is obsolete. Instead, simply write two consecutive commas, as in Obj.Method(1,,3)
lexikos
Posts: 5943
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: blanks in ternary operator

21 Dec 2017, 15:54

For commands in v1, there was no difference between omitting a middle parameter and specifying it to be blank, because there were no quote marks. So to allow an empty string, a parameter had to be optional (or require awkward syntax like % "" or %empty%; but expressions didn't exist in the beginning).

For FileAppend, an empty parameter causes it to "touch" the file but not append any text.

Trailing empty function parameters are not supported. I think there was a technical reason for this, but since it's almost completely useless (and therefore more likely to be an error), it doesn't really matter.

You may want to do [,"b","c",], but I think you've already determined from the test in the previous post that it can't possibly work. Empty items aren't stored in arrays, and length is not stored, so the empty fourth item has no effect. This isn't an issue of whether or not blank parameters are allowed at the end.
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

21 Dec 2017, 18:17

- @lexikos: Thanks for adding to this thread and making it unexpectedly interesting again, when I had thought it was essentially over.
- Yes, it's a fundamental point, blank parameters in commands are very common (and necessary), less so with functions. [EDIT:] For commands, omitted parameters and blank strings look the same, for functions they appear different.
- With the FileAppend command, you have two practical options to specify no text, and the latter, % "", is pretty ugly.

Code: [Select all] [Download] GeSHi © Codebox Plus

FileAppend,, % vPath ;AHK v1
FileAppend, % "", % vPath ;AHK v1
FileAppend(, vPath) ;invalid
FileAppend("", vPath) ;AHK v2
- (Funnily enough, I've been using % "" as a hack in my converter script when forcing a blank command parameter into an empty string function parameter.)
- Arguably FileAppend(, vPath) would be justifiable, when FileAppend is used to create a new blank file, since no text is involved, however, I'm perfectly fine with the parameter being mandatory, because it also makes sense that you're appending no text to a file.
- From testing just now, 'FileAppend no text', did not change the created/modified/accessed dates of an existing file, in AHK v1 or v2. Does it 'touch' the file in any other way?
- 'length is not stored'. This is really interesting, I didn't quite think of this. Yes, the count of items is stored (in AHK v1, and possibly in AHK v2, you can retrieve the count by checking the right offset from the object's address), but there is no arbitrary 'length' value to retrieve, it is not stored. (So you cannot have keys 1, 2, 3, but say that the 'length' is 4, there is nowhere to store that.)
User avatar
jeeswg
Posts: 4511
Joined: 19 Dec 2016, 01:58
Location: UK

Re: blanks in ternary operator

24 Jan 2018, 13:41

- One new bit of info re. blank parameters. In the past, one method was invalid, and the other was not, they were both valid for a while, then they swapped (the original valid method now becoming invalid).
- AFAIK this applies to built-in functions, and not custom functions, that output a variable ByRef.

Code: [Select all] [Download] GeSHi © Codebox Plus

;AHK v1
MsgBox, % RegExReplace("aaaa", "a", "", "", 2)
MsgBox, % RegExReplace("aaaa", "a", "",, 2) ;requires v1.1.12+

;AHK v2
MsgBox(RegExReplace("aaaa", "a", "", "", 2)) ;doesn't work in AHK v2
MsgBox(RegExReplace("aaaa", "a", "",, 2))

Links:
"+Resize" option is deleted? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=67&t=43174
jeeswg's functions tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=41823
old versions of AutoHotkey - Page 2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=2&t=30206&p=196415#p196415

- Something separate, but related to which parameters can be omitted.
- Using this approach you can retrieve the MinParams/MaxParams counts for a function.
Func Object
https://autohotkey.com/docs/objects/Func.htm
coffee
Posts: 56
Joined: 01 Apr 2017, 07:55

Re: blanks in ternary operator

24 Jan 2018, 14:33

Code: [Select all] [Download] GeSHi © Codebox Plus

MsgBox(RegExReplace("aaaa", "a", "", "", 2)) ;doesn't work in AHK v2


Bug or not, this change just seems clearer to me (works in 2a083 and not in 2a086). When you do a byref, you want the name of a variable unquoted (the variable itself). An empty value, or a value for that matter, is not a valid name for a variable (or is not a variable), if the documentation says "Specify a variable in which to store the number of replacements that occurred" I think it's reasonable for it to enforce this. Since "" is not a valid variable, but a value.

It's fine for custom functions because you are defining it yourself and hopefully you are aware of what is happening i.e the locally set variable will contain an empty string or value and wont be an alias of another outside variable, and you are handling the value cases.
But for some built-in is probably better to let the user know in case it was a typo/mistake? since what the function does is not up to the user. If the documentation says "a variable in which to store the output", you cant just go ahead and say "" is a valid variable in which to store the output.

For a function call that has a byref parameter
This

Code: [Select all] [Download] GeSHi © Codebox Plus

function("value")

Is not the same as

Code: [Select all] [Download] GeSHi © Codebox Plus

function(variable:="value")

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 2 guests