Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FunctionalHandler API Design #1

Open
maximkrouk opened this issue Oct 29, 2020 · 5 comments
Open

FunctionalHandler API Design #1

maximkrouk opened this issue Oct 29, 2020 · 5 comments
Labels
discussion A place to explore ideas

Comments

@maximkrouk
Copy link
Member

A place to discuss FunctionalHandler API

@maximkrouk maximkrouk added the discussion A place to explore ideas label Oct 29, 2020
@maximkrouk
Copy link
Member Author

maximkrouk commented Oct 29, 2020

For now, the main way to use FunctionalHanlder is this:

// Internal site

public class TapGestureRecognizer: UITapGestureRecognizer {
    @FunctionalHandler<TapGestureRecognizer, Void>
    var onTapGesture
    
    init() {
        super.init(target: nil, action: nil)
        commonInit()
    }
    
    override public init(target: Any?, action: Selector?) {
        super.init(target: target, action: action)
        commonInit()
    }
    
    private func commonInit() {
        self.addTarget(self, action: #selector(handleTap))
    }
    
    @objc private func handleTap(_ recognizer: TapGestureRecognizer) {
        $onTapGesture?(recognizer)
    }
}
// Public site

func example() {
    let tapRecognizer = TapGestureRecognizer()
    tapRecognizer.onTapGesture { recognizer in
        guard recognizer.state == .ended else { return }
        print("tapped")
    }
}

But also I'd like to add scope method to the public site

// Public site

func example() {
    let tapRecognizer = TapGestureRecognizer()
    tapRecognizer.onTapGesture.scope(\.state) { state in
        guard state == .ended else { return }
        print("tapped")
    }
}

And the main reason for the discussion is the map method. It may be convenient for data sources:

@FunctionalHandler<Void, Int>
var getNumberOfCells
func hideHalfOfCells() {
    getNumberOfCells.map { $0 / 2 }
}

But map is rarely used and its semantics probably shouldn't be mutating.

@maximkrouk maximkrouk changed the title FunctionalHandler API FunctionalHandler API Design Oct 29, 2020
@maximkrouk
Copy link
Member Author

FunctionalHandler probably should be renamed to FunctionalDataSource, and FunctionalHandler will be a new type with (Input) -> Void action. Handlers should not have outputs, now it is a generic pattern, but handlers are specific, that is why it should be reimplemented. Generic equivalent's name is still a thing to discuss.

@maximkrouk
Copy link
Member Author

Also scope here has map semantics, so the map is definitely a thing to remove, it even doesn't seem to be needed...

@maximkrouk
Copy link
Member Author

Functional prefix will be removed for Handler & DataSource types

@maximkrouk
Copy link
Member Author

maximkrouk commented Dec 26, 2023

Swift 5.9 introduced variadic generics, which may allow us to get rid of generic type overloads, but currently it's only supported on iOS17+ for types, maybe we may consider using macros to support it across all oss 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion A place to explore ideas
Projects
None yet
Development

No branches or pull requests

1 participant