Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Choose a public API

Mark each public field and method explicitly. Without __init__, the generated field constructor is public only when the class and every field are public. To keep fields private while allowing construction, declare pub def __init__:

Save this module as counter.plenty:

pub class Counter:
    value: i64

    pub def __init__(self, start: i64) -> ():
        self.value = start

    pub def increment(self: &mut Counter) -> Result[(), OverflowError[i64]]:
        self.value = self.value + 1
        Ok(())

    pub def read(self) -> i64:
        self.value

    def __del__(self) -> ():
        drop(print("counter closed"))

Application:

from counter import Counter

def main() -> Result[(), IoError | OverflowError[i64]]:
    mut count = Counter(41)
    count.increment()?
    print(count.read())?
    Ok(())
42
counter closed

The private destructor still runs automatically. Private fields and methods are accessible throughout their module, but not from another module. Reads, writes, and borrows all enforce this. Save the next module as secret.plenty:

pub class Secret:
    value: i64

    pub def __init__(self, value: i64) -> ():
        self.value = value
from secret import Secret

def main() -> Result[(), IoError]:
    item = Secret(42)
    print(item.value)?
    Ok(())
secret.Secret.value` is private

pub also applies to functions, enums, and type aliases. A public enum exposes all its variants. Public signatures cannot mention private classes or enums, even through aliases or containers. Ordinary imports are private bindings; importing a name does not re-export it. Relative imports, wildcards, circular imports, and pub import are not supported yet.

Private fields are still included in automatic printing and equality.

The lifecycle trace uses drop(print(...)) deliberately: cleanup cannot return an error, and a failed diagnostic write must not interrupt cleanup. For output that must succeed, provide an explicit fallible operation and propagate its result before leaving the scope.