Skip to content

Instantly share code, notes, and snippets.

View rnapier's full-sized avatar

Rob Napier rnapier

View GitHub Profile
// Previous async code based on Result. A "Search" wraps an async operation and offers features like cancel().
// An earlier experiment includes self.pages = result ?? [], but that's cheating.
// If you didn't care about error handling, what's the point of Result? Added displayError() to test reality.
// Of course maybe "self.pages = result ?? { displayError(err); return [] }()" would work,
// but that gets a little obtuse and scales poorly.
func search(text: String, completionHandler: (Result<[Page]>) -> Void) -> Search { ... }
self.currentSearch = self.searcher.search(searchString, completionHandler: { result in
switch result {
@rnapier
rnapier / gist:5c80d113895a796fc17b
Last active February 3, 2018 23:20
Wrapping funcs into protocols
/*:
Stuff from [Crustacean](https://developer.apple.com/sample-code/wwdc/2015/?q=protocol).
(Wish I could hide this in a single-file playground somehow.)
*/
import CoreGraphics
protocol Renderer {
func moveTo(position: CGPoint)
func lineTo(position: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat)
@rnapier
rnapier / fp.swift
Last active February 3, 2018 23:06
FP examples in Swift
// Just spending Saturday afternoon rewriting FP examples from Backus in Swift.
// http://worrydream.com/refs/Backus-CanProgrammingBeLiberated.pdf
//
// Surprising fact: reasonably possible with only one major problem (tuples are not collections)
// Unsurprising fact: you shouldn't write Swift this way
// Other unsurprising fact: Rob should probably get out more
// Don't judge me
// For future research: is it possible to build this without arrayFormHack and the arity 2 ∘?
// Basically, can we do this entirely with tuples or entirely with arrays? Currently almost everything
@rnapier
rnapier / helper.swift
Last active February 3, 2018 23:00
Helper functions
import Foundation
/// This is going to be one of those things that for many of you is so obvious that it doesn't
/// require saying. But maybe a few of you have never really done this before either. I've been
/// thinking about nested helper functions.
/// I've used little nested helper functions lots of times. I do this when I want a function, but
/// nothing outside of this scope would ever need it.
func doSomething() {
func inc(x: Int) -> Int { return x + 1 }
@rnapier
rnapier / map-0-box.swift
Last active February 3, 2018 22:59
Another Swift box for [Protocol]
// Yet another Swift box....
// I had never run into this explicitly until Andrew Spiess (@ninjazoete) asked about it a couple of days ago:
// https://twitter.com/ninjazoete/status/669530132919525377
// Now it's springing up all over the place in my work.
//
// I'm calling it "map-$0-boxing" for the moment ("identity boxing" is more accurate, but "map-$0" better
// matches the actual code). Anyone have a better or clearer implementation?
//
@rnapier
rnapier / 1-simplejson.swift
Last active February 3, 2018 22:59
Yeah, @krzyzanowskim is probably right. What problem were we solving?
import Foundation
// All the complexity needed to avoid this code probably isn't worth it in the majority of cases.
// Particularly note that the data model doesn't 100% line up with the JSON (some keys have
// slightly different names for instance). A system flexible enough to handle that (say, something
// like Go's json.Marshal) would be nice, but this code, while slightly tedious, isn't really bad.
// Basically I'm saying that a richer JSON<->Swift system built into stdlib would be nice, but the
// bar is pretty high to go pulling in a helper library.
//
// That said, compare the Go code below, and I think it really is much simpler, and scales much better
@rnapier
rnapier / iflet.swift
Last active February 3, 2018 22:58
If-let based on protocol rather than Optional
// Expanding if-let to Result
public enum Result<Wrapped> {
case Error(ErrorType)
case Value(Wrapped)
}
protocol IfLetConvertible {
typealias Wrapped
func unwrap(inout value: Wrapped!) -> Bool
@rnapier
rnapier / ClassSet.swift
Last active February 3, 2018 20:57
SetAlgebra for classes
//
// ClassSet.swift
// audio
//
// Created by Rob Napier on 1/25/18.
// Copyright © 2018 Jaybird LLC. All rights reserved.
//
/// Unordered set of unique class objects. Does not require Equatable or Hashable.
struct ClassSet<Element> where Element: AnyObject {
@rnapier
rnapier / observable.swift
Last active January 27, 2018 20:45
Observable sketch
import Foundation
typealias ObserverRemover = () -> Void
/*! An observable value
An `Observable` wraps any value. If you add an observer handler, then every time the value is set, your handler will be
called with the new value. Adding an observer returns a closure that is used to remove the observer. Note that the handler
is called every time the value is set, even if this does not change the value. If you only want the handler to be called
when the value changes, see `CoalescingObservable`.
@rnapier
rnapier / layout.swift
Last active January 7, 2018 18:40
Flow layout using intrinsic size of cells
// FIXME: This seems unnecessary. My cells define an intrinsicContentSize, which I thought would be used by the flow layout
// but this is the only way I've been able to get it to be honored. I feel I'm missing something with auto-sizing cells.
extension TypeGeneratorViewController: NSCollectionViewDelegateFlowLayout {
public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
let cell = ForwardedProtocolItem()
cell.representedObject = protocols[indexPath.item]
return cell.view.intrinsicContentSize
}
}