Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Reactive Programming in Practice

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →
Ana Betts
October 17, 2014

Functional Reactive Programming in Practice

Talk given at StrangeLoop 2014

Ana Betts

October 17, 2014

Transcript

41 slides
  1. Rx Primitives Creating Observables: Observable.Return(42) Transforming Observables: something.Select(x => x

    * 5) Changing Contexts: something.ObserveOn(RxApp.Ma inThreadScheduler)
  2. ReactiveUI Primitives WhenAny: Observe properties of objects ToProperty: creates read-only

    derived properties from Observables Command: an abstraction to invoke and marshal an asynchronous method Observable Lists: mutable lists whose changes can be Observed
  3. WhenAny this.WhenAny(x => x.Sha, x => x.Value) .Select(sha => sha

    == null || sha == unknownSha ? "(n/a)" : sha.Length > 7 ? sha.Substring(0, 7) : sha) .ToProperty(this, x => x.ShortSha, out shortSha);
  4. Commands LoadUsersAndAvatars = ReactiveCommand.CreateAsyncTask(async _ => { var users =

    await LoadUsers(); foreach(var u in users) { u.Avatar = await LoadAvatar(u.Id); } return users; }); LoadUsersAndAvatars.ToProperty(this, x => x.Users, ref users); LoadUsersAndAvatars.ThrownExceptions .Subscribe(ex => this.Log().WarnException("Failed to load users", ex));
  5. Observable Collections public class TweetsListViewModel : ReactiveObject { ReactiveList<Tweet> Tweets

    = new ReactiveList<Tweet>(); IReactiveDerivedList<TweetTileViewModel> TweetTiles; IReactiveDerivedList<TweetTileViewModel> VisibleTiles; public TweetsListViewModel() { TweetTiles = Tweets.CreateDerivedCollection( x => new TweetTileViewModel() { Model = x }, x => true, x => x.CreatedAt); VisibleTiles = TweetTiles.CreateDerivedCollection( x => x, x => !x.IsHidden); } }
  6. Elm and ReactiveUI comparisons · Both effectively use time-varied values

    (i.e. Behaviors) · Elm helps you with scheduling and ordering, Rx makes you think about it explicitly · Elm disallows signals-of-signals, Rx lets you use them (but doesn't provide any help with it)
  7. A Consistent Model of Asynchrony · Imperative code has 1030534x

    ways to model asynchrony (callbacks, events, promises) · Modeling asynchronous code in tests is actually possible
  8. A Powerful Model of Asynchrony · Describing complicated policies of

    asynchronous operations become sane to write · Discrete UI concepts can be written succinctly
  9. Expressing Complicated UI Intent // Dismiss the undo flash after

    a certain amount of time. // NB: The logic here is, "Show the flash for at *least* 5 // seconds. If the user does any UI action after that, *or* // it's been a super long time, dismiss the flash" Observable.Timer(TimeSpan.FromSeconds(5.0), RxApp.MainThreadScheduler) .SelectMany(_ => Observable.Amb( anyUIAction.Take(1), Observable.Timer(TimeSpan.FromSeconds(20.0), RxApp.MainThreadScheduler).SelectUnit())) .TakeUntil(ex.DoUndo) .Where(x => ex.Ok.CanExecute(null)) .Subscribe(_ => ex.Ok.Execute(null));
  10. [Fact] public void CommitterDateTakesPrecedenceForRelativeTime() { new TestScheduler().With(sched => { var

    c = new CommitModel(Mock.Of<IAvatarProvider>()); sched.Start(); c.AuthorDate = sched.Now; sched.Start(); Assert.Equal("just now", c.FriendlyRelativeCommitTime); sched.AdvanceBy(TimeSpan.FromMinutes(5)); c.CommitterDate = sched.Now; sched.AdvanceBy(TimeSpan.FromMinutes(5)); c.UpdateCommitTime.Execute(null); sched.Start(); Assert.Equal("5 minutes ago", c.FriendlyRelativeCommitTime); }); }
  11. "I have no idea how anyone can write apps without

    Rx" — Every developer I've met who gets good at RxUI / RAC
  12. Team Education · Most developers haven't used RxUI / RAC

    before, every developer we hire has to take The RAC Class™ · New developers will fall back onto writing imperative code
  13. Logging and tracing · Setting up a good logging framework

    is critical · Log Signals that end in an error · Signals are natively dual-point logging (i.e. they represent a Span)

More Decks by Ana Betts

Other Decks in Programming