Skip to content

🚧 Under Construction 🚧

This site is currently under construction. This page is generated by AI and has not undergone thorough review by a human. There may be hallucination!

In fact, for now only /, /reactive, and the llms.txt are carefully crafted by myself.

Signals

Observable values with automatic dependency tracking. Signals are the foundation of reactive programming, evolving from the observer pattern where data sources notify observers of changes.

The traditional observer pattern requires manual binding of subject and observer dependencies. Reactive programming implements automatic tracking of these dependencies on top of that.

A useful mental model is the call stack: if A calls B, then A depends on B. HMR starts from that intuition, but the real implementation is a little broader.

In synchronous code, dependency tracking often looks like "who is currently on the stack". In asynchronous code, HMR keeps that tracking alive through its reactivity context, so dependencies can still be collected across await boundaries.

from reactivity import signal, state

signal creates standalone observables. state is a descriptor for class attributes.

Usage

In HMR, there are two primitives: Signal and Effect. Signal is like a data source:

from reactivity import signal

s = signal(0)  # initial value is 0

print(s.get())  # use .get() to get the value of a signal

s.set(1)  # set its value to 1

print(s.get())

s.update(lambda x: x + 1)  # update using a function

This will print out 0 and then 1. As you can see, Signal is just a data source that tracks changes.

State descriptor

For class attributes, you can use the state descriptor:

class Counter:
    value = state(0)


c = Counter()
c.value = 1  # notifies effects reading Counter.value

Tips

  • get(track=False) reads without subscribing to changes
  • update(updater) modifies the signal using a function
  • batch() groups updates to reduce recomputations
  • Use state for instance attributes, signal for standalone values
  • Signals automatically track dependencies in the current reactive execution context, eliminating manual observer binding

See Also