Skip to content

Instantly share code, notes, and snippets.

View jspahrsummers's full-sized avatar

Justin Spahr-Summers jspahrsummers

View GitHub Profile
@jspahrsummers
jspahrsummers / gist:986175
Created May 23, 2011 03:27
Tentative coroutine syntax
#define coroutine(ARGS) \
__block unsigned long ext_coroutine_line_ = 0; \
\
return ^(ARGS){ \
for (;; ext_coroutine_line_ = 0) \
switch (ext_coroutine_line_) \
default:
#define return_coroutine \
}
@jspahrsummers
jspahrsummers / MultipleDispatch.cpp
Last active August 20, 2016 14:30
Example of using RTTI and template specialization for multiple dispatch in C++
template<typename Left, typename Right>
struct Intersect
{
// This will fail to compile if there's no specialization for Intersect<Right, Left>,
// thereby verifying that we've handled all combinations.
typename Intersect<Right, Left>::Result operator() (const Left &lhs, const Right &rhs) const
{
return Intersect<Right, Left>()(rhs, lhs);
}
};
@jspahrsummers
jspahrsummers / ErrorType.swift
Created August 8, 2016 21:55
An unexpected error has occurred.
do {
try myFunctionWhichOnlyThrowsOneErrorType()
} catch let err as ThatOneErrorType {
handleAppropriately()
} catch let err {
preconditionFailure("Unexpected error: \(err)")
}
@jspahrsummers
jspahrsummers / ImageLoading.m
Last active December 29, 2015 03:59
Using -flatten:withPolicy: (from ReactiveCocoa 3.0) and related operators to deal with producers that can outstrip consumers
// Asynchronously loads UIImages from the given URLs, but throttles the loading
// to keep memory and CPU usage sane.
- (RACSignal *)loadImagesAtURLs:(NSArray *)imageURLs {
// Map each URL to a signal of work. The result is a signal of work signals.
return [[imageURLs.rac_signal
map:^(NSURL *imageURL) {
return [[[[NSURLConnection
// Load the URL asynchronously.
rac_sendAsynchronousRequest:[NSURLRequest requestWithURL:imageURL]]
reduceEach:^(NSURLResponse *response, NSData *data) {
@jspahrsummers
jspahrsummers / gist:7541192
Last active December 28, 2015 18:09
A cooperative reader-writer pattern using signal generators from ReactiveCocoa 3.0
// Reads until the given stream is exhausted, creating and subscribing to a new
// signal using `writer` for each chunk of data that is read.
//
// Sends completed or error.
- (RACSignal *)readStream:(Stream *)stream writingWithGenerator:(RACSignalGenerator *)writer {
return [[[RACSignal
create:^(id<RACSubscriber> subscriber) {
while (!subscriber.disposable.disposed && stream.hasData) {
NSError *error = nil;
NSData *data = [stream readData:&error];
@jspahrsummers
jspahrsummers / gist:7045771
Last active December 25, 2015 21:49
The RACCommand example from https://gist.github.com/jonsterling/7001562 with postcomposition instead.
- (id)initWithEnabled:(RACSignal *)enabled provider:(RACSignalProvider *)provider {
if (self = [super init]) {
_enabled = [enabledSignal replayLast];
_decoratedProvider = [[[RACSignalProvider alloc]
initWithBlock:^(id input) {
return [[self.enabled take:1] flattenMap:^(NSNumber *enabled) {
if (enabled.boolValue) {
return [RACSignal return:input];
} else {
@jspahrsummers
jspahrsummers / gist:7000136
Last active December 25, 2015 15:39
Various use cases that need to be considered for ReactiveCocoa 3.0, along with their current RAC 2.x or Rx solutions

Use cases

  1. Turning an eager, pure computation into a lazy one: RACSequence, RACSignal
  2. Side-effecting work that is safe to perform multiple times: RACSignal, RACCommand
  3. Side-effecting work that is safe to perform multiple times serially, but not concurrently: RACCommand, RefCount()
    • RACScheduler would seem to apply here, but execution could become interleaved and thus not serial
  4. Side-effecting work that should only be performed once, then memoized: RACMulticastConnection with a RACReplaySubject, RACSequence
  5. Enabling/disabling a UI based on whether work can be performed: RACCommand, RACReplaySubject
    • Replaying is a Good Idea™ because this information may arrive before the UI is ready for it
  6. Updating a UI with information about work in progress: RACCommand, RACSubject
@jspahrsummers
jspahrsummers / gist:6940184
Last active December 25, 2015 07:38
lol recursive blocks
__block void (^myRecursiveBlock)(int);
id myBlock = ^(int x) {
if (x > 5) {
// Release the block from its own implicit retain cycle.
myRecursiveBlock = nil;
} else {
myRecursiveBlock(x + 1);
}
};
@jspahrsummers
jspahrsummers / gist:6400596
Created August 31, 2013 20:57
Error installing ResourceT using Cabal and GHC 7.6.3.
Control/Monad/Trans/Resource.hs:613:24:
Could not deduce (m ~ IO)
from the context (MonadBaseControl IO m)
bound by the type signature for
resourceForkIO :: MonadBaseControl IO m =>
ResourceT m () -> ResourceT m ThreadId
at Control/Monad/Trans/Resource.hs:601:19-81
`m' is a rigid type variable bound by
the type signature for
resourceForkIO :: MonadBaseControl IO m =>
@jspahrsummers
jspahrsummers / gist:5812222
Last active December 18, 2015 16:29
Make "self" cause a compilation error only within blocks.
#define self \
( \
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-value\"") self, \
/* Depends on _cmd being a const copy, like other captured variables. */ \
_Pragma("clang diagnostic pop") (*(_cmd = _cmd, &self)) \
)
// Replace libextobjc's @weakify with one that's aware of the "self" macro.
#undef ext_weakify_
#define ext_weakify_(INDEX, CONTEXT, VAR) \