> 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

Reply via email to