Comments (16)
RACUnit.defaultUnit
is equivalent tosendCompleted
. Most of the framework's current uses ofRACUnit
could easily be replaced with something else, likenil
or a dummy value.
Alternatively, nil
could be equivalent to sending completed. nil
values aren't handled very well right now anyways (e.g., in -merge
), and this would lead to a more natural translation between subscribables and collections/sequences.
from reactivecocoa.
Hmmm.... I do like the idea of having a single stream of values.
The biggest win that can come out of this is providing some common interfaces of well-understood abstraction that makes sense for both subscribables and sequences of all kinds.
I'm sure at this point I sound quite like a broken record on this matter, and I've little doubt you've heard my thoughts on this before. Nonetheless, Functors and Idioms may be modeled in Objective-C very nicely using HOMs, with a little bit of care; RAC lends itself beautifully to the following kind of API:
id nameStream = self.nameField.rac_textSubscribable;
id ageStream = self.ageField.rac_textSubscribable;
id personStream = [Person.idiom name:nameStream age:ageStream];
// We can use the same +idiom machinery with any other kind of "sequence"
id names = @{ @"Joseph", @"James", @"Tucker", @"Tyrone" };
id ages = @{ @14, @63, @7, @16 };
id people = [Person.idiom name:names ages:ages];
The real trick here is to write the same code over reactive streams and sequences; RAC has heretofore lent itself to a pretty "RAC-heavy" coding style, if you catch my drift. It would be nice to liberate our semantics from this prison of specificity, as it were, into something much more general: a family of abstractions suitable for sequences of any sort.
from reactivecocoa.
Rx has Materialize/Dematerialize methods that sound very similar to what you're proposing.
If we implement something like those, it seems like we get all the upsides you're talking about without big, breaking changes.
Like we talked about last weekend, I'm not opposed to drastically changing RAC if we can convince ourselves of better semantics.
from reactivecocoa.
That could work, although it'd be a huge pain in the ass to conditionalize stuff based on whether the stream is materialized or not.
For instance, if I want to use repeat
, it either has to know about materialization, or I have to make sure to dematerialize before I invoke repeat
and then rematerialize after.
Also, sidenote: I'm getting really sick of typing "materialize."
from reactivecocoa.
Monadic bind could be applied to subscribables.
Bind can already apply to Subscribables, at least in Rx, it's actually a huge part of using Rx; you just need to implement it. I'll give you the secrets, in C#, you can translate :)
// This is a method that, given a Subscribable, for each item in the Subscribable, returns a new Subscribable
// So! For an input [1,2,3,4], you get an output of [IO(1), IO(2), IO(3), IO(4)], but then it returns the results
// of "flattening" that Subscribable
IObservable<TOut> SelectMany(IObservable<TIn> input, Func<TIn, IObservable<TOut>> selector);
So, to implement this, a way to think of it is:
IObservable<T> Merge(IObservable<IObservable<T>> sequenceOfSequences);
IObservable<TOut> SelectMany(IObservable<TIn> input, Func<TIn, IObservable<TOut>> selector)
{
IObservable<IObservable<TOut>> selectedSequence = input.Select(selector);
return Merge(selectedSequence);
}
Merge takes a Subscribable of Subscribables, subscribes to all of them that come over the wire, and every item that comes through, it emits it to the output.
If none of this makes any kind of sense, let me know and I can elaborate :)
from reactivecocoa.
We do have selectMany
in RAC, but it's not truly a bind unless we have something like Materialize
βΒ which, as noted above, has its own problems.
from reactivecocoa.
Why is it not truly a bind?
from reactivecocoa.
So, let me back up a bit and explain the concept I have in my mind.
I'd love to have RACSequence
and RACSubscribable
as two distinct things, which share a monadic interface that can be used to implement most of the operations that are subscribable-specific right now.
For instance:
@concreteprotocol(RACMonad)
- (instancetype)filter:(BOOL (^)(id))filterBlock {
return [self bind:^(id value) {
if (filterBlock(value)) {
return [self.class unit:value];
} else {
return [self.class empty];
}
}];
}
@end
I think I did that right.
Looking at that implementation, though, I guess subscribables don't actually need to change to make it work. It's still a little weird to me that errors and completion can't be handled from within the function being bound, but I guess that's no different from Either
or Maybe
in Haskell.
from reactivecocoa.
@jonsterling Do you have a reply to the above? I think that mostly resolved my concerns with error/completed, but maybe there's a case I'm missing.
from reactivecocoa.
Yeah, KVO is a great point that I hadn't even considered.
from reactivecocoa.
Whoops, deleted the comment by mistake. I'll rewrite it, the above reply was to my comment.
Alternatively,
nil
could be equivalent to sending completed.nil
values aren't handled very well right now anyways (e.g., in-merge
), and this would lead to a more natural translation between subscribables and collections/sequences.
I don't think that's a good idea. Bridging RAC to KVO is a great way to mix RAC and non-RAC code, and for KVO nil
is a valid value for keypaths. (cf. #82)
I think the sentinel value for completed should be a singleton object with only that purpose, so users of the library wouldn't have to wrap a certain value or avoid using it entirely because it was overloaded with a new meaning.
I like RACTuple
's handling of nil
better than NSArray
's.
from reactivecocoa.
Still digesting :)
Sent from my iPhone
On Oct 31, 2012, at 4:43 PM, Justin Spahr-Summers [email protected] wrote:
@jonsterling Do you have a reply to the above? I think that mostly resolved my concerns with error/completed, but maybe there's a case I'm missing.
β
Reply to this email directly or view it on GitHub.
from reactivecocoa.
id<RACSubscribable>a = [RACSubscribable error:error];
id<RACSubscribable>b = [RACSubscribable return:value];
id<RACSubscribable>c = [RACSubscribable empty];
id<RACSubscribable>combined = [RACSubscribable combineLatest:@[a, b, c]];
With error and completed not "out of band", does combined
send (error, value, completed)
rather than just error
? It would make using +combineLatest
pretty bothersome.
Wouldn't it be better to treat sequences as subscribables rather than the other way around?
from reactivecocoa.
@Coneko No, combined
would error before anything else is sent, without violating the above semantics.
That said, I think @xpaulbettsx has convinced me this isn't really necessary, and either can be represented as the other. We can talk more about subscribables and sequences in #89, though, since this thread is winding down.
from reactivecocoa.
I realized what you were trying to say with the snippet of code.
There's no need to think about one as the other at all to begin with.
Since they're both monads, new methods can be shared between the two as long as you only use methods you define on monads to implement them.
It took me a while to figure out because I was silly and didn't notice bind
and >>=
were the same thing.
Given all that, I think the idea of adding sequences to ReactiveCocoa is great from all points of view. Although keeping this up might turn ReactiveCocoa into FunctionalCocoa.
from reactivecocoa.
π€π
from reactivecocoa.
Related Issues (20)
- [SwiftPM on Xcode] Package resolution failed HOT 2
- Unable to compile targeting macOS Catalyst using SwiftPM (fix exists)
- why RACObserve(self.scoreStepper,value) not available? HOT 1
- App rejected for HealthKit metadata HOT 4
- UISearchBar delegate proxy crash on Mac Catalyst HOT 1
- Build error when using ReactiveCocoa via Swift Package Manager HOT 3
- can not deinit HOT 2
- Xcode12 ReactiveObj archive error HOT 3
- How to implement PIN input with attempts HOT 1
- Dispose SignalProducer created via Action HOT 1
- UnsafeKVOProperty initializer crashes after updating to ReactiveSwift 6.5.0 HOT 1
- EXC_BAD_ACCESS Cash with NSURL HOT 1
- ReactiveCocoa 11.1.0 incompatible with ReactiveSwift 6.6.0 HOT 5
- Xcode 12.5 beta 3 can't build ReactiveCocoa with SwiftPM. HOT 2
- Using "<~" binding function with Signal.Observers causes memory leaks. HOT 1
- Upgrading from very old version (2.5) fails - can't find ReactiveCocoa.h HOT 1
- Cannot remove an observer <RACKVOProxy 0x280264940> for the key path "unit" from <HGConfigureModel 0x280d25050> because it is not registered as an observer.
- Current version can't be compiled with the latest ReactiveSwift version HOT 2
- Current version can't be compiled with the latest ReactiveSwift version HOT 6
- Add output values support for interception
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reactivecocoa.