[swift-evolution] MemoryLayout for a value

Dave Abrahams dabrahams at apple.com
Wed Aug 3 23:27:47 CDT 2016


on Wed Aug 03 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote:

> Why not just MemoryLayout.init(of instance: T), and drop the autoclosure
> magic altogether?

My proposal *does* drop the autoclosure magic.  `type(of: x)` is already in
the standard library (replacing `x.dynamicType`). The reasons not to have:

   MemoryLayout(of: x)

where x is an arbitrary instance, is that it reads and pronounces the
same as

   MemoryLayout<X>

but has different meaning, and even a different type (which results in
additional API complexity—the forwarding vars I showed in the [Aside]
box from my previous post).  Imagine explaining the difference between
these two in that world:

   MemoryLayout<Int>
   MemoryLayout(of: Int.self)

The first is a type representing the layout of Int.  The second is an
instance of that type representing the layout of Int's metatype.
 
> The classic sizeofValue evaluated its argument, and in Foundation several
> uses of it actually relied on that side effect. While autoclosures are
> quite clever, in general I think the user expectation is that given
> `a(b(c))` both a and b are invoked, side effects and all.
>
> Note that both type(of:) as it's currently implemented and the old
> dynamicType evaluate its argument/receiver. 

I didn't realize that, but it's fine.  I'm attached to the use of
`type(of:)` in this idiom, not to having an autoclosure involved.

> No one afaik has ever thought that behavior to be anomalous (though I
> bet we're about to hear some arguments to that effect now).  
>
> On Wed, Aug 3, 2016 at 15:46 Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> Having seen the effects in the standard library and in other
>> code, I'm concerned that we may have made a mistake in removing
>> `sizeofValue` et al without providing a replacement.  In the standard
>> library, we ended up adding an underscored API that allows
>>
>>   MemoryLayout._ofInstance(someExpression).size
>>
>> Where someExpression is an autoclosure, and thus not evaluated.  I
>> wanted to bring up the possibility of introducing a replacement as a
>> bufix.
>>
>> I propose that the way to express the above should be:
>>
>>   MemoryLayout.of(type(of: someExpression)).size
>>
>> implementable as:
>>
>>   extension MemoryLayout {
>>     @_transparent
>>     public
>>     static func of(_: T.Type) -> MemoryLayout<T>.Type {
>>       return MemoryLayout<T>.self
>>     }
>>   }
>>
>> I think this API would solve the concerns I had about confusability that
>> led me to advocate dropping the ability to ask for the size of a value.
>> The only way to use it is to pass a type and these two expressions have
>> equivalent meaning:
>>
>>     MemoryLayout<Int>
>>     MemoryLayout.of(Int.self)
>>
>> It also has the benefit of isolating the autoclosure magic to type(of:).
>>
>> ,----[ Aside ]
>> | A slightly cleaner use site is possible with a larger API change:
>> |
>> |   MemoryLayout(type(of: someExpression)).size
>> |
>> | Which would involve changing MemoryLayout from an `enum` to
>> | a `struct` and adding the following:
>> |
>> |   extension MemoryLayout {
>> |     public init(_: T.Type) {}
>> |
>> |     public var size: Int { return MemoryLayout.size }
>> |     public var stride: Int { return MemoryLayout.stride }
>> |     public var alignment: Int { return MemoryLayout.alignment }
>> |   }
>> |
>> | However I am concerned that dropping ".of" at the use site is worth the
>> | added API complexity.
>> `----
>>
>> Thoughts?
>> --
>> -Dave
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>

-- 
-Dave


More information about the swift-evolution mailing list