pointfreeco / swift-overture Goto Github PK
View Code? Open in Web Editor NEW๐ผ A library for function composition.
Home Page: https://www.pointfree.co/episodes/ep11-composition-without-operators
License: MIT License
๐ผ A library for function composition.
Home Page: https://www.pointfree.co/episodes/ep11-composition-without-operators
License: MIT License
I know, SwiftPM does not support iOS yet, but do you want to support it for Carthage?
Currently Carthage works fine until one tries to create an archive and distribute it. Builds work and run on device via Xcode. When converting archive using bitcode option I get this odd error:
warning: Failed to resolve linkage dependency Overture arm64 -> @rpath/libswiftCore.dylib: Could not find MachO for /Applications/Xcode-10.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftCore.dylib
Somehow Overture tries to link to macosx libs of Swift. I was able to resolve this by manually making a separate iOS framework target to the xcodeproj. Not an optimal solution. Any ideas?
Considering the example code from the readme:
Expected behavior
Expected label
to have type UILabel
Actual behavior
label
is of type Void
:
adding return $0
below $0.textColor = .red
however, this results in a lot of unneeded boilerplate when with
is used often.
Replacing with(UILabel())
with update(UILabel)
in the readme. Since update
does result in the expected behavior.
here are some examples of EXC_BAD_ACCESS crashes i'm getting while running my unit tests locally
I fixed the later one by changing:
static var burningDesirePostItem = with(BurningDesireFeedCellItem(), concat(
mut(\.post, .mockRegular)
))
to
static var burningDesirePostItem : BurningDesireFeedCellItem = {
let burningDesireItem = BurningDesireFeedCellItem()
burningDesireItem.post = SGPost.mockRegular
return burningDesireItem
}()
But I'm not sure if i even fully understand what the problem is? I'm assuming that in the static instances, something hasn't been setup for overture, which is expecting to be called in instance methods?
The former one i can't seem to figure out a good way to fix - it seems the last line in:
static let mock = {
return with(
CoachingAPI(),
concat(
mut(\.selectedCoachId, { return .init(String(Coach.mockCoaches.first!.id)) }),
mut(\.subscriptionStatus, { return .enabled }),
mut(\.fetchCoaches, { $0(.success(Coach.mockCoaches)) })
)
)
}()
Is it effectively mocking out the return of fetchCoaches
function on CoachingAPI
?
I think we need to do this with all our OSS. See: pointfreeco/swift-html#27
Hi!
First, thanks for this great library, very helpful!
I was wondering why all the zip(with:)
methods on sequence are not public ? Is it intentional? if yes, why?
I inherited some code, and compile time was crazy (90s - 120s, incremental. 3.5 min new) . So i ran
https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode
on our codebase and all the functions or lazy vars
that used concat
, mut
, with
from swift overture were taking considerable time to compile.
For ex. this stackview
getter was taking >5 seconds to compile!!!!
var stackView = with(UIStackView(), concat(
mut(\.axis, .vertical),
mut(\.isLayoutMarginsRelativeArrangement, true),
mut(\.layoutMargins, UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)),
mut(\.spacing, 16),
mut(\.alignment, .center)
))
Some other examples:
var titleLabel: UILabel = with(UILabel(), concat(
autolayoutStyle,
mut(\.font, .sg_font(size: 24, weight: .bold)),
mut(\.textAlignment, .center),
mut(\.numberOfLines, 0),
mut(\.lineBreakMode, .byWordWrapping)
)
)
var promptLabel: UILabel = with(UILabel(), concat(
autolayoutStyle,
mut(\.font, .sg_font(size: 14, weight: .regular)),
mut(\.textAlignment, .center),
mut(\.numberOfLines, 0),
mut(\.lineBreakMode, .byWordWrapping)
)
)
var stackView: UIStackView = with(UIStackView(), concat(
autolayoutStyle,
mut(\.axis, .vertical),
mut(\.spacing, 7),
mut(\.isLayoutMarginsRelativeArrangement, true),
mut(\.layoutMargins, .init(top: 29, left: 16, bottom: 27, right: 16))
)
)
As this is a new framework/library for me, I'd love to hear if I'm the only one experiencing this?
Writing a function that uses update
, and the compiler complains that I have to annotate my closure as @escaping
to use it with update
, but update
doesn't declare the parameter as @escaping
. Any idea why this is or how to work around this? I can definitely make my updateClient
parameter @escaping
, but it seems like this should be unnecessary.
@MainActor open func testStore(
initialState: Component.State = .mock,
updateClient: (inout Component.Client) -> Void
) -> TestStoreOf<Component> where Component.State: Equatable & HasMock, Component.Client: HasMock {
Component.testStore(
initialState: initialState,
client: update(.mock, updateClient) // Passing non-escaping parameter 'updateClient' to function expecting an @escaping closure
)
}
How about a more 'swifty' API, e.g.
pipe(incr, into: square)
instead of
pipe(incr, square)
A bit confused with the following code:
let baseNavigationBarStyle: (UINavigationBar) -> Void = { ... }
var navigationController: UINavigationController = update(
UINavigationController(rootViewController: controller),
mver(\.navigationBar, baseNavigationBar)
)
fails to compile:
Key path value type 'WritableKeyPath<UINavigationController, UINavigationBar>' cannot be converted to contextual type 'KeyPath<UINavigationController, UINavigationBar>'
The following works fine:
let baseNavigationBarStyle: (UINavigationBar) -> Void = { ... }
let baseNavigationBar: (inout UINavigationBar) -> Void = {
with($0, baseNavigationBarStyle)
}
var navigationController = UINavigationController(rootViewController: controller)
with(navigationController.navigationBar, baseNavigationBarStyle)
I'm trying to update some code that I think could really benefit from a functional style. Here's the current code:
let keyPaths: [WritableKeyPath<Config, String>] // ...
for keyPath in keyPaths {
config[keyPath: keyPath] = try evaluator.evaluateExpression(config[keyPath: keyPath])
}
I've tried a few different approaches and none of them compile because evaluateExpression
is a throwing function, and the overture functions I'm trying to use don't have rethrows
. Here's my best attempt:
let evaluators = keyPaths.map { over($0, evaluator.evaluateExpression) }
for evaluateField in evaluators {
config = try evaluateField(config)
}
rethrows
rethrows
to all of the methods except where it doesn't make sense (I feel like over
and co make sense to have rethrows
)on latest version (xcode 10.1, Swift4.2, Overture 0.3.1), even the basic example from your readme fails:
import Overture
class MyViewController: UIViewController {
let label = with(UILabel()) {
$0.font = .systemFont(ofSize: 24)
$0.textColor = .red
}
}
I think theres ambiguity between the standard and inout versions of with. I would have to annotate the type, e.g let with(UILabel) { (l: inout UILabel) in ...}
to fix it.
But its such an obvious issue, Im sure you or others must have seen it. Any suggestions?
While it's really nice that set
can be derived from over
, the implicit key-path get
is not only doing extra work, but can crash when dealing with implicitly-unwrapped optionals.
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "")
with(formatter, set(\.currencyCode, "USD"))
// crash due to `currencyCode` being a `String!`
We should redefine our setters to not leverage over
.
First of all: thank you for your great work!
Currently there are no overloads for chain
, compose
, pipe
, concat
, ... that work with throwing functions.
If you want, I can open a PR that adds these overloads.
Swift (4.2.1 and 5.0-SNAPSHOT 12/28/18) seems to get really confused about the types of curry'd higher-order functions:
func lowerOrder(_ x: String, _ y: String) { }
lowerOrder is (String, String) -> Void //> true
curry(lowerOrder) is (String) -> (String) -> Void //> true
func higherOrder(_ x: String, _ y: (String) -> Int) { }
higherOrder is (String, (String) -> Int) -> Void //> true
curry(higherOrder) is (String) -> ((String) -> Int) -> Void //> false
print(type(of: curry(higherOrder))) //> "(String) -> ((String) -> Int) -> ()\n"
Is this a problem with curry
? A problem with Swift? A problem with me not grokking some subtlety of function types?
Small intro, before getting to the point:
From some of tweets @stephencelis sent and the overall idea of this library, is to make FP more accessible. There is also this tweet:
If our Prelude library seems a lil too intense with all of its custom operators, then perhaps its Overture is more your tune!
โ Point-Free (@pointfreeco) April 9, 2018
There is indeed a big difference between them, both in terms of size, but also necessary knowledge to use one over the other.
What I propose is to provide the operators counterparts of these functions (e.g. pipe
, composition
). When an Overture
user feels confident about using operators, he/she can still use Overture
to make that switch, instead of importing Prelude
.
In my particular case, I use a very small subset of what Prelude
provides, so Overture
actually makes sense for my use case. Not having operators, is upsetting.
What do you think?
Loved your Overture showcase video and started to apply to one of my project.
I was wondering if there was a better way to initialise \UINavigationBar.*Appearance
to avoid the verbosity and stuttering?
let baseNavigationBarStyle = concat(
mut(\UINavigationBar.standardAppearance, .init()),
mut(\UINavigationBar.compactAppearance, .init()),
mut(\UINavigationBar.scrollEdgeAppearance, .init()),
mver(\UINavigationBar.standardAppearance, opaqueNavigationBar),
mver(\UINavigationBar.compactAppearance!, opaqueNavigationBar),
mver(\UINavigationBar.scrollEdgeAppearance!, opaqueNavigationBar),
mut(\UINavigationBar.titleTextAttributes, .init()),
mut(\UINavigationBar.largeTitleTextAttributes, .init()),
mut(\UINavigationBar.prefersLargeTitles, true)
)
Also setting those titleTextAttributes was a bit confusing.
Here is the full code so far:
import Foundation
import Overture
import AsyncDisplayKit
import UIKit
let neutralTintColor = mut(\UIView.tintColor, .label)
// TabBar
let baseTabBarStyle = concat(
neutralTintColor,
mut(\UITabBar.standardAppearance, .init()),
mver(\UITabBar.standardAppearance, opaqueTabBar)
)
let opaqueTabBar: (inout UITabBarAppearance) -> Void = {
with($0, baseBarAppearance)
}
let opaqueNavigationBar: (inout UINavigationBarAppearance) -> Void = {
with($0, baseBarAppearance)
}
// NavigationBar
let baseNavigationBarStyle = concat(
mut(\UINavigationBar.standardAppearance, .init()),
mut(\UINavigationBar.compactAppearance, .init()),
mut(\UINavigationBar.scrollEdgeAppearance, .init()),
mver(\UINavigationBar.standardAppearance, opaqueNavigationBar),
mver(\UINavigationBar.compactAppearance!, opaqueNavigationBar),
mver(\UINavigationBar.scrollEdgeAppearance!, opaqueNavigationBar),
mut(\UINavigationBar.titleTextAttributes, .init()),
mut(\UINavigationBar.largeTitleTextAttributes, .init()),
mut(\UINavigationBar.prefersLargeTitles, true)
)
// UIBarAppearance
let baseBarAppearance = concat(
mut(\UIBarAppearance.shadowColor, nil),
{ $0.configureWithOpaqueBackground() }
)
let baseNavigationBarAppearance = concat(
baseBarAppearance,
mut(\UINavigationBarAppearance.largeTitleTextAttributes, labelTextAttribute()),
mut(\UINavigationBarAppearance.titleTextAttributes, labelTextAttribute())
)
let labelTextAttribute: () -> [NSAttributedString.Key : Any] = {
[.foregroundColor: UIColor.label]
}
// UIView
let baseNavigationBar: (inout UINavigationBar) -> Void = {
with($0, baseNavigationBarStyle)
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.