Skip to content

Instantly share code, notes, and snippets.

View rebcabin's full-sized avatar

Brian Beckman rebcabin

View GitHub Profile

The introduction to Reactive Programming you've been missing

(by @andrestaltz)

So you're curious in learning this new thing called (Functional) Reactive Programming (FRP).

Learning it is hard, even harder by the lack of good material. When I started, I tried looking for tutorials. I found only a handful of practical guides, but they just scratched the surface and never tackled the challenge of building the whole architecture around it. Library documentations often don't help when you're trying to understand some function. I mean, honestly, look at this:

Rx.Observable.prototype.flatMapLatest(selector, [thisArg])

Projects each element of an observable sequence into a new sequence of observable sequences by incorporating the element's index and then transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.

@rebcabin
rebcabin / RxInMathematica
Created April 2, 2012 00:48
Implementation of generateWithTime from the Reactive Framework in Mathematica
ClearAll[generateWithTime, createObserver, observer, observable,
disposable, task];
generateWithTime[
initialState_,
condition_,
resultSelector_,
timeSelector_,
iterate_] :=
Module[{
state = initialState,
@rebcabin
rebcabin / ReactiveMmaWithTest
Created April 3, 2012 23:41
Commented Reactive Mathematica with UnitTest
ClearAll[generateWithTime];
generateWithTime[
initialState_,
condition_,
resultSelector_,
timeSelector_,
iterate_] :=
Module[{
state = initialState,
lastTaskForCleanup,
(*
Cold GenerateWithTime
Rx.Observable.GenerateWithTime = function(
initialState, // : State
condition, // : State -> bool
resultSelector, // : State -> Result
timeSelector, // : State -> int
iterate) // : State -> State
@rebcabin
rebcabin / gridCaptive2.m
Created April 5, 2012 20:12
application of captive2
SetAttributes[gridCaptive2, HoldAllComplete];
dpyCaptive2[{ex_, {}}] := dpyNullary[dpyCaptive2 @ ex];
dpyCaptive2[{a_, {as__}}] := dpyMultiary[dpyCaptive2 @ a, dpyCaptive2 /@ {as}];
dpyCaptive2[number2[ex_]] := dpyQuotedAtom[number2[ex]];
dpyCaptive2[string2[ex_]] := dpyQuotedAtom[string2[ex]];
dpyCaptive2[symbol2[ex_]] := dpyQuotedAtom[symbol2[ex]];
dpyCaptive2[x___] := Throw[Unevaluated @ {x}];
gridCaptive2[expr_] := dpyCaptive2 @ captive2 @ expr;
@rebcabin
rebcabin / captive2.m
Created April 5, 2012 20:09
Much better quoting
SetAttributes[captive2, HoldAllComplete];
captive2[expr_ /; NumberQ @ Unevaluated @ expr] := number2[ToString[expr]]
captive2[expr_ /; (Head @ Unevaluated @ expr === Symbol)] := symbol2[ToString @ Unevaluated @ expr]
captive2[expr_ /; (Head @ Unevaluated @ expr === String)] := string2["\"" <> expr <> "\""]
captive2[head_[args___]] := {captive2 @ head, captive2 /@ Unevaluated @ {args}}
captive2[x___] := Throw @ {x};
@rebcabin
rebcabin / WffTravesties.nb
Created June 17, 2012 05:22
Grammar and anti-parser (travesty generator) for game Wff-n-Prrof
ClearAll[P, Wff, Proposition, Unary, Binary, T,
nonTerminalsFromGrammar, terminalsFromGrammar];
P[Wff] = {{Proposition}, {Unary}, {Binary}};
P[Proposition] = {{"p"}, {"q"}, {"r"}, {"s"}};
P[Unary] = {{"N", Wff}};
P[Binary] = {{"C", Wff, Wff}, {"A", Wff, Wff}, {"K", Wff, Wff}, {"E",
Wff, Wff}};
P[Start] = P[Wff];
ClearAll[nonTerminalsFromGrammar];
@rebcabin
rebcabin / gridrules.m
Created June 17, 2012 05:30
prints nice grid layout of rules in Mathematica
gridRules[rules_] /;
(ListQ[rules] &&
(Length @ rules > 0) &&
(And @@ (((Head @ # === Rule)||(Head @ # === RuleDelayed))& /@ rules))) :=
With[{
keys = #[[1]]& /@ rules,
heads = #[[0]]& /@ rules,
vals = gridRules[#[[2]]]& /@ rules},
Grid[MapThread[{
Style[#1, Bold],
(* This code is released into the public domain by its author, Brian \
Beckman, on 2 Aug 2012. *)
ClearAll[grid, fopts];
ClearAll[allAreRulesQ, noneAreAtomsQ];
(* A "HoldAll" version of the following, with "Unevaluated" \
everywhere, may be required. *)
noneAreAtomsQ[candidates_List] :=
And @@ (Not[AtomQ@#] & /@ candidates);
allAreRulesQ[candidates_List] :=