niaeashes / ultramarine

Ultramarine is like a Functional Reactive Programming framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ultramarine

Unit Tests

Ultramarine is like a Functional Reactive Programming framework.

Our goal is to:

  • Lightweight and compact.
  • Allows expressions likes functional composition.

But Ultramarine is:

  • NOT Pure FRP Framework (Swift is not for functional programing)

Basic

Here's the basic concepts of Ultramarine.

Ultramarine is based on FRP, so I've written a little bit about FRP, but you don't need to know much about it.

Subject

A Subject is an object that holds a value and can be notified of value changes and can be connected to other Subjects.

let name = "Alice".subject() // Make string subject.
print(name.value) // "Alice"

name <<= "Bob"
print(name.value) // "Bob"

Subject always has the value. You get the value via .value property on each Subject.

Signal

Ultramarine defines Signals as values that are scattered in time, not necessarily It does not focus on time. Unlike Behavior, signals disappear when they are used up. (In FRP, this concept is called an Event.)

An Signal object is like a hole that accepts a value. When the value is raised, it is thrown into Signal.

let signal = Signal<Void>()

signal.fire(())

Signals have no function by themselves. Add a process that is chained from the signal.

let signal = Signal<Void>()
var counter = 0

let sub = signal.sink { counter += 1 }

signal.fire(())
signal.fire(())
print(counter) // 2

sub.cancel()

signal.fire(())
signal.fire(())
print(counter) // 2

Usage

Standard Operators

Arithmetic operators.

Supports: +, -, *, /

let a = 1.subject()
let b = 10.subject()

let c = a + b // c is also Subject<Int>, and always result of `a + b`.

print(c.value) // 1 + 10 = 11

a <<= 10
print(c.value) // 10 + 10 = 20

Supports to combine Subject and Int.

let a = 1.subject()
let b = a * 2 // b is always result of `a * 2`.

print(b.value) // 1 * 2 = 2

a <<= 6
print(b.value) // 6 * 2 = 12

Logical Operators

Supports: &&, ||, !

let c1 = false.subject()
let c2 = false.subject()

let r1 = c1 && c2
let r2 = c1 || c2
let r3 = !c1

print(r1.value, r2.value, r3.value) // false, false, true

c1 <<= true
print(r1.value, r2.value, r3.value) // false, true, false

c2 <<= true
print(r1.value, r2.value, r3.value) // true, true, false

CustomStringConvertible

If Value is CustomStringconvertible, Subject is also CustomStringconvertible.

let a = 42.subject()
print("answer to ultimate question: \(a)") // print '42'

Result

Ultramarine supports Result.

let signal = ResultSignal<Int, Error>()
let sub = signal
    .ifSuccess { print("Answer:", $0) }
    .ifFailure { _ in print("Caught error") }

signal.fire(value: 42)
signal.fire(error: TestError())

sub.cancel()

Result:

Answer: 42
Caught error

About

Ultramarine is like a Functional Reactive Programming framework.

License:MIT License


Languages

Language:Swift 100.0%