Reactivecocoa: How should we deal with the `rac_` prefixes in Swift 3?

Created on 10 Jul 2016  ·  15Comments  ·  Source: ReactiveCocoa/ReactiveCocoa

The Swift API guidelines set a convention of lower camel cases.

Currently, we have two exceptions in the Swift codebase: NotificationCenter.rac_notifications(forName:object:) and URLSession.rac_data(with:). Moreover, since IIRC we are going to merge Rex in as part of the Cocoa Bindings repo at some point, how the rex_ prefixes are handled should be considered too.

Should we follow, or leave them as is?

For the two extensions in this repo, the most uncreative name is probably makeProducer. But it might not suit everyone's tastes, hmm.

Begin names of factory methods with “make”, e.g. x.makeIterator().

Edit: After a second thought, for producers, they do not have any side effect applied until they are started. So a non-mutating name describing what it would deliver would be appropriate IMO, e.g. just notifications(forName:object:).

Most helpful comment

One of the things we've done with SnapKit is create a struct that hosts the extensions, the RAC api's could be stored like:

struct UIButtonRACDSL {
    var pressed: Signal<UIButton, NoError>
    init(button: UIButton) { }
}

extension UIButton {
    var rac: UIButtonRACDSL { return UIButtonRACDSL(button: self) }
}

Going down this route provides some flexibility and reduces the collision scope of the extensions.

All 15 comments

We could drop the prefixes since the types make the names unambiguous—at least in most cases. Or we could keep them. I'm on the fence.

If we do keep them, we should use rac_ here (including the code from Rex) and find a new prefix for ReactiveSwift.

Since dropping the prefix of the bindings would cause name collisions with the stored properties, an alternative for these would be introducing a proxy that hosts all of them.

e.g.

view.bindables.text <~ property

// `view.bindables` is of type `Bindings<UIView>`, which conforms to `BindingsProtocol`
// that requires an associated type `Owner`.
//
// `view.bindables.text` is provided by the extension to `BindingsProtocol` for all
//`Owner` inherited from `UIView`.

(Or just rac? But both ReactiveSwift and ReactiveCocoa could expose some kind of bindings, I assume)

... Or just name it view.textProxy, view.reactiveText or whatever, eh.

Edit: I have put together a quick prototype (https://github.com/RACCommunity/Rex/pull/143).

Edit 2: Clean the mess up for a bit. :p

ReactiveCocoa 5+ doesn't need to be compatible with Rex. RAC will subsume Rex.

Sure, I just meant those bindings brought in by Rex. Sorry if it reads like a mess. 😸

outlets would be a contender too.

"reactive" is suites better with swift language. "rac_" and "rex_" are very bad namings. I will go for "reactive", "active" or "signal" so we could have view.reactiveText or view.activeText or view.signalText

With Swift and modules there's no longer a risk for runtime collisions, and therefore no need for prefixes. So let's just drop 'em! :D

It is fine for the methods. But we still need to look for an approach for the properties, since properties cannot be overloaded. 😕

Built upon a bindable proxy e.g. view.bindables.something, we may introduce shortcuts like %view.something. 😕

I think it is safe to draw the conclusion that we cannot avoid/disambiguate compile-time collisions in any way, at least in Swift 3.0. Suggestions like using operators or magic property just limit the potential of collision to one entity.

I would risk an operator collision in exchange for a nicer shorthand though...

I think we're stuck with prefixes for properties for now.

One of the things we've done with SnapKit is create a struct that hosts the extensions, the RAC api's could be stored like:

struct UIButtonRACDSL {
    var pressed: Signal<UIButton, NoError>
    init(button: UIButton) { }
}

extension UIButton {
    var rac: UIButtonRACDSL { return UIButtonRACDSL(button: self) }
}

Going down this route provides some flexibility and reduces the collision scope of the extensions.

Yeah, I have brought it up before with a protocol-based version. It replaces the underscore with a dot, and allows the introduction of an operator shorthand. IMO using rac as the property name would be fine, as it is not a very common abbreviation anyway.

https://github.com/RACCommunity/Rex/pull/143

rac property would look so much cleaner… SOOO MUUUCH!!! :heart_eyes:

I think we should steal the approach that RxSwift has taken.

https://github.com/ReactiveX/RxSwift/blob/4952adb27c684b47792923b00015516849061eab/RxCocoa/Common/Reactive.swift
https://github.com/ReactiveX/RxSwift/blob/4952adb27c684b47792923b00015516849061eab/RxCocoa/iOS/UIControl%2BRx.swift

They added a struct, Reactive that's generic over the type they want to extend. They then added methods on constrained extensions to Reactive. Evidently they modeled this after Swift's .lazy.

Was this page helpful?
0 / 5 - 0 ratings