Skip to content

Instantly share code, notes, and snippets.

@mattt
Last active April 21, 2023 17:14
Show Gist options
  • Save mattt/f457625af116721ffb57 to your computer and use it in GitHub Desktop.
Save mattt/f457625af116721ffb57 to your computer and use it in GitHub Desktop.
// See: https://devforums.apple.com/message/1000934#1000934
import Foundation
// Logic
operator prefix ¬ {}
@prefix func ¬ (value: Bool) -> Bool {
return !value
}
operator infix { associativity left precedence 120 }
func (left: Bool, right: Bool) -> Bool {
return left && right
}
operator infix { associativity left precedence 110 }
func (left: Bool, right: Bool) -> Bool {
return left || right
}
operator infix { associativity left precedence 140 }
func (left: Bool, right: Bool) -> Bool {
return left ^ right
}
operator infix { associativity left precedence 120 }
func (left: Bool, right: Bool) -> Bool {
return ¬(left right)
}
operator infix { associativity left precedence 110 }
func (left: Bool, right: Bool) -> Bool {
return ¬(left right)
}
operator prefix {}
@prefix func (condition: @auto_closure () -> Bool) {
assert(condition, "Assertion Failed")
}
// Math
operator infix × { associativity left precedence 150 }
func × (left: Double, right: Double) -> Double {
return left * right
}
operator infix ÷ { associativity left precedence 150 }
func ÷ (left: Double, right: Double) -> Double {
return left / right
}
operator infix { associativity left precedence 150 }
func (left: Double, right: Double) -> Double {
return left / right
}
operator prefix {}
@prefix func (number: Double) -> Double {
return sqrt(number)
}
operator prefix {}
@prefix func (number: Double) -> Double {
return cbrt(number)
}
operator infix ± { associativity left precedence 140 }
func ± (left: Double, right: Double) -> (Double, Double) {
return (left + right, left - right)
}
operator prefix ± {}
@prefix func ± (value: Double) -> (Double, Double) {
return 0 ± value
}
operator infix { associativity left precedence 140 }
func (left: Double, right: Double) -> (Double, Double) {
return (left - right, left + right)
}
operator prefix {}
@prefix func (value: Double) -> (Double, Double) {
return 0 value
}
operator infix { associativity left precedence 150 }
func (left: Int, right: Int) -> Bool {
return left % right == 0
}
operator infix { associativity left }
func (left: Int, right: Int) -> Bool {
return ¬(left right)
}
// Sets
operator infix { associativity left }
func <T: Equatable> (left: T, right: Array<T>) -> Bool {
let filtered = right.filter {$0 == left}
return filtered.count > 0
}
operator infix { associativity left }
func <T: Equatable> (left: T, right: Array<T>) -> Bool {
return ¬(left right)
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: T) -> Bool {
return right left
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: T) -> Bool {
return right left
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Array<T> {
var intersection: Array<T> = []
for value in left {
if value right {
intersection.append(value)
}
}
return intersection
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Array<T> {
var union: Array<T> = left
for value in right {
if ¬(value left) {
union.append(value)
}
}
return union
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
for value in left {
if ¬(value right) {
return false
}
}
return true
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return left == right || (left right)
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return left right
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return ¬(left right)
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return right left
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return right left
}
operator infix { associativity left }
func <T: Equatable> (left: Array<T>, right: Array<T>) -> Bool {
return left right
}
// Sequences
operator prefix {}
@prefix func (values: Array<Double>) -> Double {
return reduce(values, 0.0, +)
}
operator prefix {}
@prefix func (values: Array<Double>) -> Double {
return reduce(values, 1.0, *)
}
operator infix {}
func (left: Array<Double>, right: Array<Double>) -> Double? {
if left.count != right.count {
return nil
}
var product: Array<Double> = []
for (index, _) in enumerate(left) {
let (a, b) = (left[index], right[index])
product.append(a * b)
}
return product
}
// Comparison
operator infix { associativity left }
func <T: Equatable> (left: T, right: T) -> Bool {
return left == right
}
//operator infix ≤ { associativity left }
//func ≤<T: Equatable> (left: T, right: T) -> Bool {
// return left < right || left == right
//}
//operator infix ≥ { associativity left }
//func ≥<T: Equatable> (left: T, right: T) -> Bool {
// return left > right || left == right
//}
//operator infix ≬ { associativity left }
//func ≬<T: Equatable> (left: T, right: (T, T)) -> Bool {
// return left > right.0 && left < right.1
//}
@andymatuschak
Copy link

Cute, @mattt. :)

@smile0210
Copy link

Nice!

@ochococo
Copy link

ochococo commented Jul 9, 2014

Awesome!

@marzapower
Copy link

The "V" function should return "a || b" and not "a && b".

@beccadax
Copy link

I'm not sure if this is intentional, but your logic operators don't short-circuit the way the originals do. If that's a mistake, take a look at @auto_closure to see how to fix this.

@PopFlamingo
Copy link

Wow ! Awesome ! Thank you :)

@lonelytango
Copy link

wow...

@staypufd
Copy link

Very nice!

@xuvw
Copy link

xuvw commented Oct 28, 2014

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment