DSLs in Swift

DSLs in Swift

A talk I given at SwiftCrunch http://swiftcrunch.com, the first ever hack day on Swift.

https://github.com/kylef/QueryKit
https://twitter.com/kylefuller

D200a17dd269fd4001bacb11662dab4b?s=128

Kyle Fuller

July 06, 2014
Tweet

Transcript

  1. 2.
  2. 3.
  3. 4.
  4. 5.
  5. 6.
  6. 11.
  7. 12.
  8. 14.
  9. 15.
  10. 19.

    NSExpression *left = [NSExpression expressionForKeyPath:@"name"]; NSExpression *right = [NSExpression expressionForConstantValue:@"Kyle"];

    [NSComparisonPredicate predicateWithLeftExpression:left rightExpression:right modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];
  11. 26.
  12. 27.
  13. 29.
  14. 32.
  15. 34.
  16. 37.

    let fetchRequest = NSFetchRequest(entityName: "Person") fetchRequest.predicate = NSPredicate(format:"name == %@",

    "Kyle") fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)] var error:NSErrorPointer? var objects = managedObjectContext.executeFetchRequest(fetchRequest, error:error!) if let objects = objects { ; }
  17. 38.
  18. 40.
  19. 45.
  20. 46.

    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath

    age not found in entity <NSSQLEntity Person id=6>' *** First throw call stack: ( 0 CoreFoundation 0x00000001039e5495 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000102fe199e objc_exception_throw + 43 2 CoreData 0x0000000100b04438 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 904 3 CoreData 0x0000000100b03f6d -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 365 4 CoreData 0x0000000100b03bd3 -[NSSQLCore newRowsForFetchPlan:] + 115 5 CoreData 0x0000000100b034a4 -[NSSQLCore objectsForFetchRequest:inContext:] + 516 6 CoreData 0x0000000100b03025 -[NSSQLCore executeRequest:withContext:error:] + 245 7 CoreData 0x0000000100b02b60 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 3504 8 CoreData 0x0000000100b00a21 -[NSManagedObjectContext executeFetchRequest:error:] + 497 9 Fitness First 0x000000010021d89a -[KFObjectManager array:] + 138 10 Fitness First 0x00000001000c6396 -[FFGDashboardViewController viewWillAppear:] + 1190 11 UIKit 0x0000000101ae8db5 -[UIViewController _setViewAppearState:isAnimating:] + 422 12 UIKit 0x0000000101d42410 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:animation:] + 5629 13 UIKit 0x0000000101aeffce -[UIViewController presentViewController:withTransition:completion:] + 4854 ) libc++abi.dylib: terminating with uncaught exception of type NSException
  21. 54.
  22. 55.
  23. 57.

    !

  24. 60.

    BAD

  25. 63.
  26. 68.
  27. 69.
  28. 70.
  29. 73.
  30. 74.

    class Attribute { var ascending:NSSortDescriptor { return NSSortDescriptor(key: "x", ascending:

    true) } var descending:NSSortDescriptor { return NSSortDescriptor(key: "x", ascending: true) } } @infix func == (left: Attribute, right: AnyObject) -> NSPredicate { return NSPredicate(format: "x", nil) }
  31. 75.

    class QuerySet { func orderBy(sortDescriptor:NSSortDescriptor) -> QuerySet { return self

    } func filter(predicate:NSPredicate) -> QuerySet { return self } subscript(range: Range<Int>) -> QuerySet { return self } }
  32. 76.

    class Person { class var name:Attribute { return Attribute() }

    } QuerySet().filter(Person.name == "Kyle") .orderBy(Person.name.ascending)
  33. 77.

    !

  34. 80.
  35. 81.
  36. 82.
  37. 83.
  38. 84.
  39. 85.
  40. 86.
  41. 87.
  42. 88.
  43. 89.
  44. 90.
  45. 93.