Implicit Operation Layer
$ enters the implicit operation layer for a value or a type. It exposes low-level operations as
explicit method-like calls: taking references, taking raw pointers, explicit dereference, explicit
move, freeing resources, querying layout, and casting.
Basic Form
Section titled “Basic Form”Value operations are written as value$.op(...):
Int value = 42;
Int& ref = value$.ref();Int* ptr = unsafe { value$.ptr()};Int copied = ref$.get();Type operations are written as Type$.op(...):
Int size = Int$.size();Int align = Int$.align();Int*! value = unsafe { Int$.alloc() };Binding Rules
Section titled “Binding Rules”$ binds to the complete expression on its left:
a$.b // equivalent to (a$).ba.b$ // equivalent to (a.b)$Use parentheses for compound expressions:
Int raw = (left + right)$.as(Int);Do not read $ as part of field access. It first switches the left-hand expression into the implicit
operation layer, then resolves the following operation.
Value Operations
Section titled “Value Operations”| Operation | Meaning |
|---|---|
value$.ref() | returns a shared readonly T& borrow |
value$.mut_ref() | returns a unique mutable T&!; requires a writable place |
value$.ptr() | returns a readonly T*; requires unsafe |
value$.mut_ptr() | returns a writable T*!; requires a writable place and unsafe |
value$.get() | explicitly reads through T^, T&, T&!, T*, or T*! |
value$.set(new_value) | explicitly writes through a T&! or T*! target |
value$.move() | forces an explicit move and invalidates the source |
value$.addr() | gets a raw pointer to the current value; requires unsafe |
value$.dealloc() | frees an object allocated by the default heap allocator; requires unsafe |
value$.as(Type) | low-level cast; requires unsafe for raw pointer casts |
These operations are not ordinary methods. They are built-in operations for references, ownership, raw pointers, allocation, and low-level casts.
Explicit Dereference
Section titled “Explicit Dereference”T^ can auto-dereference when the expected type is its pointee type. T& and T* require explicit
reads; use $.get() when you want to state the pointee read directly:
Int^ owner = new Int(42);Int copied = owner$.get();
Int value = 10;Int& ref = value$.ref();Int copied_ref = ref$.get();Member access is the exception: owner.member can pass through T^ to access the owned value.
Ownership Transfer
Section titled “Ownership Transfer”Non-copyable movable values move by default in value positions. $.move() is the explicit form,
and can also force a move instead of the default copy for a Copyable value:
Int^ a = new Int(42);Int^ b = a$.move();
Int copyable = 1;Int forced = copyable$.move();The source is invalid after the move:
Int value = a$.get(); // error: a has been moved.See Ownership, Borrowing & Lifetimes for the complete ownership rules.
Type Operations
Section titled “Type Operations”Types can enter the implicit operation layer too:
Int size = Int$.size();Int align = Int$.align();Int max_align = Int$.max_align();Int*! value = unsafe { Int$.alloc() };Int*! values = unsafe { Int$.alloc(10) };These operations query layout information or perform low-level allocation. Layout information is also consumed by the backend.
| Operation | Meaning |
|---|---|
Type$.size() | type size |
Type$.align() | ABI alignment |
Type$.max_align() | maximum Jiang type alignment supported by the default allocator |
Type$.alloc() | allocates one uninitialized object and returns Type*! |
Type$.alloc(n) | allocates storage for n uninitialized objects and returns Type*! |
Prefer target-type initialization for normal safe conversions. Do not write ordinary conversions as
$.as(...):
Float f = Float(10);Int i = Int(f);value$.as(Type) only represents a low-level cast: it is closer to interpreting or converting the
current value as the target type. Use it mainly for raw pointers, integer addresses, and FFI. Do not
use it as the normal spelling for numeric conversions, construction, or everyday APIs.
Int address = 0x1000;Int* ptr = unsafe { address$.as(Int*)};Low-level memory operations are gated by the unsafe effect. Use unsafe { ... } when a
small expression or block needs to take raw pointers, cast raw pointers, allocate raw storage, or
explicitly deallocate storage. $.get() and $.set() are not themselves unsafe; the unsafe boundary
is the operation that creates or casts the raw pointer.
Optional Operations
Section titled “Optional Operations”maybe$.some() force-unwraps an optional value:
Int? maybe = 42;Int value = maybe$.some();| Operation | Meaning |
|---|---|
optional$.some() | force-unwraps an optional and returns its T value |
Prefer .some(...) patterns, guard, or ?? in ordinary code:
Int value = maybe ?? 0;Forced unwrap is best reserved for low-level paths where surrounding logic already guarantees a present value.