[swift-evolution] [Review] SE-0091: Improving operator requirements in protocols

Brent Royal-Gordon brent at architechies.com
Tue May 24 01:22:55 CDT 2016


> It does privilege the left-hand side of a binary operator, but I think that’s acceptable for the operators we’ve seen in practice. (Of course we would need real data to back that up.)

I'm not quite so convinced that privileging the left side isn't a big deal—think of all the mandatory type checks and other chicanery in an `-isEqual:` implementation—but I wonder if we can avoid privileging the left-hand side at all. For instance, suppose use of an infix operator "looked" like this:

	(lhs, rhs).==()

And method dispatch on a tuple was defined to use the dynamic types of all members of the tuple, with some kind of multimethod dispatch system. Then both operands participate equally in the dispatch, and a case with disparate subclasses will fall back to a superclass.

	// Note: This is, admittedly, an incredibly funky syntax.
	protocol Equatable {
		extension <T: Equatable>(T, T) {
			func ==() -> Bool
		}
	}

	class Car: Equatable {
		let vin: String
	}
	extension (Car, Car) {
		func ==() -> Bool {
			return self.0.vin == self.1.vin
		}
	}
	
	class Taxi: Car {
		var cabNumber: String
	}
	extension (Taxi, Taxi) {
		func ==() -> Bool {
			return self.0.cabNumber == self.1.cabNumber
		}
	}
	
	class Uber: Car {
		var driverID: Int64
	}
	extension (Uber, Uber) {
		func ==() -> Bool {
			return self.0.driverID == self.1.driverID
		}
	}

	// Note that I'm erasing the subclasses here.
	let taxi: Automobile = Taxi()
	let uber: Automobile = Uber()

	taxi == taxi	// Compares by cabNumber
	uber == uber	// Compares by driverID
	taxi == uber	// Compares by vin

Multimethod dispatch at runtime is relatively slow, but it *would* give us the exact behavior we want.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list