custom binding pattern matches

Sometimes I wish for custom *binding* patterns in Swift. Is something
like this already in the works? Anyone else wishing for this?

I have attached some code where I fake it, but these examples
show what I'm really after:

/* Match complex numbers, let expressions with type qualification: */

for elt in [1.0 + î, 2.0 + 3.0 * î, 4.0 + 5.0 * î, 6.0 * î] {
  switch elt {
  case î * (let d: Double):
    print("matched î * \(d)")
  case 1 + î * (let a: Double):
    print("matched 1 + î * \(a)")
  case (let b: Double) + î * (let c: Double):
    print("matched \(b) + î * \(c)")
  default:
    print("no match")
  }
}

/* Match complex numbers, let expressions with types inferred: */

for elt in [1.0 + î, 2.0 + 3.0 * î, 4.0 + 5.0 * î, 6.0 * î] {
  switch elt {
  case î * (let d):
    print("matched î * \(d)")
  case 1 + î * (let a):
    print("matched 1 + î * \(a)")
  case (let b) + î * (let c):
    print("matched \(b) + î * \(c)")
  default:
    print("no match")
  }
}

/* Match strings, assigning substrings to numeric types a la scanf(3): */

if case "\(let a: Double) + \(let b: Double) î" = "1 + 2 î" {
  print("matched \(a) + \(b) î")
}

/* Approximately match strings; `fuzz` is an "edit distance" between
* the pattern and the match.
*/

if case ApproximateMatch("\(let a: Double) + \(let b: Double) î", let fuzz) = "1 + 2 * î", fuzz < 5 {
  print("matched \(a) + \(b) î with fuzz \(d)")
}

/* Simplify an algebraic expression: n1 / d + n2 / d -> (n1 + n2) / d.

binding.swift (496 Bytes)

complex.swift (1.42 KB)

double.swift (1.39 KB)

main.swift (636 Bytes)

···

*
* Original source:
*/

if case .sum(.quotient(let ln, let ld),
             .quotient(let rn, let rd)) = expr, ld == rd {
  return evaluate(.quotient(.sum(ln, rn), ld), env)
}

/* => with operator overloading (no custom binding patterns) becomes: */

if case .sum(.quotient(let ln, let ld),
             .quotient(let rn, let rd)) = expr, ld == rd {
  return evaluate((ln + rn) / ld, env)
}

/* => with custom binding patterns and operator overloading becomes: */

if case (let ln: Expr) / (let ld: Expr) +
        (let rn: Expr) / (let rd: Expr) = expr, ld == rd {
  return evaluate((ln + rn) / ld, env)
}

/* => with type inference becomes: */

if case (let ln) / (let ld) + (let rn) / (let rd) = expr, ld == rd {
  return evaluate((ln + rn) / ld, env)
}

Dave

--
David Young
dyoung@pobox.com Urbana, IL (217) 721-9981

I'm also highly interested in this! Could someone knowledgeable please shed some light on this topic?

Terms of Service

Privacy Policy

Cookie Policy