'force an expression' and 'can be an expression'

Report problems with documented functionality
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

'force an expression' and 'can be an expression'

19 Sep 2017, 10:22

I would have expected that force an expression, where available, would make a parameter work as it does in a function. This does not seem to be the case for certain parameters in certain commands, I believe these are the 'can be an expression' parameters.

I must admit that I had no reason to expect that 'force an expression' would work differently on some parameters, compared to others, and this has come as a big shock. So this surprise, could well apply to other users also.

It had seemed that the intention of force expression, was to allow the use of simple unambiguous expression syntax in commands, precisely to avoid the parameter ambiguity you get in commands.

This also has potential ramifications for automated conversion to AHK v2. I.e. previously I could go by the rule that: if a parameter starts with '% ', then you can remove the '% ', no further conversion necessary.

Thanks for reading.

Example:

Code: Select all

q::
a := "5"
5 := 10
MsgBox, % %a% ;10 ;as expected

vText := "abcdefghijklmnopqrstuvwxyz"
StringLeft, vOutput, vText, % %a%
MsgBox, % vOutput ;abcde (expected: abcdefghij)
StringLeft, vOutput, vText, % (%a%)
MsgBox, % vOutput ;abcdefghij as expected
return
Some further discussion:
Combining variables and when to use % - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=37162
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: 'force an expression' and 'can be an expression'

19 Sep 2017, 11:22

Well put jeeswg, I will follow this with interest, ofc :wave:.
Regarding your link, to save others some time, the related discussion started here.

Cheers.
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: 'force an expression' and 'can be an expression'

20 Sep 2017, 01:09

jeeswg, In the other thread you're talking about this behavior not being documented, only I believe it is. Ironically you linked this page in that discussion, only it appears, you either didn't read the section immediately below the passage you mentioned, or you comprehend it differently than I do. Expression Operators in descending precedence order, where it says in the %var% section,
For backward compatibility, command parameters that are documented as "can be an expression" treat an isolated name in percent signs (e.g. %Var%, but not Array%i%) as though the percent signs are absent. This can be avoided by enclosing the reference in parentheses; e.g. Sleep (%Var%).
To me this means, using sleep as an example,
Sleep %var%
Sleep % var
Sleep % %var%
are all identical, and resolve to:
Sleep var

It is however, a little unclear perhaps, () should be documented as the way to force an expression for "can be an expression" type arguments, since:
Sleep % (%var%)
Sleep (%var%)
are also identical to each other i.e. the leading % isn't what is forcing the expression for these particular types, they're actually more like the IF (expression), exception.
just me
Posts: 9442
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: 'force an expression' and 'can be an expression'

20 Sep 2017, 02:14

Jeeswg also linked the other related part of the docs here:
Force an expression: An expression can be used in a parameter that does not directly support it (except OutputVar parameters) by preceding the expression with a percent sign and a space or tab. ...
Parameters that are documented as "can be an expression" directly support expressions, so it's redundant to "force an expression" and the single % sign can be ignored when the script is loaded:

Code: Select all

#NoEnv
#Persistent
Var := "5"
Text := "abcdefghijklmnopqrstuvwxyz"
StringLeft, Output, Text, % %Var%
ListLines
Return

Esc::ExitApp
ListLines wrote:

Code: Select all

003: Var := "5"
004: Text := "abcdefghijklmnopqrstuvwxyz"
005: StringLeft,Output,Text,%Var%
006: ListLines
jeeswg wrote:This also has potential ramifications for automated conversion to AHK v2. I.e. previously I could go by the rule that: ...
That's no sufficient reason to change the current behaviour.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: 'force an expression' and 'can be an expression'

26 Oct 2017, 06:47

@just me:
Parameters that are documented as 'can be an expression' directly support expressions, but in an unusual way. Without the '% ' such parameters should continue to act in that unusual way, but with the '% ' which is used to 'force an expression', it should indeed 'force an expression'.

@all:
I started this thread to document the problem, whether it is resolved or not, it affects script writing and conversion, and also in my case, the writing of a beginner tutorial.

Clearly it would be better if 'force an expression' would always mean that the parameters behaved just like they did in an expression, this is what most users would expect, and so far I have seen nothing in the documentation which explains that 'force an expression' is currently inconsistent and can't be relied upon (to make a parameter behave just like it would in an expression).

Here are two attempts at listing which commands/parameters are affected:

Command syntax - "This parameter can be an expression" - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 418#p41418
[EDIT: this file no longer exists, it was split into separate AHK v1/v2 files:]
Scintillua-ahk/ahk.lua at master · Lexikos/Scintillua-ahk · GitHub
https://github.com/Lexikos/Scintillua-a ... k.lua#L818
[EDIT: see here instead:]
GitHub - Lexikos/Scintillua-ahk: AutoHotkey lexers for Scintillua + SciTE4AutoHotkey
https://github.com/Lexikos/Scintillua-ahk

When you 'force an expression' by prefixing a command parameter with '% ', you expect it to act like an expression.

Code: Select all

;current situation: these are equivalent:
PostMessage, a, b, c, Edit1, A
PostMessage, %a%, % %b%, % %c%, Edit1, A  
PostMessage, % %a%, % %b%, % %c%, Edit1, A ;old behaviour: 'can be an expression' takes precedence over 'force an expression'
PostMessage(a, b, c, "Edit1", "A")

;it should be that these are equivalent:
PostMessage, (%a%), (%b%), (%c%), Edit1, A
PostMessage, % (%a%), % (%b%), % (%c%), Edit1, A
PostMessage, % %a%, % %b%, % %c%, Edit1, A ;new behaviour: 'force an expression' takes precedence over 'can be an expression'
PostMessage(%a%, %b%, %c%, "Edit1", "A")
Did anyone seriously expect that 'can be an expression' would take precedence over 'force an expression'?

Btw using the information from the link and by searching the help file for 'can be an expression' and 'can be expressions', I can greatly improve my script converters.
Last edited by jeeswg on 26 Jan 2018, 20:44, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: 'force an expression' and 'can be an expression'

26 Oct 2017, 07:45

I disagree. Currently you don't have to bother whether a parameter can be an expression or not if you always use %% to mark variables.
With your changes the user has to check whether a parameter can be an expression or not - your suggestion would make AHK unuseable.
And actually you are wrong. Currently 'can be an expression' is only used if you directly put an expression into the parameter and doesn't affect the 'force an expression' mode.
Therefore it is correct to say that 'force an expression' takes precedence over 'can be an expression' where as your new suggestion is the opposite.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: 'force an expression' and 'can be an expression'

26 Oct 2017, 13:01

Clearly it would be better if 'force an expression' would always mean that the parameters behaved just like they did in an expression
It is funny you say that jeeswg, because the documentation on how expressions work, states that the expression %var% in a parameter which can be an expression, behaves like the %% where absent :thumbup:.
  • So is this a bug? No!
  • Is this a problem with the language? Yes, but far from the most significant one.
  • What to do? Forget about it, and use v2. :thumbup:
Cheers.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: 'force an expression' and 'can be an expression'

28 Oct 2017, 06:40

@ nnnik, hello :wave: . I'm not sure I follow your comments. Please correct me if I'm missing the point, but the suggestion is that

Code: Select all

Command, % %var%	; Forcing an expression - should cause a double deref even if the parameter can be an expression, it currently doesn't
should behave as

Code: Select all

Command, (%var%) ; This is a double deref
when the parameter can be an expression. As AHK is now, If you want to do a double deref in a command parameter, you need to check if the parameter can be an expression, or blindly force an expression and add the round brackets (because I can't spell). There wouldn't be any change for this case,

Code: Select all

Command, %var% ; The suggestion is not that this would cause a double deref
Now, in the ask for help section we may often see very creative variants of expressions, so it is entirely possibly that there is code out there which works by luck, because Command, % %var% works as Command, var, but other than such cases, I don't think the suggestion is going to break anything. However, the documention mentions backwards-compability in relation to this matter, and I'm not familliar enough with the history of the language to assess if that also applies to when one forces an expression. From my point of view, jeeswgs suggestion would swap one inconsistency for another, but for the better. I still don't think it is a bug though, and because v2 already solves most of these issues, I think it would be a waste of time if someone would do any work on this. :lol:

Cheers.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: 'force an expression' and 'can be an expression'

28 Oct 2017, 06:48

I'm not making a suggestion. How did you reach that conclusion?
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: 'force an expression' and 'can be an expression'

28 Oct 2017, 06:57

No, I mean that I do not follow your comments in relation to jeeswgs suggestion. Edit: I see that is was unclear, sorry :oops:
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: 'force an expression' and 'can be an expression'

28 Oct 2017, 07:03

Hmm yeah it seems I misunderstood jeeswgs post.
Recommends AHK Studio
guest3456
Posts: 3462
Joined: 09 Oct 2013, 10:31

Re: 'force an expression' and 'can be an expression'

28 Oct 2017, 10:08

Helgef wrote:
Clearly it would be better if 'force an expression' would always mean that the parameters behaved just like they did in an expression
It is funny you say that jeeswg, because the documentation on how expressions work, states that the expression %var% in a parameter which can be an expression, behaves like the %% where absent :thumbup:.
  • So is this a bug? No!
  • Is this a problem with the language? Yes, but far from the most significant one.
  • What to do? Forget about it, and use v2. :thumbup:
Cheers.
^
this pretty much sums it up

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

Re: 'force an expression' and 'can be an expression'

02 Nov 2017, 10:42

@Helgef:
Variables and Expressions
https://autohotkey.com/docs/Variables.htm#Operators
For backward compatibility, command parameters that are documented as "can be an expression" treat an isolated name in percent signs (e.g. %Var%, but not Array%i%) as though the percent signs are absent. This can be avoided by enclosing the reference in parentheses; e.g. Sleep (%Var%).
But which says nothing about what happens when you 'force an expression', e.g. Sleep % %Var%.

Thanks, your 'should behave as' post, neatly summarises the problem, and has led me to write this summary:

Code: Select all

;this is about 'force an expression',
;the use of % to make a parameter in a command,
;behave as it would as a parameter in a function,
;this is about how the following line behaves:
Command, % %var%

;sometimes it behaves like this (logical), like an expression in a function:
CommandAsFunc(%var%)

;sometimes it behaves like this (illogical), unlike an expression in a function:
CommandAsFunc(var)

;it behaves in the illogical way for parameters listed as
;'can be an expression'

;I have so far found nothing in the documentation
;that states that when you 'force an expression',
;it doesn't always 'force an expression'
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 20 guests