Sent from my iPad
> On Jun 2, 2016, at 2:58 PM, Erica Sadun <er...@ericasadun.com> wrote: > > >> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote: >> On Jun 2, 2016, at 1:30 PM, John McCall <rjmcc...@apple.com> wrote: >> >>>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson <matt...@anandabits.com> >>>> wrote: >>>> On Jun 2, 2016, at 12:01 PM, John McCall <rjmcc...@apple.com> wrote: >>>> >>>>>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution >>>>>>> <swift-evolution@swift.org> wrote: >>>>>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu <xiaodi...@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.) I don't disagree with the points you make. But one can argue that this is a good thing. It calls attention to code that requires extra attention and care. In some ways this is similar to 'UnsafeMutablePointer<T>' vs '*T'. Verbosity was a deliberate choice in that case. > > -- E > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution