Skip to content

Syntax Sugar

ffredyk edited this page Jul 23, 2026 · 1 revision

Syntax Sugar

SQ# adds optional syntax enhancements over standard SQF. All original SQF syntax still works — these are opt-in conveniences.

1. then Is Optional

// SQF (required):
if (alive _unit) then { _unit setDamage 1; };

// SQ# (both OK):
if (alive _unit) { _unit setDamage 1; };
if (alive _unit) then { _unit setDamage 1; };

2. Trailing Commas Allowed

No more "Unexpected ','" errors:

// SQF — ERROR:
_arr = [1, 2, 3,];

// SQ# — fine:
_arr = [1, 2, 3,];
params ["_a", "_b",];

3. Bracket Array Access

_arr[i] is sugar for _arr select i:

// SQF:
_first = _arr select 0;
_arr set [1, 99];

// SQ# sugar:
_first = _arr[0];
_arr[1] = 99;                  // assignment too!

4. Hash-Select Syntax

_arr # i is alternative to _arr select i:

_first = _arr # 0;             // same as _arr select 0
_name = _map # "name";         // future: hashmap access

5. String Sugar

Escape Sequences

// SQF — no escapes:
_msg = "Line 1" + endl + "Line 2";  // clunky

// SQ#:
_msg = "Line 1\nLine 2";            // \n works
_path = "C:\\Users\\Name";          // \\ = backslash
_quote = "He said \"Hi\"";          // \" = escaped quote

Verbatim Strings

_path = @"C:\Users\Name\Documents";  // no escapes at all

Multi-Line Strings

_help = """
    Usage: mycommand [options]
    
    Options:
      -h, --help     Show this message
    """;

String Interpolation (f-strings)

// SQF:
_msg = format ["Player %1 has %2 HP", _name, _hp];

// SQ#:
_msg = f"Player {_name} has {_hp} HP";

// With expressions:
_msg = f"HP: {_hp}/{_maxHp} ({_hp / _maxHp * 100}%)";

6. _x and _forEachIndex Auto-Binding

No need to declare or params them:

[10, 20, 30] forEach {
    print f"[{_forEachIndex}] = {_x}";
};
// [0] = 10
// [1] = 20
// [2] = 30

_this is also set: [_x, _forEachIndex, originalArray]

7. global Keyword (Explicit)

Bare names without _ are already global (SQF style). global keyword makes it explicit:

score = 100;                   // global (SQF style — implicit)
global HIGH_SCORE = 999;       // global (explicit — same thing)

8. Type Annotations (Optional)

private _hp: number = 100;     // typed local
private _name: string = "";    // for clarity/tooling

9. Strict ==

No type coercion — == is always strict:

// SQF: "hello" == "HELLO" → true (case-insensitive — WHAT?)
// SQ#: "hello" == "HELLO" → false (strict, correct)

// SQF: "123" == 123 → maybe true, maybe error
// SQ#: "123" == 123 → false (string ≠ number)

10. Clear Error Messages

// SQF: undefined variable → "Zero Divisor" or silent fail
// SQ#: Undefined variable '_myVar'

// SQF: type mismatch → "Zero Divisor"
// SQ#: Expected Number, got String

Summary

Feature SQF SQ# Required?
then after if Required Optional No
Trailing commas Error Allowed No
Bracket access _arr[i] No Yes No
Hash-select _arr # i Arma 3 only Yes No
String escapes \n, \t No Yes No
Verbatim strings @"..." No Yes No
Multi-line strings """...""" No Yes No
f-strings f"..." No Yes No
global keyword No Yes No
Type annotations : type No Yes No
Strict == Sometimes Always Yes
Clear error messages Rarely Always Yes

All sugar is optional — standard SQF syntax continues to work. Use what you like.

See Also

SQ# Wiki

Home

Engine Docs

Migration

Commands

Value Constructors

Arithmetic

Comparison

Logic

Array

String

Math

Random

Type & Introspection

HashMap

Code Execution

Concurrency

Scheduler

Thread Safety

Error

Output

Time

Multiplayer

Compiler

Clone this wiki locally