Skip to content

SwiftPipeline is a lightweight, functional-style library for Swift that brings the power of threading macros inspired by languages like Clojure.

License

Notifications You must be signed in to change notification settings

Maartz/SwiftPipeline

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SwiftPipeline

Swift Package Manager

SwiftPipeline is a lightweight, functional-style library for Swift that brings the power of threading macros and functional operators inspired by languages like Clojure and Haskell. With clean and expressive operators, SwiftPipeline allows you to thread data through a series of transformations in a concise and readable way.

Features 🎯

Threading Operators

  • Thread-first (=>): Passes the value as the first argument to functions or uses KeyPaths for property extraction
  • Thread-last (=>>): Passes the value as the last argument to functions
  • Thread-as (~=>): Binds a value to a name for custom transformations

Functional Operators

  • FlatMap (<|): Applies functions to optional values or arrays
  • Applicative (<*>): Applies wrapped functions to wrapped values
  • Kleisli composition (>=>): Composes functions that return optionals
  • Alternative (<|>): Provides fallback values for computations
  • Monadic bind (>>-): Chains operations that produce optionals
  • Reverse bind (-<<): Flipped version of monadic bind

Why SwiftPipeline? πŸ€”

Clean and Declarative Code

  • Transform your Swift code into highly expressive and readable pipelines
  • Chain operations in a natural, left-to-right flow
  • Reduce nested function calls and temporary variables
  • Make complex data transformations clear and maintainable

Rich Functional Programming Patterns

  • Combines threading macros from Clojure with functional operators from Haskell
  • Powerful composition with monadic, applicative, and alternative operators
  • Strong type safety while maintaining functional programming elegance
  • Makes optional handling and error propagation elegant

Lightweight and Swift-Native

  • Zero external dependenciesβ€”pure Swift implementation
  • Minimal runtime overhead
  • Small API surface with maximum expressiveness
  • Seamlessly integrates with Swift's type system and standard library

Flexible and Extensible

  • Works with any Swift type, including your custom types
  • Combines beautifully with Swift's KeyPaths
  • Easy to extend with your own operators
  • Perfect for both small scripts and large applications

Battle-Tested Patterns

  • Based on proven functional programming concepts
  • Inspired by decades of FP best practices
  • Makes complex operations predictable and safe
  • Reduces cognitive load when dealing with complex transformations

Great for Teams

  • Makes code intent clear and self-documenting
  • Reduces merge conflicts by encouraging linear transformations
  • Easy to learn, hard to misuse
  • Consistent patterns across your codebase

Whether you're building data pipelines, handling optional chains, or just want cleaner code, SwiftPipeline provides the tools you need without the bloat.

Installation πŸ“₯

Add SwiftPipeline to your project using the Swift Package Manager:

  1. Open your project in Xcode
  2. Go to File > Add Packages
  3. Enter the following repository URL:
    https://github.com/Maartz/SwiftPipeline.git
    
  4. Select the latest version and add the package

Usage πŸ“–

Basic Threading Operators

Thread-first (=>)

struct Person {
    let name: String
    let age: Int
}

let person = Person(name: "Alice", age: 30)
let result = person
    => \.name
    => { $0.uppercased() }
// Output: "ALICE"

Thread-last (=>>)

let numbers = [1, 2, 3]
let result = numbers
    =>> { $0.map { $0 + 1 } }
    =>> { $0.filter { $0 % 2 != 0 } }
    =>> { $0.reduce(0, +) }
// Output: 6

Thread-as (~=>)

let total = 5 
    ~=> { x in x + 10 } 
    => { $0 * 2 }
// Output: 30

Functional Operators

Map (<|)

// With optionals
let double: (Int) -> Int = { $0 * 2 }
let result = double <| Some(5)  // Optional(10)

// With arrays
let numbers = [1, 2, 3]
let doubled = double <| numbers  // [2, 4, 6]

Applicative (<*>)

let maybeDouble: ((Int) -> Int)? = { $0 * 2 }
let result = maybeDouble <*> Some(5)  // Optional(10)

// With arrays
let functions = [{ $0 * 2 }, { $0 + 3 }]
let values = [1, 2]
let results = functions <*> values  // [2, 4, 4, 5]

Alternative (<|>)

let parseNumber: (String) -> Int? = { Int($0) }
let result = parseNumber("invalid") <|> parseNumber("42") <|> Some(0)
// Falls back to valid parsing or default

Monadic Bind (>>-) and Reverse Bind (-<<)

let parseId: (String) -> Int? = { Int($0) }
let findUser: (Int) -> User? = { id in 
    // Find user by id
    id == 42 ? User(id: 42, name: "John") : nil 
}

// Using >>-
let user1 = "42" >>- parseId >>- findUser

// Using -<<
let user2 = findUser -<< (parseId -<< "42")

Complex Examples

Optional Chaining with Alternatives

struct User {
    let id: Int
    let email: String?
}

let validateEmail: (String) -> String? = { email in
    email.contains("@") ? email : nil
}

let result = parseId -<< "42"
    >>- findUser
    >>- { user in user.email >>- validateEmail }
    <|> Some("[email protected]")

Applicative with Computations

let compute: (Int) -> (Int) -> Int? = { x in 
    { y in (x + y) > 0 ? x + y : nil } 
}

let result = (parseId -<< "5" >>- compute) 
    <*> Some(-3) 
    <|> Some(10)

API Reference πŸ“š

Operators

Operator Type Description Example Usage
=> Threading Thread-first value => function
=>> Threading Thread-last value =>> function
~=> Threading Thread-as value ~=> { $0 * 2 }
<| Functional Map function <| optional
<*> Functional Applicative wrappedFn <*> wrappedValue
>=> Functional Kleisli composition f >=> g
<|> Functional Alternative computation1 <|> computation2
>>- Functional Monadic bind value >>- function
-<< Functional Reverse bind function -<< value

Contributing 🀝

We welcome contributions! Feel free to:

  • Submit a bug report or feature request
  • Fork the repository and open a pull request

License πŸ“œ

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgements πŸ™

SwiftPipeline is inspired by the threading macros of Clojure and functional operators from Haskell, aiming to bring similar functionality to the Swift ecosystem.


Enjoy using SwiftPipeline! πŸš€

About

SwiftPipeline is a lightweight, functional-style library for Swift that brings the power of threading macros inspired by languages like Clojure.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages