Having ExpressibleByStringInterpolation refine ExpressibleByStringLiteral makes sense. I think there's a more powerful alternative design you should also consider. If the protocol looked like this:
protocol ExpressibleByStringInterpolation: ExpressibleByStringLiteral { associatedtype LiteralSegment: ExpressibleByStringLiteral associatedtype InterpolatedSegment init(forStringInterpolation: Void) mutating func append(literalSegment: LiteralSegment) mutating func append(interpolatedSegment: InterpolatedSegment) } Then an interpolation expression like this in `Thingy` type context: "foo \(bar) bas \(zim: 1, zang: 2)\n" could desugar to something like: { var x = Thingy(forStringInterpolation: ()) // Literal segments get appended using append(literalSegment: "literal") x.append(literalSegment: "foo ") // \(...) segments are arguments to a InterpolatedSegment constructor x.append(interpolatedSegment: Thingy.InterpolatedSegment(bar)) x.append(literalSegment: " bas ") x.append(interpolatedSegment: Thingy.InterpolatedSegment(zim: 1, zang: 2)) return x }() This design should be more efficient, since there's no temporary array of segments that needs to be formed for a variadic argument, you don't need to homogenize everything to Self type up front, and the string can be built up in-place. It also provides means to address problems 3 and 4, since the InterpolatedSegment associated type can control what types it's initializable from, and can provide initializers with additional arguments for formatting or other purposes. -Joe
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution