=! gotcha
a_riot42
Posts: 1,624
I never noticed this before but in Netlinx it seems there are two different 'not equals' operators, either =! or !=
This is very annoying and I don't understand why they would do this. If you are toggling feedback on a touch panel then you need to write this:
If you write this:
it doesn't compile.
However, if you write this:
it compiles fine but doesn't evaluate to true. You have to write:
which compiles fine and give the correct result.
In three years of writing Netlinx code I haven't noticed this before. Anyone know why this is? I am guessing there are some legacy issues involved.
Thanks,
Paul
This is very annoying and I don't understand why they would do this. If you are toggling feedback on a touch panel then you need to write this:
[dvTP, button.input.channel] =! [dvTP, button.input.channel]
If you write this:
[dvTP, button.input.channel] != [dvTP, button.input.channel]
it doesn't compile.
However, if you write this:
if (iSomeInteger != 1){}
it compiles fine but doesn't evaluate to true. You have to write:
if (iSomeInteger =! 1){}
which compiles fine and give the correct result.
In three years of writing Netlinx code I haven't noticed this before. Anyone know why this is? I am guessing there are some legacy issues involved.
Thanks,
Paul
0
Comments
I believe != is a comparison and =! is an assignment. So one is "not equal" and the other "equals not" what something is. With the "equal not" the not isn't really linked to the = "equal" but to the value that follows.
I always thought that the not equal operator in Netlinx is "<>".
I just checked the Netlinx Language Reference Guide and it is "<>". So, if either "!=" or "=!" works correctly as a not equal operator in a logical expression, it's probably an "undocumented feature."
I just checked the AMX website, and the "Netlinx Language Reference Guide" (last updated 12/17/07) still has "<>" as the not equal to relation operator. The only use of "!=" that shows up via search is as part of a string literal. Quite obviously, "!=" works, and as you were taught that in AMX school, I guess it's a supported feature of the language. Personally, I learned Netlinx programming by reading the Language Reference Guide, and I still refer to it from time-to-time. Usually when my Lunesta prescription needs a refill.
This EqualNot That
But instead think of it as:
This Equals NotThat
Paul
!= is the opposite of ==
=! is an assignment, but I use it like this
test = !test
but the compiler doesn't take note of the space between the = and !
Heck, I still use AND and OR instead of && and || I don't get the difference between two key strokes and three.
I don't think so. It appears that"!=" is considered equivalent to" <>". Notice that the following won't compile:
a = (b !< c)
but, of course, this will:
a = !(b < c)
My guess is that in Netlinx the "<>" relational operator is inherited from Axcess. So, it sort of is "old school" from that perspective. I think that "!=" is either an accidental addition to the language or was enabled in order to prevent professional computer science people familiar with C and Java undue angst. Sort of like the way Netlinx allows both "=" and "==" for comparisons, though, that's documented in the language guide and in the Studio language help.
Paul
You have to remember that NetLinx is an interpreted language, and though it looks a lot like C, it is fundamentally different in the way code runs ... it's actually closer to something like Visual Basic that way. The interpretor can do some funky things internally that look like what you expect, but only coincidentally. That fact that it compiles doesn't necessarily mean it is working as expected either, as we all have no doubt found at one time or another.
So how does this code work:
So the compiler treats 3! as one operation which evaluates to 0(?), and then compares 0 to 4?
Paul
If I understand you're logic correctly, you're saying the the '!' following the 3 should be read as 'Not 3' If so, I don't think that is correct in Netlinx.
what you have written should be read 'If 3 is not equal to 4 then ring the bell'
To write Netlinx code to say 'Not 3' you'd write
if(!3) or if(NOT 3)
And, of course we're playing with symantics since a constant in an evaluator never offers a different value.
What you have written will always ring the bell because by definition 3 is never equal to 4.
I fell like I'm back in my college logic courses...
I can't believe I'm getting bogged down in this triviality, but here I am.
"!" in Netlinx is equivalent to "NOT". "!=" apparently functions equivalently to "<>", though "!=" as a relational operator does not seem to be a documented feature of the language. If "!=" worked as an accident because the interpreter somehow treats it as two operations, I'd expect that "NOT=" would work too, but it doesn't. Further, I would expect that "! =" would work also (it doesn't), as space between operators is, as far as I know, ignored.
So, it appears to me that "!=" is treated by Netlinx as a single relational operator which is probably identical to "<>", though I would not claim to have proven that. I suppose the way to tell for sure would be to compare the resulting token files, but that effort far exceeds my level of curiosity
So, once again, this appears to me to be an undocumented feature of the language. My problem with using such things is that I don't believe a user can depend upon an undocumented feature to be supported. If a revision were to break this feature, it wouldn't be a bug, but it probably wouldn't break any "compiled" code, either.
Being relatively new to programming, never doing accent or any other language other then what I've dabbled in since taking on AMX some 4 years ago I'm still trying to figure out what's the right way and what's the wrong way. I'm pretty sure != was taught in PRO I & II and to me it is more readable that "<>" but then again I haven't been using "<>" for the last 10-20 years so "!=" is just what I'm used to. It seems to me that != would be a simpler comparison to go through than if(x < y || x > y) {} which is what "<>" does.
Jeff
I've seen <> used by several "top end" programmers, however I prefer to use != after playing around with C#, so that if someone does a cross-over into netlinx and looks at my code, it's a bit easier to understand (and it also makes me feel like I'm a REAL programmer. ) I think that using any evaluation with words is - "childish", and not "purist" programming - but then again, I don't always stick purist programming rules.
To me it seems that making a comparison to != to <> is like comparing == to = (even though we've gone down that road many of times, and know when / how to use ==.)
Hmmm.. I don't consider <> to be confusing since the other common logicals were >= (greater than OR equal) and <= (less than OR equal) it's basically saying 'any number lesser OR greater than' which means the same as not equal.
I say potato, you say starchy perennial tuber.
The more interesting test would be to see if this works as expected:
if(3 != 3)
The routine, shrunk and simplified here, was supposed to check for a specific byte when the stack pointer had a value of 3 and the byte in that position was 'not = $23'
Interestingly, the fragment was legacy from an AXcent system and was pulled into NetLinx as I am sure many others did early on. This statement worked in AXcess...It didn't work in NetLinx though which is why it confused me!
if ((_sp = 3) && (!data = $23))
{
// do some stuff
}
The fact that ((_sp = 3) && (!data = $23)) worked in AXcess is basically that the compiler was very lazy with syntax format, and assumed certain things from time to time. So, when compiling, it assumed I meant (!(data = $23))
NetLinx is very particular about what it is that you have "said", and it will take you for exactly what you "say" in your code.
In reading the line back in long form, the code fragment (!data = $23) translates as follows:
"The negation of 'data', being equal to $23."
In fact, this will NEVER equate in NetLinx (and shouldn't have in AXcess!)
My remedy -
if ((_sp = 3) && (data <> $23))
{
//knock yourself out
}
Thought it might be appropriate to share this scenario in this thread.
For instance, in a conditional, you would type:
if (x != y) which is evaluated as true if and only if x is not equal to y
If you want to set x to the NOT of y, you would type
x = !y
If the x and y are buttons on a tp, then you would enter,
[tp,btnX] = ![tp,btnY]
Since Netlinx compiler ignores the spaces, what you originally posted is the same as what I have stated here in this last example. In this case, you are not checking a conditional.
You would never write a statement with
x != A + B where A and B are some constants. That would not make any sense.
These are two very different uses of the ! in place of the word NOT.