Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@porglezomp
Last active August 21, 2019 21:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porglezomp/ef74519e266dab1c77e8ab7b3966f954 to your computer and use it in GitHub Desktop.
Save porglezomp/ef74519e266dab1c77e8ab7b3966f954 to your computer and use it in GitHub Desktop.
Where we're going we don't need primitive control flow!
/// Like a smalltalk bool, but worse. Just used for control flow, we can use real boolean ops.
class ChitChatBool {
func ifTrue<T>(block: () -> T) -> T? { return nil }
}
class True: ChitChatBool {
override func ifTrue<T>(block: () -> T) -> T? { return block() }
}
class False: ChitChatBool { }
let booleans: [Bool: ChitChatBool] = [true: True(), false: False()]
func toChitChat(bool: Bool) -> ChitChatBool {
return booleans[bool] ?? ChitChatBool()
}
public struct Otherwise<T> {
let value: T?
internal init(_ value: T?) {
self.value = value
}
public func or(_ cond: Bool, block: () -> T) -> Otherwise<T> {
// Does ?? count as control flow? I'm gonna say no because it makes the
// implementation nicer, and because I could still do it without using it.
return Otherwise(value ?? toChitChat(bool: cond).ifTrue(block: block))
}
public func otherwise(block: () -> T) -> T {
return value ?? block()
}
}
public func when<T>(_ cond: Bool, block: () -> T) -> Otherwise<T> {
return Otherwise(nil).or(cond, block: block)
}
// This works great! :3
// No primitive control flow in sight! :D
(0...2).forEach { i in
let val = when (i == 0) {
"This is the first case"
} .or (i == 1) {
"Hey, case 1"
} .otherwise {
"This is the last case"
}
print(val)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment