Package: rxflow
rxflowIntroductionrxflow is minimalistic library for reactive state management in Python. It is inspired by derivablejsFeaturesSmall, no dependencies- Only 16KB of bytes of pure Pythonic goodness.Push-pull change propagation- Elements are observable and can send change notifications (push). Consumers can then lazily evaluate or dereference the changed element as needed (pull). This approach balances the amount of information in updates with the amount of computation triggered automatically on a variable changing.Glitch-free- Python evaluates from left to right producing a determinstic and glitch-free execution.InstallationInstall rxflow by running:pip install rxflowBackground and MotivationIn computing, reactive programming is a declarative programming
paradigm concerned with data streams and the propagation of change
(Wikipedia)In an imperative programming language like Python a variable assignment likec = a * bis instantaneous.aandbcan be modified immediately after without affectingc>>>a=10>>>b=5>>>c=a*b>>>print(c)50>>>b=10>>>print(c)## This will still be 5050>>>Procedural programming is a sensible default because it allows us to make many simplifying assumptions about variable naming and reuse. However, there are other cases where we may prefer thatcupdates dynamically based on the latest values ofaandb. In other words, we wantcto be"reactive"toaandb.A spreadsheet is essentially a reactive programming interface because we can set some cell $X$ based on the value of one or more another cells $Y1..YN$ and any updates to $Y1..YN$ would automatically propagate to $X$. Both spreadsheets and reactive programming work well for use cases where we need to model lots of variables linked through a complex system of relationships. Solving such tasks procedurally is cumbersome and produces code that is difficult to reason about. rxflow is designed to brige this gap.Basic Example>>>fromrxflowimportVar,Fn,Val>>>a=Var(10)>>>b=Var(5)>>>c=Fn(lambdaa,b:a*b,a=a,b=b)>>>print(Val(c))50>>>b(10)>>>print(Val(c))## This will be 100 because b has changed100>>>SemanticsThere are 3 basic types of elementsVar(variable),Fn(function) andSeq(sequence)AVaris the most basic type of element. AVarcan becreated, updatedanddereferencedfromrxflowimportVar,Val## Create a Varpi=Var(3.1)print(pi)## >> Var(3.1)## Dereference a Varcurr_pi=Val(pi)print(curr_pi)## >> 3.1## Dereference a Varpi(3.1415926535)print(Val(pi))## >> 3.1415926535AFnis a value that is derived from other elements. AFncan becreatedand it's value can beevaluatedfromrxflowimportVar,Fn,Valpi=Var(3.141592)r=Var(42)## Create a Fn from 2 Varsarea=Fn(lambdapi,r:pi*pow(r,2),pi=pi,r=r)## Evaluate a Fnprint(Val(area))## >> 5541.768288## Update one of the varsr(2048)print(Val(area))## >> 13176791.891968ASeqis a sequence of values that are derived from other elements. ASeqcan becreatedand it's values can beaccessedby evaluating the generator.fromrxflowimportVar,Seqdeffibber(N,fib0,fib1):deffibbr(n):ifn==0:returnfib0elifn==1:returnfib1else:returnN[n-1]+N[n-2]returnfibbrf0=Var(0)f1=Var(1)fib=Seq(fibber,fib0=f0,fib1=f1)print(fib[5])## >> 5print(fib[8])## >> 21print(fib[2])## >> 16f0(15)print(fib[2])## >> 16createaSeqby callingSeq(generator, **kwargs)generatoris a function that takesN: Seq, **argsand returns another function that accepts a single intnand returns the nth value in the sequence**kwargsare the named arguments of type (Union[Var,Fn,Seq]) that will be passed to the generatoraccess the elementsof aSeqe.g.my_seq[42]ContributeIssue Tracker:https://github.com/achadha235/rxflow/issuesSource Code:https://github.com/achadha235/rxflowSupportIf you are having issues, please let us know.
We have a mailing list located at:reactivepython@google-groups.comLicenseThe project is licensed under the BSD license.