All Projects → bow-swift → Bow Arch

bow-swift / Bow Arch

Licence: other
🏛 Functional Architecture in Swift using Bow

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Bow Arch

Zio Logging
Simple logging for ZIO apps, with correlation, context & pluggable backends out of the box.
Stars: ✭ 85 (-48.8%)
Mutual labels:  functional-programming, fp
Test State
Scala Test-State.
Stars: ✭ 119 (-28.31%)
Mutual labels:  functional-programming, fp
Pattern Matching Ts
⚡ Pattern Matching in Typescript
Stars: ✭ 107 (-35.54%)
Mutual labels:  functional-programming, fp
Funland
Type classes for interoperability of common algebraic structures in JavaScript, TypeScript and Flow
Stars: ✭ 46 (-72.29%)
Mutual labels:  functional-programming, fp
Kingly
Zero-cost state-machine library for robust, testable and portable user interfaces (most machines compile ~1-2KB)
Stars: ✭ 147 (-11.45%)
Mutual labels:  architecture, functional-programming
Rambda
Faster and smaller alternative to Ramda
Stars: ✭ 1,066 (+542.17%)
Mutual labels:  functional-programming, fp
Scalajs React
Facebook's React on Scala.JS
Stars: ✭ 1,524 (+818.07%)
Mutual labels:  functional-programming, fp
Bugz
🐛 Composable User Agent Detection using Ramda
Stars: ✭ 15 (-90.96%)
Mutual labels:  functional-programming, fp
Monix
Asynchronous, Reactive Programming for Scala and Scala.js.
Stars: ✭ 1,819 (+995.78%)
Mutual labels:  functional-programming, fp
Sup
Composable, purely functional healthchecks in Scala.
Stars: ✭ 138 (-16.87%)
Mutual labels:  functional-programming, fp
Metalang99
A functional language for C99 preprocessor metaprogramming
Stars: ✭ 152 (-8.43%)
Mutual labels:  functional-programming, fp
Fs2
Compositional, streaming I/O library for Scala
Stars: ✭ 1,998 (+1103.61%)
Mutual labels:  functional-programming, fp
Stm4cats
STM monad for cats-effect
Stars: ✭ 35 (-78.92%)
Mutual labels:  functional-programming, fp
Request Compose
Composable HTTP Client
Stars: ✭ 80 (-51.81%)
Mutual labels:  functional-programming, fp
Flawless
WIP Delightful, purely functional testing no-framework. Don't even try to use it at work!
Stars: ✭ 33 (-80.12%)
Mutual labels:  functional-programming, fp
Clear Config
Scala FP configuration library with a focus on runtime clarity
Stars: ✭ 108 (-34.94%)
Mutual labels:  functional-programming, fp
Frameless
Expressive types for Spark.
Stars: ✭ 717 (+331.93%)
Mutual labels:  functional-programming, fp
D4s
Dynamo DB Database Done Scala-way
Stars: ✭ 27 (-83.73%)
Mutual labels:  functional-programming, fp
Returns
Make your functions return something meaningful, typed, and safe!
Stars: ✭ 2,015 (+1113.86%)
Mutual labels:  functional-programming, fp
Doobie
Functional JDBC layer for Scala.
Stars: ✭ 1,910 (+1050.6%)
Mutual labels:  functional-programming, fp

Bow Arch

Gitter bow-arch Playground

Welcome to Bow Arch!

Bow Arch is a library to architect applications in pure Functional Programming, based on the notion of Comonadic User Interfaces. Please, refer to the project website for extensive documentation.

 

👩‍🏫 Principles

🎨 View as a function of state: Using SwiftUI, we can create user interfaces in a declarative manner, that are a representation of a given state. The library goes even further and promotes the creation of views that are based on immutable state.

🚧 Clear separation of concerns: The core concepts in the library are state, input, dispatcher, view, and component. Each one of them deals with a specific concern, and lets us separate how our code deals with different aspects of application development.

📦 Modularity: The library promotes the creation of components that can be easily reused across the application, or even in other applications. These components are highly composable and let us manage the complexity of large applications.

Testability: Functional code is intrinsically testable; therefore, software created with Bow Arch is easy to test. The library also provides utilities that you can leverage to write powerful and expressive tests.

🧩 Highly polymorphic: The library is based on abstract, parameterized artifacts. This makes this library not only a library to architect your application, but a library to create different architectures by replacing each of these parameters. Nevertheless, specific bindings are provided in the library, so that users do not have to deal with these details.

🧮 Mathematical background: Bow Arch is based on concepts from Category Theory, which brings soundness to the reasoning we can do about our code. Nonetheless, the API of the library hides the complexity of these concepts and users do not need to be experts in this topic to use the library in their applications.

 

💻 How to get it

Bow Arch is available through Swift Package Manager, integrated in Xcode. You only need to use the repository URL on GitHub and the version or branch you would like to use. Alternatively, you can describe this dependency in your Package.swift file by adding the line:

.package(url: "https://github.com/bow-swift/bow-arch.git", from: "{version}")

 

👨‍💻 Usage

Bow Arch lets you architect your application in terms of components that can be reused across applications. Let's go over what you need to create in order to build a stepper component.

📋 State

A component should have a state that is rendered in its view. State is usually modeled using an immutable data structure, typically a struct.

For our stepper component, we can model our state as:

struct StepperState {
    let count: Int
}

📲 Input

Next step is modeling inputs that a component can handle. Inputs are usually described using cases of an enum.

In our ongoing example, the component can receive two inputs, corresponding to tapping on the decrement or increment buttons. These can be modeled as:

enum StepperInput {
    case tapDecrement
    case tapIncrement
}

🎨 View

With state and input defined, we can render a view using SwiftUI. SwiftUI is a declarative framework to describe user interfaces in Swift, with multiple bindings for the different operating systems in the Apple Platforms.

We can describe the view as a function of its state, and use a function to receive inputs:

import SwiftUI

struct StepperView: View {
    let state: StepperState
    let handle: (StepperInput) -> Void

    var body: some View {
        HStack {
            Button("-") {
                self.handle(.tapDecrement)
            }

            Text("\(state.count)")

            Button("+") {
                self.handle(.tapIncrement)
            }
        }
    }
}

🔨 Dispatcher

Inputs new to be transformed into actions that modify the state. This is done at the Dispatcher. Dispatchers are pure functions that receive inputs and produce actions:

typealias StepperDispatcher = StateDispatcher<Any, StepperState, StepperInput>

let stepperDispatcher = StepperDispatcher.pure { input in
    switch input {
    case .tapDecrement:
        return .modify { state in
            StepperState(count: state.count - 1)
        }^

    case .tapIncrement:
        return .modify { state in
            StepperState(count: state.count + 1)
        }^
    }
}

🧩 Component

Finally, we can put everything together as a component:

typealias StepperComponent = StoreComponent<Any, StepperState, StepperInput, StepperView>

let stepperComponent = StepperComponent(
    initialState: StepperState(count: 0),
    dispatcher: stepperDispatcher,
    render: StepperView.init)

Components already conform to SwiftUI View, so they can be used as part of other views, or assigned as the root view of a UIHostingController.

let controller = UIHostingController(rootView: stepperComponent)

 

👏 Acknowledgements

We want to thank Arthur Xavier, Phil Freeman, and Edward Kmett, for their previous work on Comonads and Comonadic UIs in the PureScript and Haskell languages. The usage of optics to break down and compose components is inspired by the use of index and case paths in the Swift Composable Architecture by Stephen Cellis and Brandon Williams. Their work has inspired the creation of this library.

 

⚖️ License

Copyright (C) 2020 The Bow Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].