Skip to content

Assignments#

Code Example

Runnable Example in Jac and JacLib

# Assignments

with entry {
    # Simple assignment
    x = 10;
    print(x);

    # Chain assignment
    a = b = c = 20;
    print(f"{a} {b} {c}");

    # Let keyword
    let value = 100;
    print(value);

    # Type annotation with value
    age: int = 25;
    name: str = "Alice";
    print(f"{age} {name}");

    # Type annotation without initial value
    result: str;
    result = "computed";
    print(result);

    # Let with type
    let count: int = 5;
    print(count);

    # Augmented arithmetic assignments
    num = 10;
    num += 5;
    num -= 3;
    num *= 2;
    num /= 4;
    num %= 5;
    num **= 2;
    num //= 3;
    print(num);

    # Augmented bitwise assignments
    bits = 12;
    bits &= 7;
    bits |= 3;
    bits ^= 5;
    bits <<= 2;
    bits >>= 1;
    print(bits);

    # Tuple unpacking
    (x, y) = (10, 20);
    print(f"{x} {y}");

    # Swap
    (x, y) = (y, x);
    print(f"{x} {y}");

    # List unpacking
    [p, q, r] = [1, 2, 3];
    print(f"{p} {q} {r}");

    # Nested unpacking
    (m, (n, o)) = (5, (6, 7));
    print(f"{m} {n} {o}");

    # Extended unpacking with *
    (first, *rest) = [1, 2, 3, 4, 5];
    print(f"{first} {rest}");

    (head, *middle, tail) = [10, 20, 30, 40, 50];
    print(f"{head} {middle} {tail}");

    (*beginning, last) = [100, 200, 300];
    print(f"{beginning} {last}");
}
# Assignments

with entry {
    # Simple assignment
    x = 10;
    print(x);

    # Chain assignment
    a = b = c = 20;
    print(f"{a} {b} {c}");

    # Let keyword
    let value = 100;
    print(value);

    # Type annotation with value
    age: int = 25;
    name: str = "Alice";
    print(f"{age} {name}");

    # Type annotation without initial value
    result: str;
    result = "computed";
    print(result);

    # Let with type
    let count: int = 5;
    print(count);

    # Augmented arithmetic assignments
    num = 10;
    num += 5;
    num -= 3;
    num *= 2;
    num /= 4;
    num %= 5;
    num **= 2;
    num //= 3;
    print(num);

    # Augmented bitwise assignments
    bits = 12;
    bits &= 7;
    bits |= 3;
    bits ^= 5;
    bits <<= 2;
    bits >>= 1;
    print(bits);

    # Tuple unpacking
    (x, y) = (10, 20);
    print(f"{x} {y}");

    # Swap
    (x, y) = (y, x);
    print(f"{x} {y}");

    # List unpacking
    [p, q, r] = [1, 2, 3];
    print(f"{p} {q} {r}");

    # Nested unpacking
    (m, (n, o)) = (5, (6, 7));
    print(f"{m} {n} {o}");

    # Extended unpacking with *
    (first, *rest) = [1, 2, 3, 4, 5];
    print(f"{first} {rest}");

    (head, *middle, tail) = [10, 20, 30, 40, 50];
    print(f"{head} {middle} {tail}");

    (*beginning, last) = [100, 200, 300];
    print(f"{beginning} {last}");
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
x = 10
print(x)
a = b = c = 20
print(f'{a} {b} {c}')
value = 100
print(value)
age: int = 25
name: str = 'Alice'
print(f'{age} {name}')
result: str
result = 'computed'
print(result)
count: int = 5
print(count)
num = 10
num += 5
num -= 3
num *= 2
num /= 4
num %= 5
num **= 2
num //= 3
print(num)
bits = 12
bits &= 7
bits |= 3
bits ^= 5
bits <<= 2
bits >>= 1
print(bits)
x, y = (10, 20)
print(f'{x} {y}')
x, y = (y, x)
print(f'{x} {y}')
[p, q, r] = [1, 2, 3]
print(f'{p} {q} {r}')
m, (n, o) = (5, (6, 7))
print(f'{m} {n} {o}')
first, *rest = [1, 2, 3, 4, 5]
print(f'{first} {rest}')
head, *middle, tail = [10, 20, 30, 40, 50]
print(f'{head} {middle} {tail}')
*beginning, last = [100, 200, 300]
print(f'{beginning} {last}')
Jac Grammar Snippet
assignment: KW_LET? (atomic_chain EQ)+ (yield_expr | expression)
          | atomic_chain type_tag (EQ (yield_expr | expression))?
          | atomic_chain aug_op (yield_expr | expression)

aug_op: RSHIFT_EQ
       | LSHIFT_EQ
       | BW_XOR_EQ
       | BW_OR_EQ
       | BW_AND_EQ
       | MOD_EQ
       | DIV_EQ
       | FLOOR_DIV_EQ
       | MUL_EQ
       | SUB_EQ
       | ADD_EQ
       | MATMUL_EQ
       | STAR_POW_EQ

Description

Assignment statements bind values to variables, providing the foundation for storing and manipulating data in your programs.

Simple Assignment

Line 5 shows the most basic assignment: x = 10;. The equals sign = takes the value on the right (10) and binds it to the variable name on the left (x). Line 6 prints the value to verify the assignment worked.

Chain Assignment

Line 9 demonstrates chaining assignments to give multiple variables the same value. This evaluates right-to-left: first 20 is assigned to c, then to b, then to a. All three variables now hold the value 20, as confirmed by printing them on line 10.

The let Keyword

Lines 13-14 introduce the let keyword for explicit variable declaration. While let is optional, it makes your intent clear - you're creating a new variable. This improves code readability, especially in complex scopes.

Type Annotations

Jac supports optional type annotations to document what kind of value a variable should hold:

Pattern Example Line Description
Type with value 17-18 age: int = 25; declares and assigns
Type without value 22-23 result: str; declares for later assignment
Let with type 27 let count: int = 5; combines declaration and typing

Lines 17-18 show annotating variables with their types: age: int = 25 and name: str = "Alice". These annotations serve as documentation and enable type checking tools to catch errors.

Lines 22-23 demonstrate declaring a variable with a type but without an initial value. Line 22 declares result: str, then line 23 assigns it the value "computed".

Augmented Assignment Operators

Instead of writing x = x + 5, you can use augmented assignment: x += 5. These operators combine an operation with assignment:

graph LR
    A[num = 10] --> B[num += 5]
    B --> C[num -= 3]
    C --> D[num *= 2]
    D --> E[num /= 4]
    E --> F[num %= 5]
    F --> G[num **= 2]
    G --> H[num //= 3]
    H --> I[Final: 1]

Lines 31-39 show all arithmetic augmented assignments:

Operator Line Meaning Effect on num
+= 32 Add and assign 10 + 5 = 15
-= 33 Subtract and assign 15 - 3 = 12
*= 34 Multiply and assign 12 * 2 = 24
/= 35 Divide and assign 24 / 4 = 6.0
%= 36 Modulo and assign 6.0 % 5 = 1.0
**= 37 Power and assign 1.0 ** 2 = 1.0
//= 38 Floor divide and assign 1.0 // 3 = 0.0

Lines 42-48 demonstrate bitwise augmented assignments:

Operator Line Operation
&= 43 Bitwise AND
\|= 44 Bitwise OR
^= 45 Bitwise XOR
<<= 46 Left shift
>>= 47 Right shift

Tuple Unpacking

Lines 51-52 show unpacking a tuple into multiple variables. The tuple (10, 20) on the right is unpacked, assigning 10 to x and 20 to y in a single statement. This is much cleaner than two separate assignments.

The Swap Pattern

Line 55 demonstrates the classic swap using tuple unpacking. This swaps the values of x and y without needing a temporary variable. If x was 10 and y was 20, they become 20 and 10 respectively.

List Unpacking

Lines 59-60 show that lists can also be unpacked. This works identically to tuple unpacking - the values from the list are distributed to the variables in order.

Nested Unpacking

Lines 63-64 demonstrate unpacking nested structures. The outer tuple contains 5 and another tuple (6, 7). Variable m gets 5, while the inner tuple is unpacked with n getting 6 and o getting 7.

Extended Unpacking with Asterisk

The * operator captures remaining elements into a list:

Pattern Line Example Result
Rest elements 67 (first, *rest) = [1, 2, 3, 4, 5] first=1, rest=[2,3,4,5]
Middle elements 70 (head, *middle, tail) = [10, 20, 30, 40, 50] head=10, middle=[20,30,40], tail=50
Beginning elements 73 (*beginning, last) = [100, 200, 300] beginning=[100,200], last=300

Line 67 shows (first, *rest) where first captures the first element and rest captures everything else as a list.

Line 70 demonstrates (head, *middle, tail) where the asterisk variable captures all elements between the first and last.

Line 73 shows (*beginning, last) where the asterisk comes first, capturing all elements except the last one.

Practical Applications

Unpacking is particularly useful for: - Function returns: Extracting multiple return values - Data processing: Separating headers from data rows - Pattern matching: Pulling apart structured data - Swapping: Exchanging values elegantly

The combination of simple assignments, type annotations, augmented operators, and unpacking patterns gives you powerful tools for managing data in your Jac programs.