Types and OOP Properties

Attributes and Properties

Klyn distinguishes between stored implementation state and the public surface that exposes it. In practice, properties are the primary way to publish state cleanly, while attributes or backing fields remain an implementation detail.

Backing Fields
public class Rational:
    private _numerator as Int
    private _denominator as Int

Backing fields usually carry a leading underscore and stay private to the class.

Custom Properties
public property denominator as Int:
    get:
        return this._denominator
    set:
        if value == 0:
            throw Exception("denominator cannot be 0")
        this._denominator = value

Properties can enforce validation or compute values before they expose data.

Auto-Implemented Properties
public class Point:
    public property x = 0
    public property y = 0

Auto-properties are ideal when you want a normal property surface but do not need custom getter or setter logic.

Readonly Properties
public readonly property name as String
public readonly property offset as Int

Use readonly when callers may observe a value but should not mutate it directly.

Observable Signal Properties

Add signal when a property represents observable state. Assignment keeps the same property syntax, but the compiler compares the old and new values and notifies the shared binding engine automatically when the value actually changes. Application code must not call Binding.notify() itself.

import klyn.binding

public class Counter:
    public signal property value as Int = 0

counter = Counter()
mirror = Counter()
Binding.oneWay(counter::value, mirror::value)

counter.value = 1
assert mirror.value == 1

Use signal properties for durable state such as text, selection, progress, or a current value. Use an event instead for a one-shot action such as a click. The complete distinction is covered in Signals vs Events.

Property Access Syntax
r = Rational(1, 3)
print(r.numerator)
r.denominator = 5

Properties use ordinary member access syntax. Callers do not need to know whether the property is auto-implemented or backed by custom getter and setter blocks.

When to Use Each Form
Need Preferred form
Internal implementation state only Private backing field
Simple public state Auto-implemented property
Validation or derived logic Custom property with get and/or set
Read-only public surface readonly property
Observable state for binding signal property