Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Techniques to write DSLs in Swift

Techniques to write DSLs in Swift

Luis Solano

June 06, 2014
Tweet

More Decks by Luis Solano

Other Decks in Programming

Transcript

  1. asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla

    asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla
  2. @implementation Subscription - (id)init { self = [super init]; if

    (!self) return nil; self.state = @"pending"; } - (void)activateWithCode:(NSString *)activationCode { if ([self.state isEqualToString:@"pending"] && [self.code isEqualToString:activationCode]) { self.state = @"active"; } } - (void)suspend { if ([self.state isEqualToString:@"active"]) { [self stopBilling]; } } @end IMPLEMENTATION
  3. LSStateMachine *sm = [[LSStateMachine alloc] init]; LSState *s1 = [[LSState

    alloc] initWithName:@"pending"]; LSState *s2 = [[LSState alloc] initWithName:@"active"]; [sm addState:s1]; [sm addState:s2]; LSEvent *e1 = [[LSEvent alloc] initWithName:@"activate"]; LSTransition *t1 = [[LSTransition alloc] initWithEvent:e1 from:s1 to:s2]; [sm addTransition:t1]; ABSTRACTION
  4. LSStateMachine *sm = [[LSStateMachine alloc] init]; LSState *s1 = [[LSState

    alloc] initWithName:@"pending"]; LSState *s2 = [[LSState alloc] initWithName:@"active"]; [sm addState:s1]; [sm addState:s2]; LSEvent *e1 = [[LSEvent alloc] initWithName:@"activate"]; LSTransition *t1 = [[LSTransition alloc] initWithEvent:e1 from:s1 to:s2]; [sm addTransition:t1]; ABSTRACTION
  5. asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla

    asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla
  6. LSStateMachine *sm = [[LSStateMachine alloc] init]; LSState *s1 = [[LSState

    alloc] initWithName:@"pending"]; LSState *s2 = [[LSState alloc] initWithName:@"active"]; [sm addState:s1]; [sm addState:s2]; LSEvent *e1 = [[LSEvent alloc] initWithName:@"activate"]; LSTransition *t1 = [[LSTransition alloc] initWithEvent:e1 from:s1 to:s2]; [sm addTransition:t1]; ABSTRACTION
  7. sm.when("activate", transitionFrom: "pending", to: "active") sm.when("suspend", transitionFrom: "active", to: "suspended")

    sm.when("unsuspend", transitionFrom: "suspended", to: "active") sm.when("terminate", transitionFrom: "active", to: "terminated") sm.when("terminate", transitionFrom: "suspended", to: "terminated") ! sm.before("terminate") { subscription in subscription.terminatedAt = NSDate.date() } ! sm.before("suspend") { subscription in subscription.stopBilling() } DSL
  8. asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla

    asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla asjdañlksjdlaksjdñlak asjdañlksjdla
  9. LSStateMachine *sm = [[LSStateMachine alloc] init]; LSState *s1 = [[LSState

    alloc] initWithName:@"pending"]; LSState *s2 = [[LSState alloc] initWithName:@"active"]; [sm addState:s1]; [sm addState:s2]; LSEvent *e1 = [[LSEvent alloc] initWithName:@"activate"]; LSTransition *t1 = [[LSTransition alloc] initWithEvent:e1 from:s1 to:s2]; [sm addTransition:t1]; SWIFT METHODS luisobo/StateMachine
  10. extension Temp: FloatLiteralConvertible { typealias FloatLiteralType = Double class func

    convertFromFloatLiteral(value: Double) -> Temp { return Temp(degrees: value) } } USING LITERALS WITH YOUR TYPES
  11. BLOCKS FOR CONTEXT User.defineFactory { f in f["foo"] = "bar"

    f["password"] = "hunter2" } luisobo/Defactory
  12. OPERATOR OVERLOAD ^= *= * % + - / <<=

    ||= << || |= <= >>= !== >= ~= | >> < += &&= %= ... -= &% /= && &* &+ &- &/ === == & .. ^ > &= != ~ ! -- ++ - + -- ++
  13. =>>

  14. extension NSString: Matchable { func matcher() -> Matcher { return

    StringMatcher(pattern: self) } } ADD PROTOCOL TO EXISTING CLASS
  15. ADD PROTOCOL TO EXISTING CLASS extension NSRegularExpression: Matchable { func

    matcher() -> Matcher { return RegexMatcher(pattern: self) } }
  16. Thin layer on top of an abstraction. Limited expressiveness and

    domain focus. Make your code more maintainable Developer happiness Improved communication Fewer bugs! As seen in TV
  17. ! ! Domain-specific languages by Martin Fowler brain photo: flickr/_DJ_

    redacted font: github/christiannaths Nocilla: github/luisobo StateMachine: github/luisobo Defactory: github/luisobo Kiwi: github/kiwi-bdd metamacros.h github/jspahrsummers THANKS! @luisobo