> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution > <[email protected]> wrote: > On Jun 2, 2016, at 1:30 PM, John McCall <[email protected] > <mailto:[email protected]>> wrote: > >>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson <[email protected] >>> <mailto:[email protected]>> wrote: >>> On Jun 2, 2016, at 12:01 PM, John McCall <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution >>>>> <[email protected] <mailto:[email protected]>> wrote: >>>>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu <[email protected] >>>>>> <mailto:[email protected]>> 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
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
