| 
				   | 
				
| Line 1: | 
Line 1: | 
 | == About writing SQF code without negation ==
  |  | 
 | {{Feature|Informative|'''Important note from the author'''
  |  | 
 | This page is about a '''subjective''' topic. This article was written by someone who is a proponent of avoiding negation wherever that is practical.<br>
  |  | 
 | The author of this article wants to make it 100% clear that code written '''with negation''' is still '''functional''' and capable of getting results.<br>
  |  | 
 | Like every other language, code can be written in multiple styles. One of which is using negation. Another can be to write with limited negation.
  |  | 
 | It all comes down to subjective preferences or how much you care about readability.}}
  |  | 
 | === What is "negation"? ===
  |  | 
 | Negation refers to formulating a sentence in a negative way. Here are some examples:
  |  | 
 | * "do NOT do that!"
  |  | 
 | * "do NOT change that thing!"
  |  | 
 | * "he is NOT happy!"
  |  | 
 | Simply put: any sentence with the word "NOT" in it is using negation.
  |  | 
 | 
  |  | 
  | 
 | === Why care about negation? ===
  |  | 
 | Research has shown ( look it up if you wish ) that the human brain has more difficulty processing sentences with negation in it. Which could lead to the need for reading a sentence multiple times.<br>
  |  | 
 | The same goes for code in any language.
  |  | 
 | 
  |  | 
 | === [[exitWith]] is your friend :) ===
  |  | 
 | To show you why, here is an example of how something could be written '''with''' negation, followed by code '''without''' negation that does exactly the same thing.
  |  | 
 | <sqf>
  |  | 
 | /*
  |  | 
 |    with negation, basic checks on params.
  |  | 
 |    a typical "only continue if all parameters meet the required conditions"
  |  | 
 | */
  |  | 
 | [ controlNull, objNull, 0, true ] call {
  |  | 
 |    if( !isNull( _this select 0 ) ) then {
  |  | 
 |       if( !isNull( _this select 1 ) ) then {
  |  | 
 |          if( !isNil{ _this select 2 } ) then {
  |  | 
 |             if( !isNil{ _this select 3 } ) then {
  |  | 
 |                systemChat "all checks passed";
  |  | 
 |             };
  |  | 
 |          };
  |  | 
 |       };
  |  | 
 |    };
  |  | 
 | };
  |  | 
 | </sqf>
  |  | 
 | <sqf>
  |  | 
 | // same result as example above, but without negation.
  |  | 
 | [ controlNull, objNull, 0, true ] call {
  |  | 
 |    if( isNull( _this select 0 ) ) exitWith {};
  |  | 
 |    if( isNull( _this select 1 ) ) exitWith {};
  |  | 
 |    if( isNil{ _this select 2 } ) exitWith {};
  |  | 
 |    if( isNil{ _this select 3 } ) exitWith {};
  |  | 
 |    systemChat "all checks passed";
  |  | 
 | };
  |  | 
 | </sqf>
  |  | 
 | In the two examples above, avoiding negation makes the code a lot more simple and avoids many nested checks.
  |  | 
 | 
  |  | 
 | === Where avoiding negation becomes...... awkward ===
  |  | 
 | When trying to avoid negation in all types of situations, it can get awkward inside of a function that COULD have a parameter that needs to be handled IF it is something other than Null.<br>
  |  | 
 | As you are probably aware, there is no such thing as a command which checks for the opposite of <sqf inline>isNull</sqf>.
  |  | 
 | For example, in a function where passing a control is '''optional''':
  |  | 
 | <sqf>
  |  | 
 | [ controlNull, true ] call {
  |  | 
 |    params [
  |  | 
 |       ["_this0", controlNull,[controlNull]],
  |  | 
 |       ["_this1", false,[false]]
  |  | 
 |    ];
  |  | 
 |    if NOT(isNull _this0) then { systemChat "the control exists" };
  |  | 
 |    // if it is null, just move on quietly.
  |  | 
 |    if( _this select 1 ) then { systemChat str( random 9000 ) };
  |  | 
 | };
  |  | 
 | </sqf>
  |  | 
 | In the example above, the goal is to just move on if an argument is missing or null. therefore, avoiding negation with <sqf inline>exitWith</sqf> is impossible.<br>
  |  | 
 | If one were to write that same code without negation, '''it would become very complicated, harder to read, and SLOWER''' than simply using <sqf inline>NOT</sqf>.
  |  | 
 | An example of that can be seen below:
  |  | 
 | <sqf>
  |  | 
 | [ player ] call {
  |  | 
 |    if( ( ( str( _this select 0 ) find "NULL" ) == -1 ) then {}; // yes it works, but is a lot slower than just using NOT(isNull)
  |  | 
 | };
  |  | 
 | </sqf> 
  |  | 
 | What that does is it wraps the parameter into a string, which for [[objNull]] would become <sqf inline>"<NULL-object>"</sqf>.<br>
  |  | 
 | Then, simply look for <sqf inline>"NULL"</sqf> in there, and if [[find]] returns -1, it sure is a valid object!
  |  | 
 | 
  |  | 
 | === CONCLUSION ===
  |  | 
 | Yes, it is possible to avoid negation entirely. However, there is a cost. '''Depending on the situation, it can lead to a significant increase in code execution time.'''.<br>
  |  | 
 | Therefore, it would be fair to say that striving to avoid negation can be beneficial to the readability of the code, but it becomes a paradox when avoiding it in any given situation.
  |  | 
 | <br>
  |  | 
 | {{ Feature | Informative | The content of this page is purely meant to invoke a productive discussion or to inspire someone who might also want to use "positive code".<br>
  |  | 
 | '''This page means to only offer up another way of writing SQF code, without invoking any hierarchical '''this is better''' nonsense.}}
  |  |