Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Example of using Swift property change observation to bind models to arguments passed to DSL closures
//: Playground - show possible simple DSL mechanism using mutable local vars
import UIKit
typealias MoveToFunction = (x: Float, y: Float) -> ()
typealias LineToFunction = (x: Float, y: Float) -> ()
typealias DSLClosure = (inout colour: UInt32, moveTo: MoveToFunction, lineTo: LineToFunction) -> ()
enum GraphicsCommand {
case setColour(colour: UInt32)
case moveTo(x: Float, y: Float)
case lineTo(x: Float, y: Float)
class GraphicsBuilder {
/// Called with a closure that can access a special list of functions and properties
func build(code: DSLClosure) -> [GraphicsCommand] {
var commands = [GraphicsCommand]()
var colour: UInt32 = 0xffffff {
didSet {
if oldValue != colour {
commands.append( .setColour(colour: colour))
let moveTo = { x, y in
commands.append( .moveTo(x: x, y: y))
let lineTo = { x, y in
commands.append( .lineTo(x: x, y: y))
code(colour: &colour, moveTo: moveTo, lineTo: lineTo)
return commands
let dsl = GraphicsBuilder()
/// This is what it looks like to use it. You can see what you can do in the arg list.
/// It is likely that moving these things to a struct is better. This would in itself be a nice pattern,
/// using structs to define the functionality of a DSL. However we're demonstrating the possibilities
/// of mutable, observable local vars here...
let commands = { (colour, moveTo, lineTo) in
colour = 0xff0000
moveTo(x: 50, y: 50)
colour = 0x00ff00
lineTo(x: 100, y: 100)
colour = 0x0000ff
lineTo(x: 0, y: 100)
colour = 0xff00ff
lineTo(x: 50, y: 50)
print("Command list is \(commands)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment