-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Add @dynamicMemberLookup to ObservableType and SharedSequenceConvertiblebType #2068
Add @dynamicMemberLookup to ObservableType and SharedSequenceConvertiblebType #2068
Conversation
34b9895
to
76f8abc
Compare
76f8abc
to
a7a785e
Compare
@@ -4612,7 +4651,9 @@ | |||
buildSettings = { | |||
CLANG_ANALYZER_NONNULL = YES; | |||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES; | |||
CODE_SIGN_IDENTITY = "iPhone Developer"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these changes.
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that we don't need these either.
@@ -23,8 +23,6 @@ | |||
</BuildableReference> | |||
</TestableReference> | |||
</Testables> | |||
<AdditionalOptions> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove all unnecessary changes for this PR.
I haven't worked with Swift for a while now so I've missed some developments. How does this relate to the How much compiler overhead does this add? Do we have some estimates? Can somebody run this changes on a larger codebase? I kind of like the changes on the one hand, but on the other it is kind of confusing. @freak4pc Thoughts? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edited: This is a good change syntactically speaking, makes writing a tad more natural.
I don't have any data regarding performance / etc because this is still a relatively new feature, and we also need to see if this creates any effect on existing consumers (probably not).
Could you run the benchmark targets before and after this to provide some idea of the effect this makes? @yuriferretti
@yuriferretti Can you also share where in Combine is this used? I couldn't find this on top of Publisher types, for example. |
Co-Authored-By: Shai Mishali <[email protected]>
Co-Authored-By: Shai Mishali <[email protected]>
@kzaher
I'm not sure I share your point of view here. struct Person {
var name: String
var lastName
}
var obs: Observable<Person> ...
obs.name // valid and the type will be `Observable<String>`
//equivalent to
obs.map { $0.name } Personally I feel this change not a good fit for dynamicMemberLookup. I might be wrong, but the idea to shortcut a map feels like driving a Ferrari in a courtyard. I would see @dynamicMemberLookup as a good fit for a BehaviorSubject
soon we will have Keypaths as function that will already improve map ergonomics:
|
Could you elaborate more on that, what do you think would be a good fit?
And how would to deal with it throwing an error in case the subject errors out? If you had a good workaround I can add it to the implementation |
In this wwdc video Doug Gregor shows how the used |
It doesn't conflict with observable extensions in any way, it can also provide access to them if they are
After your question I started making some tests and I think the compiler gets lost sometimes when a long keyPath chain has an inner member that is optional. I will try to reproduce it more reliably and try some workarounds and If I didn't succeed I will file a bug to Swift and put PR on hold. |
Sure, I will send it to you when I reach my machine later today! |
The use case for @dynamicMemberLookup is when you do have a value that your @dynamicMemberLookup class/struct is wrapping. In an By seeing the code The way this is used in swiftUI (with @State for example) is to return a Binding of a property from an object that is already existing representing a state. All the examples I've seen so far have the same behavior: existing wrapped value -> do something with their properties. With Observable we don't have a wrapped value.
You could return an optional, then do the same for |
Fully agree with @gringoireDM about counter intuitive side of this proposal Sent with GitHawk |
Yup, my instinct is that - it's fun syntactically and saves some crud. e.g. observable.map { $0.a.b.c } -> observable.a.b.c BUT - I think it's too confusing as they aren't really properties of the Observable but of it's underlying Element type. |
Soon prefix operator ^
prefix func ^<Root, Value>(keypath: KeyPath<Root, Value>) -> (Root) -> Value {
return { $0[keyPath: keypath] }
} With this code you can do |
It think you meant
IMHO would be strange and counterintuitive to suddenly expose all attributes as optional values. |
@kzaher @freak4pc @gringoireDM |
@yuriferretti yes, I meant
It's not the same. Binding is projecting an inner attribute that is already present, while you are transforming the stream. It's deeply different. Binding projects a property of an object that is currently wrapping. Observable is not wrapping an object.
Not really. the Besides |
I'm sorry but I feel that you are trying to focus in the smaller picture in order to justify your vision and before continuing, please, understand that I'm not trying to impose nothing nor telling what's right or wrong here. I'm just trying to show where my inspiration came from. I think both of us will agree that the most valuable aspect of Another way to see how both implementations have the same pouporse is: struct Foo {
let bar: Bar
}
let foo: Observable<Foo> = ... How would you create an |
I'm sorry you feel this way, but that's not the case. You can't have @dynamicMemberLookup if you don't have a member to lookup.
No, we don't. The most valuable aspect of
Binding has a reference to an existing
Correct, but as new Binding, not as a map of the trigger that ticks the binding to emit a change. struct Foo {
var bar: Bar
}
struct Baz {
@Binding var fooInstance: Foo
func myFunc() {
let barBinding = $fooInstance.bar
fooInstance.bar = newBar // <- this will cause barBinding to emit a new event
}
}
But you are not creating an Surely the type check will give you the right to think that you've made an observable of Bar, but truly you are not observing Bar changes on the current Foo. |
Please point me where I wrote that I'm talking about an observable that emmits just a single time.
Sure and
You are totaly mixing up things here. I said before that both I will simplify the things here to avoid more misinterpretations and please be aware that I'm not talking about the let foo: Binding<Foo> = .constant(Foo()) // no wrapper pure types
let dynamicBinding: Binding<Bar> = foo.bar //dynamicMember returns Binding<Bar>
let initBinding: Binding<Bar> = Binding(base: foo) // it would also work as the above but is more verbose
let obsFoo : Observable<Foo> = .just(Foo())
let dynamicBar: Observable<Bar> = obsFoo.bar //dynamicMember returns Observable<Bar>
let mapBar: Observable<Bar> = obsFoo.map { $0.bar } // same as above but more verbose I'm not talking about when they will emit, update, complete or whatever. I'm talking about enabling a shorcut to make those kind of transformations more brief and noiseless. It's not about doing the same job, it's about where the idea came from! |
It seems that swift's typechecker has some optional chaining KeyPath related bugs that I'm stumbling upon right now as stated here. |
Hi guys,
One of the cool features that Combine brought us is to enable keypath based
@dynamicMemberLookup
on some types of sequences what makes simple attribute based transformation much easier like the following:So I added the
@dynamicMemberLookup
toObservableType
andSharedSequenceConvertiblebleType
to allow RxSwift Sequences the same neat mapping.Please let me now your thoughts about it.