[swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

Erica Sadun erica at ericasadun.com
Thu Jun 2 14:58:39 CDT 2016

> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
> On Jun 2, 2016, at 1:30 PM, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>>> On Jun 2, 2016, at 12:01 PM, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>>>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
> We could have a primary initializer like this:
> init(_ type: T.Type)
> It would look better than a default initializer that requires the type to be passed as a generic argument.  The fact that it is not labeled would make it clear that this is the primary initializer.
>> I still think the value-based APIs are misleading and that it would be better to ask people to just use a type explicitly.
> Sure.  I don't necessarily disagree.  But I think it's important to make clear that this is orthogonal to the struct vs free function discussion.  That was the main point I was trying to make.  :)
>>> Adding the label will eliminate the potential for confusion about type vs metatype.  Wanting to know the size of the metatype is probably extremely rare, but there is not reason to prohibit it.
>> I agree that the label makes the problem better.
>> John.

I do want to say that while I'm including this in Alternatives Considered (and will update as soon as we finish lunch), that I stand by the freestanding functions as preferable to this clever but extremely indirect approach.

I believe the MemoryLayout type introduces a level of indirection that is less helpful in the rare times the user will consume this functionality, that it clutters calls and adds cognitive burden for reading code.

Let me give you some examples:

let errnoSize = sizeof(errno.dynamicType)
return sizeof(UInt) * 8
sendBytes(from: &address, count: sizeof(UInt.self))
_class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
bytesPerIndex: sizeof(IndexType))

In every example, calling a size function's clarity is simpler than using the Memory Layout approach:

let errnoSize = MemoryLayout.init(t: errno).size
return MemoryLayout<UInt>.size * 8
sendBytes(from: &address, count: MemoryLayout<UInt>.size)
_class_getInstancePositiveExtentSize(bufferClass) == MemoryLayout<_HeapObject.self>.size
bytesPerIndex: MemoryLayout<IndexType>.size

The full type specification lends the calls an importance and verbosity they don't deserve compared to their simpler counterparts. The eye is drawn every time to the "MemoryLayout<T>" pattern:

* Prominence of the type constructor
* Simplicity of the function call
* Number of code characters used
* Swift's adherence to a mantra of concision and clarity.

It fails all these. To put it in usability terms: it's a big stinking mess compared to the readability and eye tracking of the simpler function. (I've cc'ed in Chris Lattner, who has people who can test this kind of thing on call.)

-- E

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160602/d41e68e7/attachment.html>

More information about the swift-evolution mailing list