The built-in support for Unicode variables and operators in Swift opens the door to some interesting experiments.
First, a quick implementation of numerical function integration.
// For more complex ideas around these subjects,
// https://github.com/mattt/Euler/blob/master/Euler.swift
import Foundation
let π : Double = .pi
typealias ScalarFunction = (Double) -> Double
typealias Trapezoidal = (Double, Double) -> Double
prefix operator ∑
prefix func ∑ (array: [Double]) -> Double {
var result = 0.0
array.forEach { value in
result += value
}
return result
}
let sum = ∑[1, 2, 3, 5, 8, 13]
func ~= (left: Double, right: Double) -> Bool {
let ε : Double = 0.001
let δ = left - right
return abs(δ) <= ε
}
// Function taken from the "fast numeric integral" example from
// http://www.codeproject.com/Articles/31550/Fast-Numerical-Integration
func f (x: Double) -> Double {
return exp(-x / 5.0) * (2.0 + sin(2.0 * x))
}
// Trapezoidal rule adapted from
// http://www.numericmethod.com/About-numerical-methods/numerical-integration/trapezoidal-rule
prefix operator ∫
prefix func ∫ (f: @escaping ScalarFunction) -> Trapezoidal {
return { (min : Double, max : Double) -> (Double) in
let steps = 50
let h = abs(min - max) / Double(steps)
var surfaces = [Double]()
for position in 0 ..< steps {
let x1 = min + Double(position) * h
let x2 = x1 + h
let y1 = f(x1)
let y2 = f(x2)
let s = (y1 + y2) * h / 2
surfaces.append(s)
}
return ∑surfaces
}
}
let integral = (∫f) (0, 100)
let sinIntegral = ∫sin
let curve1 = sinIntegral(0, π/2)
let curve2 = sinIntegral(0, π)
assert(curve1 ~= 1, "Almost 1")
assert(curve2 ~= 2, "Almost 2")
print("sum: \(sum)")
print("integral: \(integral)")
print("curve1: \(curve1)")
print("curve2: \(curve2)")
And here’s a small implementation of Set theory, leading to De Morgan’s Laws at the very bottom.
// Set operations taken from
// https://en.wikipedia.org/wiki/Set_(mathematics)
// Operator association groups taken from
// https://developer.apple.com/reference/swift/1851035-swift_standard_library_operators
// Typealias for the whole exercise
typealias MathSet = Set<AnyHashable>
// Required for the cartesian product, adapted from
// http://stackoverflow.com/a/37324570
struct Pair<T: Hashable, U: Hashable> : Hashable, CustomStringConvertible {
let first : T
let second: U
var hashValue : Int {
return first.hashValue &* 31 &+ second.hashValue
}
var description: String {
return "\(first), \(second)"
}
public static func == (lhs: Pair, rhs: Pair) -> Bool {
return lhs.first == rhs.first && lhs.second == rhs.second
}
}
// The empty set
let Ø = MathSet()
// The "Universal" set
var U = MathSet()
// Creation operators
// Every time a new set is created, we add its contents to the
// universal set created above
prefix operator ⟨
prefix func ⟨ (array: [AnyHashable]) -> MathSet {
for obj in array {
U.insert(obj)
}
return MathSet(array)
}
postfix operator ⟩
postfix func ⟩ (array: [AnyHashable]) -> [AnyHashable] {
return array
}
// Intersection
infix operator ∩ : MultiplicationPrecedence
func ∩ (s1: MathSet, s2: MathSet) -> MathSet {
return s1.intersection(s2)
}
// Union
infix operator ∪ : AdditionPrecedence
func ∪ (s1: MathSet, s2: MathSet) -> MathSet {
return s1.union(s2)
}
// Belongs
infix operator ∈ : ComparisonPrecedence
func ∈ (obj: Any, set: MathSet) -> Bool {
return set.contains(obj as! AnyHashable)
}
// Does not belong
infix operator ∉ : ComparisonPrecedence
func ∉ (obj: Any, set: MathSet) -> Bool {
return !(obj ∈ set)
}
// Subset
infix operator ⊆ : ComparisonPrecedence
func ⊆ (s1: MathSet, s2: MathSet) -> Bool {
return s1.isSubset(of: s2)
}
// Cardinality
prefix operator |
prefix func | (set: MathSet) -> Int {
return set.count
}
postfix operator |
postfix func | (set: MathSet) -> MathSet {
return set
}
// Relative complement
infix operator ∖ : MultiplicationPrecedence
func ∖ (s1: MathSet, s2: MathSet) -> MathSet {
return s1.subtracting(s2)
}
// Absolute complement
postfix operator ′
postfix func ′ (set: MathSet) -> MathSet {
return U ∖ set
}
// Symmetric difference
infix operator ∆ : AdditionPrecedence
func ∆ (s1: MathSet, s2: MathSet) -> MathSet {
return s1.symmetricDifference(s2)
}
// Cartesian product
infix operator × : MultiplicationPrecedence
func × (s1: MathSet, s2: MathSet) -> MathSet {
var result = Set<Pair<AnyHashable, AnyHashable>>()
for obj1 in s1 {
for obj2 in s2 {
let pair = Pair(first: obj1, second: obj2)
result.insert(pair)
}
}
return result
}
let A = ⟨[1, "alpha", "beta", "gamma", 23, 23]⟩
let B = ⟨["omega", "gamma", "delta", 23, 63, 1, 1, 1]⟩
let C = ⟨[1, "alpha"]⟩
let D = ⟨["Brazil", "Switzerland", "Austria"]⟩
let intersection = A ∩ B
let union = A ∪ B
let isNotSubset = A ⊆ B
let isSubset = C ⊆ A
let cardinality = |A|
let subtracted = B ∖ A
let complement = A′
let symmetric = A ∆ B
let product = A × B
let noAlpha = "alpha" ∈ B
let yesAlpha = "alpha" ∉ B
// Print the whole universe
print(U)
// Asserting some basic properties of sets
assert(A == A , "A set is equal to itself")
assert(A != B , "A set is not equal to others")
assert(A ∩ B == B ∩ A , "Intersection is commutative")
assert(A ∪ B == B ∪ A , "Union is commutative")
assert(A ∪ A == A , "Union with itself is neutral")
assert(A ∪ Ø == A , "The empty set is neutral in union")
assert((C ⊆ A) && (C ∪ A) == A , "Condition to be a subset")
assert((A ⊆ (A ∪ B)) , "Condition of inclusion")
assert(A ∖ A == Ø , "Removing a set from itself yields the empty set")
assert(A ⊆ U , "Any set is part of the Universal set")
assert(B ⊆ U , "Any set is part of the Universal set")
assert(C ⊆ U , "Any set is part of the Universal set")
assert(A ∪ A′ == U , "The union of a set with its complementary yields the universal set")
assert(|(A × B)| == |A| * |B| , "The number of items in a product set is equal to the product of the number of items")
assert(A × Ø == Ø , "The empty set is the absorbing element of the product")
assert(A × (B ∪ C) == A × B ∪ A × C, "Product is distributive")
assert(A × B ∪ A × C == (A × B) ∪ (A × C), "Associative laws are applied correctly")
// De Morgan's Laws
assert((A ∪ B)′ == A′ ∩ B′ , "First law: the complement of A union B equals the complement of A intersected with the complement of B.")
assert((A ∩ B)′ == A′ ∪ B′ , "Second law: the complement of A intersected with B is equal to the complement of A union to the complement of B.")