That Integer Literal Thing

Last night I put up a tweet asking developers to participate in a one-question survey. Enough people asked me what this was about that I promised a quick post.

The Swift standard library include a number of conversion protocols that Matthew Johnson and I thought were badly named. The standard library includes about 80-odd protocols, and about 15% of them have to do with conversion.

So we submitted a renaming proposal that was rejected. The standard library team preferred to use a new Syntax namespace. Our proposal had focused on naming guidance. Their response was specific to implementation, under the philosophy umbrella that Swift Evolution proposals need to address real world design not set theoretical guidance. We could not find a middle ground but the discussion has continued post-WWDC as the problems remain without a solution. Matthew has been working on a new proposal.

When a type conforms to the IntegerLiteralConvertible protocol, it   “allows an integer literal to be interpreted as an expression having the conforming type”. To allow this behavior to happen, the conforming type implements an initializer that accepts Int and returns the type.

/// Conforming types can be initialized with integer literals.
public protocol IntegerLiteralConvertible {

    associatedtype IntegerLiteralType

    /// Create an instance initialized to `value`.
    public init(integerLiteral value: Self.IntegerLiteralType)
}

I think this would be better expressed something like this:

/// Conformance allows integer literals to be interpreted
/// as an expression having the conforming type. 
///
/// ```
/// let instance: T = *integer literal*
/// ```
/// 
/// for example:
/// 
/// ```
/// let myDouble: Double = 2 // The literal 2 is automatically cast
/// let anotherDouble: Double = myDouble * 5 // The literal 5 is automatically cast
/// ```
///
public protocol NAME_TO_BE_DETERMINED {

    ///  For constrained integer literal types, which otherwise default to `Int`.
    associatedtype IntegerLiteralType

    /// Create an instance initialized to `value`.
    ///  Required to enable in-line syntax substitutions
    public init(integerLiteral value: Self.IntegerLiteralType)
}

The question of the protocol name is a tricky one. Discussion members  suggested Syntax.IntegerLiteral and Syntax.IntegerLiteralExpressible, both of which I find lacking. I don’t think they convey the intended meaning.

Last night I asked Swift developers what they thought Syntax.IntegerLiteralExpressible meant and here are the results. By a margin of about 9:1 they felt it meant “The conforming type can express itself as an integer literal.” There’s a tab at the top of the linked page that enables you to switch between “Question Summaries” and “Individual Responses”, so you can see how the explanations pair with survey responses.

Update: Dave Abrahams responds: 

[T]he only correct-ish option you gave people is slightly awkward and inaccurate—I’d have said “Instances of the conforming type can be expressed as integer literals,” but that matches the 90% meaning almost exactly; certainly much better than the 10%.

As far as I can tell, your poll supports my suggestion.

While conversion protocols exist almost exclusively for the consumption of types declared in the standard library, they (like their current brethren) will be seen, read about, and their effects used by regular Swift developers. In that light, I think there’s value in pursuing good naming. Hopefully Swift ends up with something better than Syntax.AllowsIntegerLiteralToBeInterpretedAsExpressionOfConformingType.

Comments are closed.