Variables, Constants, and Scopes - CPULL/Dflat GitHub Wiki
A variable name in Dflat must start with a letter and can be composed of letters, numbers, and underscores. They are case-sensitive, and cannot start with an underscore (_).
Dflat uses type-first declarations, but allows type inference when the compiler can deduce the type from the initializer.
-
Explicit declaration:
i32 a = 10 -
Inferred declaration (
var):var count = 10. The type is strictly taken from the initializer. If the compiler cannot decide the type, it results in a compile error (e.g.,var x = nullorvar l = []are invalid). -
Partial inference:
varcan coexist with partial forms likearr a = [...],vec v = [...], ormap m = {...}.
Dflat supports tuple destructuring and multi-variable assignments.
- Multiple returns: a function can return more than one value:
i32 width, string name = getUser()
var userId, var userName = getUser()
existing, _, i32 fresh = f() // Mix existing, discard, new
To discard a value, you can use the discard operator (_).
-
Tuple destructuring: the items of a tuple can be unpacked into separate variables in one statement. Use
_to skip an item:
i32 total, string name, bool enabled = record
i32 onlyCount, _, bool onlyActive = record
-
Tuple item access: items can be read by name (
record.label) or by index (record[1]). The index must be a literal, aconst, or an enum value; an out-of-range index is a compile error. Indexes apply left to right (e.g., in an array of tuples,myTuple[2][1]is the second item of the third tuple). -
Swapping: To swap two values:
x, y = y, x
The right side is evaluated first before any assignment occurs.
Constants are declared using the const keyword (e.g., const u64 SECRET_CODE_PHASE2 = 100). A const represents a read-only value and pointer, offering a global guarantee.
-
Naming rule: Constants declared with
constmust use UPPER_SNAKE_CASE; otherwise, a level 3 warning is emitted.
Dflat uses C#-style block scoping, with specific rules for safety and initialization:
- Block Scoping: Variables declared within a block are visible only within that block and its nested blocks.
- Definite Assignment: Reading a variable before it is assigned on every execution path reads its zero value (null for objects) and triggers a level 1 warning.
- No Shadowing of Locals: Declaring a local variable with the same name as a local variable in an enclosing block is a compile error.
Dflat provides three main categories of conversion:
Keeps the value. Out-of-range values saturate (triggering a level 2 warning), or raise an OutOfRangeCastException if a specific catch exists.
- Real-to-integer conversions follow Rust rules: truncate toward zero,
$+\infty \to \text{max}$ ,$-\infty \to \text{min}$ ($0$ for unsigned), and$\text{NaN} \to 0$ . - Conversion to
time: out-of-range values convert to null and raiseOutOfRangeCastExceptionif caught (silent).
Reinterprets the exact same bits (zero-extends when widening).
-
[char]: an invalid code point maps toU+0000, or raises anInvalidCharacterCodePointExceptionif a specific catch exists. -
Pointers: Created from numbers or other pointers exclusively via transmute (
[*u64]address), and such pointers are automatically marked asunsafe.
Allowed only for widening conversions that keep the value within the same family (e.g., i8 -> i64, r32 -> r64), unsigned-to-wider-signed (u16 -> i32), any scalar type to bool, or any type to string (which calls toStr()). An implicit conversion is equivalent to a cast.
- Numbers equal to
0orNaN,'\0', nulldate/time/clock, zero/nulllapse, null/emptystring, andnullevaluate tofalse. - Anything else evaluates to
true. - Collections and tuples cannot be cast or transmuted to
bool.