Skip to content

Instantly share code, notes, and snippets.

@an0
an0 / Guard.swift
Created August 21, 2015 19:31
Guard
protocol Guard {}
class Adam: Guard {}
class Alfred: Adam {}
func conforms1<T>(x: Any.Type, y: T.Type) -> Bool {
return x is T.Type
}
// This also should be true but for some reason type is Guard.Protocol instead of Guard.Type.
print(conforms1(Adam.self, y: Guard.self))
@an0
an0 / SelfReferential.swift
Last active August 29, 2015 14:27
Self Referential Limitation or Bug
final class Foo {
// static let _sharedInstance = self.init() // Why not work?
static let _sharedInstance = Foo()
static func sharedInstance() -> Self {
return _sharedInstance // Why 'Foo' is not convertible to 'Self'? It is `static` so `Self` can only be `Foo`. In fact since the class is final there won't be any subclasses at all.
// return self.init() // Why this works?
}
required init() {
@an0
an0 / NSObjectVSNSObjectProtocol.md
Last active August 29, 2015 14:26
NSObject VS NSObjectProtocol

NSObjectProtocol is more general than NSObject and isEqual and hash are defined in NSObjectProtocol. Logically, we should inherit NSObjectProtocol from Equatable and Hashable.

Why not? Why instead extend NSObject to conform to Equatable and Hashable?

The current design causes problems like this:

if obj.delegate == self {

Binary operator '==' cannot be applied to operands of type 'XXXDelegate' and 'XXXDelegate'

@an0
an0 / ImplicitlyUnwrappedOptionalUnwrappedUnexpected.swift
Last active August 29, 2015 14:26
Implicitly Unwrapped Optional is Really Dangerous and Its Type Matching is Buggy
/* Implicitly unwrapped optional is really dangerous, especially when unwrapped unexpected.
For example, I expect here `a` will be checked again `nil` first before being unwrapped and compared to `b`.
That is to say, I thought there are `==(lhs: T?, rhs: T)` and `==(lhs: T, rhs: T?)`. But there aren't.
There are only `==(lhs: T, rhs: T)` and `==(lhs: T?, rhs: T?)`.
Reasonably, (lhs: T!, rhs: T) matches better the former than latter so the former is picked so crash. */
let a: Int! = nil
let b: Int = 1
@an0
an0 / GenericTypesNotThatWorseThanProtocols.swift
Created August 7, 2015 14:47
Generic Types are Not That Worse than Protocols
// Response to http://www.russbishop.net/swift-associated-types:
// 1. Type parameter leaking is a real problem(the `S` parameter of `buyFoodAndFeed` below can not be omitted — "We have no way to express that we don't care about the Supplement type parameter") but not as severe as is described in the article because non-generic subclasses of generic superclasses do not need type parameter re-specification when being used.
// 2. It is not true that "we have no way to link the type of F to Food". We can link Animal.F to Store.G. See `buyFoodAndFeed` below.
class Food {
required init() {
}
}
@an0
an0 / CaseLetWhere.swift
Created August 6, 2015 20:15
Case-condition is Powerful
for case (let x, 0) in [(0, 0), (0, 1), (1, 0), (1, 1)] where x > 0 {
print(x)
}
@an0
an0 / ArraysBuildingWithReduceOptimization.md
Last active August 29, 2015 14:26
Is Arrays Building with Reduce Optimizable?
@an0
an0 / PowerOfDefaultAssociatedType.swift
Last active August 29, 2015 14:25
Power of Default Associated Type
// Simplify code of http://martiancraft.com/blog/2015/07/objective-c-swift-core-data/ by using default associated type to eliminate the need of defining associated type in every subclass.
class ManagedObject {}
class Person: ManagedObject {}
class Thing: ManagedObject {}
let db: [ManagedObject] = [Person(), Thing()]
// Source: https://twitter.com/AirspeedSwift/status/618546432954474497
prefix func !<T>(t: T?) -> T {
return t ?? Array<Int8>(count: sizeof(T), repeatedValue: 0).withUnsafeBufferPointer {
UnsafePointer($0.baseAddress).memory
}
}
prefix func !<T: ExtensibleCollectionType>(t: T?) -> T {
return t ?? T()
@an0
an0 / A2Z.swift
Last active February 28, 2016 23:41
A...Z
extension Character: ForwardIndexType {
public func successor() -> Character {
return Character(String(self).successor())
}
}
extension String: ForwardIndexType {
public func successor() -> String {
let scalars = self.unicodeScalars
let scalar = scalars[scalars.startIndex]