Sent from my iPad

> On Jun 2, 2016, at 12:01 PM, John McCall <[email protected]> wrote:
> 
>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>> <[email protected]> wrote:
>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu <[email protected]> wrote:
>>> 
>>> Well, as I understand it, it's not actually possible to write your own 
>>> type(of:), so we're going from a "magic" property to a "magic" function at 
>>> least for now.
>> 
>> No, but you *can* write `func foo<T>(_ t: T)` which accepts any value (you 
>> *cannot* write a property that is available for all properties - that would 
>> require the ability to write `extension Any`.  This is the distinction I am 
>> making.  Of course the implementation is compiler magic no matter how we 
>> express it syntactically.  But we can make it *appear* just like it might if 
>> the implementation *wasn’t* compiler magic.  That makes it fit into the 
>> language better IMO and was the biggest motivator for changing `dynamicType`.
>> 
>>> 
>>> I'm most alarmed that one implication of the MemoryLayout proposal is loss 
>>> of the `ofValue` family of functions. These functions don't fit with the 
>>> design: imagine, what is `MemoryLayout<Double>.size(ofValue: Float(42))`? 
>>> But the response seems to be that these functions don't seem necessary at 
>>> all and should be removed. "I don't see a use for it" is an insufficient 
>>> justification for a feature removal. Looking to other languages, C# has 
>>> sizeof as a static property but tellingly offers the equivalent of 
>>> sizeofValue (well, strideofValue) as a function in a different module. 
>>> Essentially every other C-family language that exposes pointers to the user 
>>> offers both of and ofValue equivalents. The question is, how does a user 
>>> with existing code using sizeofValue() migrate to Swift 3? I do not see a 
>>> viable answer with the MemoryLayout design.
>> 
>> Going with MemoryLayout *does not* mean we would have to give up the value 
>> functions if we don’t want to:
>> 
>> struct MemoryLayout<T> {
>>     init() {}
>>     init(t: T) { /* throw away the value */ }
>>     
>>     // we could omit the static properties and require 
>>     // writing MemoryLayout<Int>() if we don’t like the duplication
>>     static let size: Int
>>     static let spacing: Int
>>     static let alignment: Int
>> 
>>     let size: Int
>>     let spacing: Int
>>     let alignment: Int
>> }
>> 
>> let size = MemoryLayout<Int>.size
>> let sizeOfValue = MemoryLayout(42).size
> 
> There's no good reason for this type to be generic.  It should be non-generic 
> and require the use of the instance properties.

Dave's initial suggestion was generic and Joe suggested static properties.  I 
suppose it doesn't have to be generic if we pass the type directly to the 
initializer, but that design would eliminate the possibility of inferring the 
type from a value (which some people seem to want to retain).

I didn't mean to advocate either way about adding a value initializer and 
instance properties.  I was only trying to show that it is *possible* to do 
that if we want to preserve the ofValue capabilities.

> 
> It's actively harmful for this type to appear to be computed from a value.  
> The layout is not in any way tied to the dynamic type of the value — for 
> example, it is not the instance layout of the most-derived class or the value 
> layout of the dynamic type of an existential.  

Understood, but that same problem exists for the current ofValue operations 
doesn't it? We can discuss removing them (I am not opposed to that), but that 
is independent of whether we should use a MemoryLayout struct as opposed to 
free functions.

> Furthermore, saying that it is computed from a value means that attempting to 
> compute it from a type will succeed using the layout of the metatype, which 
> seems like a catastrophic failure of API design.

I was a bit hasty with the argument label and my example calling code wouldn't 
have actually worked.  I should have included a clear external label.

This is what we would want to actually do (Erica, can you update again?):

init(ofValue: @autoclosure () -> T) { }

Used like this:

let sizeOfValue = MemoryLayout(ofValue: 42).size

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.

> 
> John.
> 
>> 
>>> 
>>>> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson <[email protected]> 
>>>> wrote:
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> 
>>>>> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
>>>>> <[email protected]> wrote:
>>>>> 
>>>>>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith <[email protected]> 
>>>>>> wrote:
>>>>>> I really like this idea. This IMO is lower level functionality than 
>>>>>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>>>>>> grouped under its own domain, the MemoryLayout type.
>>>>>> 
>>>>>> Plus MemoryLayout can be extended with new convenience methods.
>>>>>> 
>>>>>> I’m fine with those old methods being removed, but I never use them so! 
>>>>>> Is it the same as calling type(of:) then using that with MemoryLayout? I 
>>>>>> imagine they could be fixit’d easily, and that they compile down to the 
>>>>>> same underlying code.
>>>>> 
>>>>> I'm actually souring to the idea. It goes in the diametrically opposite 
>>>>> direction from dynamicType. There, something was changed from being 
>>>>> property-like to being function-like. Here, Dave's proposal would take 
>>>>> something that's a function and turn it into a property. Hmm.
>>>> 
>>>> That's not a fair comparison though.  With dynamicType we removed a 
>>>> "magic" property visible on all types, which isn't something you can write 
>>>> and turned it into a function (which is obviously something you can 
>>>> write).  
>>>> 
>>>> Dave's MemoryLayout creates a new type to bundle together related items 
>>>> which makes their semantic relationship more clear.  It also receives the 
>>>> type via a generic argument rather than a function argument and makes the 
>>>> properties static.  That is more representative of what is actually 
>>>> happening and could help to prevent confusion.  
>>>> 
>>>> If we really need an 'ofValue' option that infers T from a value the 
>>>> properties on MemoryLayout could also be made available as instance 
>>>> properties and it could have an initializer that accepts an instance to T 
>>>> and throws the value away.  However, I'm not at all convinced this is 
>>>> necessary.
>>>> 
>>>>>>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution 
>>>>>>> <[email protected]> wrote:
>>>>>>> 
>>>>>>> 2. Dave A. and others expressed the opinion that these should probably 
>>>>>>> not be global functions; his preference was for:
>>>>>>> 
>>>>>>> ```
>>>>>>> MemoryLayout<T>.size // currently sizeof()
>>>>>>> MemoryLayout<T>.spacing // currently strideof()
>>>>>>> MemoryLayout<T>.alignment // currently alignof()
>>>>>>> ```
>>>>>>> 
>>>>>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and 
>>>>>>> alignofValue() are better off removed altogether. I don't know if 
>>>>>>> people are going to be happy about this idea.
>>>>> 
>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected]
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to