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 < > [email protected]> 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 >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >> -- -Dave _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
