|
|
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.}}
| |