Last active
August 21, 2019 21:28
-
-
Save porglezomp/ef74519e266dab1c77e8ab7b3966f954 to your computer and use it in GitHub Desktop.
Where we're going we don't need primitive control flow!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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