{"id":19031082,"url":"https://github.com/alexito4/flow","last_synced_at":"2025-10-07T06:23:01.941Z","repository":{"id":57889084,"uuid":"443857044","full_name":"alexito4/Flow","owner":"alexito4","description":"🌊 Let your code flow. Extension methods for fluent syntax in Swift.","archived":false,"fork":false,"pushed_at":"2022-01-22T10:08:13.000Z","size":26,"stargazers_count":106,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T16:24:14.780Z","etag":null,"topics":["fluent-api","scope-functions","swift","syntactic-sugar","thenable","using","with"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexito4.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-02T19:53:14.000Z","updated_at":"2025-03-27T14:42:58.000Z","dependencies_parsed_at":"2022-08-26T13:12:11.818Z","dependency_job_id":null,"html_url":"https://github.com/alexito4/Flow","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexito4%2FFlow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexito4%2FFlow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexito4%2FFlow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexito4%2FFlow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexito4","download_url":"https://codeload.github.com/alexito4/Flow/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250468756,"owners_count":21435536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fluent-api","scope-functions","swift","syntactic-sugar","thenable","using","with"],"created_at":"2024-11-08T21:21:21.276Z","updated_at":"2025-10-07T06:22:56.891Z","avatar_url":"https://github.com/alexito4.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flow\n\n[![Build \u0026 Test](https://github.com/alexito4/Flow/actions/workflows/ci.yml/badge.svg)](https://github.com/alexito4/Flow/actions/workflows/ci.yml)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Falexito4%2FFlow%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/alexito4/Flow)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Falexito4%2FFlow%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/alexito4/Flow)\n\n🌊 Let your code *flow*.\n\nThis library provides a bunch of extension methods for a better fluent syntax in Swift. This style is very useful for some operations that benefit from being able to be chained (composed) together.\n\n## Functionality\n\n- `.then` to configure reference and value types. Useful for configuration at the point of initialization.\n\n- `.mutate` in place value types.\n- `.let` to transform an object into another.\n- `.do` to perform multiple actions with the same object.\n- Free function variants, for when you prefer this syntax or don't want to conform to the protocol:\n  - `with` (similar to `.then`)\n  - `withLet` (similar to `.let`)\n- `run` as an alternative to immediately executed closures.\n\n## `.then`\n\nUse `.then` to perform an object configuration inline. It applies statements in the closure to the object. It's very useful to set the properties of an object when defining it.\n\n```swift\nlet label = UILabel().then {\n  $0.text = \"Hello\"\n  $0.textColor = .red\n  $0.font = .preferredFont(forTextStyle: .largeTitle)\n  $0.sizeToFit()\n}\n\nlet size = CGSize().then {\n\t$0.width = 20\n}\n```\n\n\u003e There are two overloads of this method provided. One that works on `AnyObject` (a.k.a. classes) and another that operates on `Any` (intended for value types). The compiler picks the correct one appropriately.\n\n- In the closure you get a reference to `self` or an `inout` copy in case of value types.\n- It returns the same reference to the object, or the mutated copy for value types.\n\nInfluences:\n\n- [Then.with](https://github.com/devxoul/Then/blob/master/Sources/Then/Then.swift#L42)\n- [Kotlin.apply](https://kotlinlang.org/docs/scope-functions.html#apply) and [Kotlin.also](https://kotlinlang.org/docs/scope-functions.html#also)\n\n## `.mutate`\n\nMutates a value **in place**. It s like `.then` but applies to `self` instead of a new copy. The value needs to be defined as a `var`.\n\n```swift\nview.frame.mutate {\n  $0.origin.y = 200\n  $0.size.width = 300\n}\n```\n\n- In the closure you get an `inout` reference to `self` .\n- It returns nothing.\n\n\u003e This should be used only for value types. For reference types is recommended to use `.then`.\n\n## `.let`\n\nYou can think of `.let` as a `map` operation but for all the types (not only for *Functors*). It lets you transform the object into an object of another type.\n\n```swift\nlet dateString: String = Date().let {\n    let formatter = DateFormatter()\n    return formatter.string(from: $0)\n}\n```\n\nIt works especially well for type conversions based on initializers:\n\n```swift\nlet number: Int? = \"42\".let(Int.init)\n```\n\n\u003e Don't overuse this when you can use just plain dot syntax. You can use it to access a member of the object `Date().let { $0.timeIntervalSince1970 }` but that's just the same as `Date().timeIntervalSince1970`. \n\n- You get a reference to `self` in the closure.\n- It returns the object returned in the closure.\n\nInfluences:\n\n- Swift's own `let` declaration.\n- [Kotlin.let](https://kotlinlang.org/docs/scope-functions.html#let) and [Kotlin.run](https://kotlinlang.org/docs/scope-functions.html#run).\n\n##  `.do`\n\nUse this method to perform multiple actions (side effects) with the same object. It helps to reduce the verbosity of typing the same name multiple times.\n\n```swift\nUserDefaults.standard.do {\n    $0.set(42, forKey: \"number\")\n    $0.set(\"hello\", forKey: \"string\")\n    $0.set(true, forKey: \"bool\")\n}\n```\n\nThis behaves like other methods if you discard their return, but is preferred to use `do` to convey the intention better. It also lets you avoid writing the `return` on some occasions.\n\n- You get a reference to `self` in the closure.\n- It returns nothing.\n\nInfluences:\n\n- [Then.do](https://github.com/devxoul/Then/blob/master/Sources/Then/Then.swift#L56)\n\n## `.debug`\n\nBy default, it prints `self` to the console. This method is useful for debugging intermediate values of a chain of method calls.\n\n```swift\nlet result = Object()\n   .then { ... }\n   .debug(\"prefix\")\n   .let { ... }\n   .debug()\n```\n\n- You get a reference to `self` in the closure.\n- It returns the same object without touching it.\n\n## Free function `with`\nExecutes a closure with the object. This free function it's a substitute for `.then` when you can't use the method or if you prefer the free function style.\n\n```swift\nlet label = with(UILabel()) {\n    $0.text = \"Hello\"\n    $0.textColor = .red\n    $0.font = .preferredFont(forTextStyle: .largeTitle)\n    $0.sizeToFit()\n}\n```\n\n- You get a reference to an `inout` copy of `self` in the closure.\n- It returns the returned object in the closure.\n\nInfluences:\n\n- [Overture.with](https://github.com/pointfreeco/swift-overture#with-and-update)\n- [Kotlin.with](https://kotlinlang.org/docs/scope-functions.html#with)\n- Many other languages have a `with` or `using` function.\n\n## Free function `withLet`\nVariant of `with` that let's you return a different type. It's a free function alternative of `let`.\n\n## Free function `run`\nExecutes a closure of statements, useful to be used when you need an expression. This is like making a closure and invoking immediately but sometimes is clearer to have a specific name for it.\n\n```swift\nlet result = run { ... } // same as { ... }()\n```\n\nInfluences:\n\n- [Kotlin.run](https://kotlinlang.org/docs/scope-functions.html#run)\n\n\n## Supported Types\n\nSince Swift doesn't let us extend non-nominal types like `Any` we need to conform each type to the `Flowable` protocol. \n\nThe library provides out of the box conformances for a bunch of Standard Library, Foundation and UIKit types. See [Conformances.swift](/Sources/Flow/Conformances.swift) for the entire list.\n\nYou can conform any type yourself by just extending it:\n\n```swift\nextension YourType: Flowable {}\n```\n\n\u003e Note that you can use the free function variants without the types conforming to the protocol.\n\n## Influences\n\n- [devxoul/Then](https://github.com/devxoul/Then)\n- Functional style approaches (like [Overture](https://github.com/pointfreeco/swift-overture))\n- Kotlin [Scope Functions](https://kotlinlang.org/docs/scope-functions.html). Note that Swift can't \"rebind self\" inside a closure, so most of Kotlin's scope functions are redundant.\n- Other languages that have a similar `with` or `using` functions.\n\n# Author\n\nAlejandro Martinez | https://alejandromp.com | [@alexito4](https://twitter.com/alexito4)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexito4%2Fflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexito4%2Fflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexito4%2Fflow/lists"}