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.
public class Rational:
private _numerator as Int
private _denominator as Int
Backing fields usually carry a leading underscore and stay private to the class.
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.
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.
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.
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.
| 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 |
| Observable but immutable surface | readonly property |