Sent from my iPad

> On Jun 2, 2016, at 1:30 PM, John McCall <[email protected]> wrote:
> 
>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson <[email protected]> wrote:
>>> 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.
> 
> I'm not trying to dictate the entire design.  I'm saying that, if you're 
> going to have a layout structure, I see no reason for it to be generic, and 
> you should absolutely not make the primary way of constructing it be 
> implicitly value-based.

I'm interested to hear what others have to say about making this type generic 
or not.  I don't have a strong opinion about that.  I wonder if the initial 
motivation for that approach was that you would not create instances, just use 
the static properties.

I didn't consider the value-based initializer primary.  The generic parameter 
and default initializer is what I considered primary (following the previous 
discussion).

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.
> 
>> 
>>> 
>>> 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