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.

The principle of automatic tracking is simple -- for example, the call stack actually records dependencies between calls. If we consider A calls B as representing A depends on B, then through the relative positions of A and B on the call stack, we can determine the dependency relationship between A and B.

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 call stacks, eliminating manual observer binding

See Also