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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution