[Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

Upon accepting SE-0098, the core team renamed the proposed stdlib function from dynamicType() to type(of:). They write, "The core team recognizes that this means that we should probably resyntax the existing sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

-- E

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

···

On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

Upon accepting SE-0098, the core team renamed the proposed stdlib function
from dynamicType() to type(of:). They write, "The core team recognizes
that this means that we should probably resyntax the existing
sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

If it's worth continuing the discussion in this thread, I rather like the
MemoryLayout<T>.size idea. For discoverability, we might want to have
@availability(*, unavailable, message: "use MemoryLayout<T>.size, etc.")
public init(){}.

Jacob

···

On Wed, Jun 1, 2016 at 9:55 PM, Xiaodi Wu via swift-evolution < swift-evolution@swift.org> wrote:

On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

Upon accepting SE-0098, the core team renamed the proposed stdlib
function from dynamicType() to type(of:). They write, "The core team
recognizes that this means that we should probably resyntax the existing
sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

And added alignof/alignofValue plus the original discussion thread

-- E

···

On Jun 1, 2016, at 10:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Upon accepting SE-0098, the core team renamed the proposed stdlib function from dynamicType() to type(of:). They write, "The core team recognizes that this means that we should probably resyntax the existing sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

To summarize the previous discussion:

1. Per Joe Groff, although sizeof() and friends are treated as
terms-of-art, these names were lifted straight from C and do not correspond
to anything named "sizeof" in LLVM.

2. There are issues with using a name such as stride(of:), because
stride(...) already means something else in the stdlib; moreover, size(of:)
isn't the best name for something that doesn't do what its C namesake does;
therefore, larger changes to the naming were suggested.

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.

* * *

If we take inspiration from type(of:), then it's actually sizeofValue(),
etc., that should be renamed size(of:), etc. Also, a fun tidbit is that
what's currently called sizeof(), etc.--the ones that take types rather
than values--are actually not very good candidates for having parameter
labels, because it's OK to write `sizeof(Int)`, but one must currently
write `size(of: Int.self)` when the function has a label.

···

On Wed, Jun 1, 2016 at 11:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

Upon accepting SE-0098, the core team renamed the proposed stdlib
function from dynamicType() to type(of:). They write, "The core team
recognizes that this means that we should probably resyntax the existing
sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

It's a nice syntax, but I'm not fully comfortable with the suggestion that
sizeofValue(), etc. should go. Also, I wonder about the static vs. dynamic
type issue here (despite having started the last thread, I still haven't
sat down to think it through).

···

On Thu, Jun 2, 2016 at 12:03 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

If it's worth continuing the discussion in this thread, I rather like the
MemoryLayout<T>.size idea. For discoverability, we might want to have
@availability(*, unavailable, message: "use MemoryLayout<T>.size, etc.")
public init(){}.

Updated with all the feedback so far. Will keep an eye on this.

-- E

···

On Jun 1, 2016, at 11:10 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, Jun 2, 2016 at 12:03 AM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:
If it's worth continuing the discussion in this thread, I rather like the MemoryLayout<T>.size idea. For discoverability, we might want to have @availability(*, unavailable, message: "use MemoryLayout<T>.size, etc.") public init(){}.

It's a nice syntax, but I'm not fully comfortable with the suggestion that sizeofValue(), etc. should go. Also, I wonder about the static vs. dynamic type issue here (despite having started the last thread, I still haven't sat down to think it through).

Upon accepting SE-0098, the core team renamed the proposed stdlib function from dynamicType() to type(of:). They write, "The core team recognizes that this means that we should probably resyntax the existing sizeof/strideof functions, but that should be a follow-on discussion."

Follow on discussion started. Have at it.

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

To summarize the previous discussion:

1. Per Joe Groff, although sizeof() and friends are treated as terms-of-art, these names were lifted straight from C and do not correspond to anything named "sizeof" in LLVM.

2. There are issues with using a name such as stride(of:), because stride(...) already means something else in the stdlib; moreover, size(of:) isn't the best name for something that doesn't do what its C namesake does; therefore, larger changes to the naming were suggested.

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()

Thanks for the summary. I missed the original thread.

I think I like this approach despite its verbosity. Will give it a little bit more thought...

···

Sent from my iPad

On Jun 2, 2016, at 12:05 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Wed, Jun 1, 2016 at 11:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

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.

* * *

If we take inspiration from type(of:), then it's actually sizeofValue(), etc., that should be renamed size(of:), etc. Also, a fun tidbit is that what's currently called sizeof(), etc.--the ones that take types rather than values--are actually not very good candidates for having parameter labels, because it's OK to write `sizeof(Int)`, but one must currently write `size(of: Int.self)` when the function has a label.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

Patrick

···

On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> 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.

Upon accepting SE-0098, the core team renamed the proposed stdlib function from dynamicType() to type(of:). They write, "The
core team recognizes that this means that we should probably resyntax the existing sizeof/strideof functions, but that should be
a follow-on discussion."

Follow on discussion started. Have at it.

See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830

To summarize the previous discussion:

1. Per Joe Groff, although sizeof() and friends are treated as terms-of-art, these names were lifted straight from C and do not correspond to
anything named "sizeof" in LLVM.

2. There are issues with using a name such as stride(of:), because stride(...) already means something else in the stdlib; moreover, size(of:) isn't
the best name for something that doesn't do what its C namesake does; therefore, larger changes to the naming were suggested.

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()

I'd also be willing to see memoryLayout(T.self).size, if pressed.

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.

I would be happy to hear from people about their use-cases that become
utterly unreadable when

  sizeofValue(x)

is replaced by

  MemoryLayout<x.Self>.size

or

  memoryLayout(type(of: x)).size

But if we don't have strong evidence that such use-cases exist, I am
strongly biased toward removing those functions. These incredibly
low-level facilities are seldom used, even within the standard library.
It would take a very strong argument to convince me that the exposed API
should be broader than absolutely necessary in this area.

···

on Wed Jun 01 2016, Xiaodi Wu <swift-evolution@swift.org> wrote:

On Wed, Jun 1, 2016 at 11:55 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> > wrote:

* * *

If we take inspiration from type(of:), then it's actually sizeofValue(), etc., that should be renamed size(of:), etc. Also, a fun tidbit is that what's
currently called sizeof(), etc.--the ones that take types rather than values--are actually not very good candidates for having parameter labels,
because it's OK to write `sizeof(Int)`, but one must currently write `size(of: Int.self)` when the function has a label.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

Using MemoryLayout is a much bigger change than the simple name changes being pitched here. I'm not ruling it out, but it may be deferred or additive as the 3.0 timeline allows and the core team decides.

For now, my suggested design (strongly based on Wux's feedback and the previous thread discussion) is:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(of: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(ofValue: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(ofValue: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(of: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(ofValue: T) -> Int

···

On Jun 1, 2016, at 11:24 PM, Patrick Smith <pgwsmith@gmail.com> 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.

Patrick

On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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.

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.

···

On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith <pgwsmith@gmail.com> wrote:

On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> 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.

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(of: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(ofValue: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(ofValue: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(of: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(ofValue: T) -> Int

If `type(of:)` takes an instance, then I think `size(of:)`, `spacing(of:)` and `align(of:)` need to do the same, with `size(ofType:)`, `spacing(ofType:)`, and `align(ofType:)` handling the type side of things.

···

--
Brent Royal-Gordon
Architechies

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.

···

Sent from my iPad

On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:
On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith <pgwsmith@gmail.com> wrote:

On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> 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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(of: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(ofValue: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(ofValue: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(of: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func align<T>(ofValue: T) -> Int

If `type(of:)` takes an instance, then I think `size(of:)`, `spacing(of:)` and `align(of:)` need to do the same, with `size(ofType:)`, `spacing(ofType:)`, and `align(ofType:)` handling the type side of things.

+1 if we stick with the function direction. But I'm not convinced this is the best direction.

···

Sent from my iPad
On Jun 2, 2016, at 6:26 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Supporting Dave A, type-based calls are much more likely to be used than instance calls, unlike with dynamicType/type(of:)

Term stdlib search gist search Google site:github +swift
sizeof 157 169 4880
sizeofValue 4 34 584
alignof 44 11 334
alignofValue 5 5 154
strideof 347 19 347
strideofValue 4 5 163
Type-based calls like sizeof() are poor candidates for parameter labels. While it's acceptable to write sizeof(Int), but one must write size(of: Int.self) (with the trailing self) when the function has a label. For this reason, this proposal prefers using no-label calls for types (otherwise they would have been ofType) and labeled calls for values:

print(sizeof(Int)) // works
print(sizeof(Int.self)) // works

func withoutLabel<T>(thetype: T.Type) -> Int { return sizeof(T) }
func withLabel<T>(label label: T.Type) -> Int { return sizeof(T) }

// Works
print(withoutLabel(Int))

// Works
print(withLabel(label: Int.self))

// Does not work
// error: cannot create a single-element tuple with an element label
// print(withLabel(label: Int))

So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(_: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(of: T) -> Int
-- E

And following up to myself.

Please look here: https://github.com/erica/swift-evolution/blob/0f93c3c31b1d59358a61a5e2608dc71a598d9316/proposals/XXXX-sidestride.md

Plus, I fixed the typos in strideof/strideofValue's counts.

-- E

···

On Jun 2, 2016, at 8:43 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Supporting Dave A, type-based calls are much more likely to be used than instance calls, unlike with dynamicType/type(of:)

Term stdlib search gist search Google site:github +swift
sizeof 157 169 4880
sizeofValue 4 34 584
alignof 44 11 334
alignofValue 5 5 154
strideof 347 19 347
strideofValue 4 5 163
Type-based calls like sizeof() are poor candidates for parameter labels. While it's acceptable to write sizeof(Int), but one must write size(of: Int.self) (with the trailing self) when the function has a label. For this reason, this proposal prefers using no-label calls for types (otherwise they would have been ofType) and labeled calls for values:

print(sizeof(Int)) // works
print(sizeof(Int.self)) // works

func withoutLabel<T>(thetype: T.Type) -> Int { return sizeof(T) }
func withLabel<T>(label label: T.Type) -> Int { return sizeof(T) }

// Works
print(withoutLabel(Int))

// Works
print(withLabel(label: Int.self))

// Does not work
// error: cannot create a single-element tuple with an element label
// print(withLabel(label: Int))

So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(_: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(of: T) -> Int
-- E
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Supporting Dave A, type-based calls are much more likely to be used than instance calls, unlike with dynamicType/type(of:)

Term stdlib search gist search Google site:github +swift
sizeof 157 169 4880
sizeofValue 4 34 584
alignof 44 11 334
alignofValue 5 5 154
strideof 347 19 347
strideofValue 4 5 163
Type-based calls like sizeof() are poor candidates for parameter labels. While it's acceptable to write sizeof(Int), but one must write size(of: Int.self) (with the trailing self) when the function has a label.

Isn’t this a short-term concern? I thought that requirement was going away.

···

On Jun 2, 2016, at 9:43 AM, Erica Sadun <erica@ericasadun.com> wrote:

For this reason, this proposal prefers using no-label calls for types (otherwise they would have been ofType) and labeled calls for values:

print(sizeof(Int)) // works
print(sizeof(Int.self)) // works

func withoutLabel<T>(thetype: T.Type) -> Int { return sizeof(T) }
func withLabel<T>(label label: T.Type) -> Int { return sizeof(T) }

// Works
print(withoutLabel(Int))

// Works
print(withLabel(label: Int.self))

// Does not work
// error: cannot create a single-element tuple with an element label
// print(withLabel(label: Int))

So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(_: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(of: T) -> Int
-- E

That proposal was returned for revision; as far as user ergonomics in Swift 3, .self is going to be a consideration. Best to find a solution that reads nicely regardless of the situation with .self removal.

From the core team decision:

"The core team would definitely like to circle back to this proposal after Swift 3 is out the door."

I think we should consider the best long-term design. If that happens to be dropping labels great, but if not, maybe we don’t want to do that just because it will look better in Swift 3 at the cost of a better design when “.self” is not required.

Dave’s MemoryLayout approach avoids the question of labels entirely. This is another subtle nudge in that direction IMO.

···

On Jun 2, 2016, at 10:03 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, Jun 2, 2016 at 9:57 AM Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

On Jun 2, 2016, at 9:43 AM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

Supporting Dave A, type-based calls are much more likely to be used than instance calls, unlike with dynamicType/type(of:)

Term stdlib search gist search Google site:github +swift
sizeof 157 169 4880
sizeofValue 4 34 584
alignof 44 11 334
alignofValue 5 5 154
strideof 347 19 347
strideofValue 4 5 163
Type-based calls like sizeof() are poor candidates for parameter labels. While it's acceptable to write sizeof(Int), but one must write size(of: Int.self) (with the trailing self) when the function has a label.

Isn’t this a short-term concern? I thought that requirement was going away.

For this reason, this proposal prefers using no-label calls for types (otherwise they would have been ofType) and labeled calls for values:

print(sizeof(Int)) // works
print(sizeof(Int.self)) // works

func withoutLabel<T>(thetype: T.Type) -> Int { return sizeof(T) }
func withLabel<T>(label label: T.Type) -> Int { return sizeof(T) }

// Works
print(withoutLabel(Int))

// Works
print(withLabel(label: Int.self))

// Does not work
// error: cannot create a single-element tuple with an element label
// print(withLabel(label: Int))

So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(_: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(of: T) -> Int
-- E

That proposal was returned for revision; as far as user ergonomics in Swift
3, .self is going to be a consideration. Best to find a solution that reads
nicely regardless of the situation with .self removal.

···

On Thu, Jun 2, 2016 at 9:57 AM Matthew Johnson <matthew@anandabits.com> wrote:

On Jun 2, 2016, at 9:43 AM, Erica Sadun <erica@ericasadun.com> wrote:

Supporting Dave A, type-based calls are much more likely to be used than
instance calls, unlike with dynamicType/type(of:)

Termstdlib searchgist searchGoogle site:github +swift
sizeof 157 169 4880
sizeofValue 4 34 584
alignof 44 11 334
alignofValue 5 5 154
strideof 347 19 347
strideofValue 4 5 163
Type-based calls like sizeof() are poor candidates for parameter labels.
While it's acceptable to write sizeof(Int), but one must write size(of:
Int.self) (with the trailing self) when the function has a label.

Isn’t this a short-term concern? I thought that requirement was going
away.

For this reason, this proposal prefers using no-label calls for types
(otherwise they would have been ofType) and labeled calls for values:

print(sizeof(Int)) // worksprint(sizeof(Int.self)) // works
func withoutLabel<T>(thetype: T.Type) -> Int { return sizeof(T) }func withLabel<T>(label label: T.Type) -> Int { return sizeof(T) }

// Worksprint(withoutLabel(Int))
// Worksprint(withLabel(label: Int.self))
// Does not work// error: cannot create a single-element tuple with an element label// print(withLabel(label: Int))

So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size<T>(_: T.Type) -> Int

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size<T>(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory. The result is always positive.
public func spacing<T>(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment<T>(of: T) -> Int

-- E