I think we need more to our type calculus


(Daryle Walker) #1

I’ve been trying to get the maximum of a list of counts. I started by using “myCollection.map { $0.myCountProperty }.reduce(0, max)”. Then I thought I should really use the value closest to negative infinity as the base. The problem is how to get that value. The current hard-coded “0” works because the count type ultimately aliases “Int”, but shouldn’t have to count on that. I put in “MyCountType.min”, where “MyCountType” is hard coded from the docs of “myCountProperty”, but I shouldn’t have to do that either.

There is a “type(of:)” global function, which I did use. But not only did I have to make up an expression to go in there, its return value, some sort of meta-type stuff I don’t understand, can’t be used on the right side of a “typealias” construct. I ultimately used “let lowestCount = type(of: anElement.myCountProperty).min” to get what I needed.

Some queries/requests:

1. Is the expression within “type(of:)” evaluated?
2. I think we need the equivalent of "std::declval” from C++. Especially if the answer to (1) is yes.
3. Why isn’t the return type(?) of “type(of:)” compile-time enough to be used as a type-alias?
4. Should we add something like the C++ type-traits collection of generic structures to give use type information as type-aliases or type-level instances?

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


(Slava Pestov) #2

I’ve been trying to get the maximum of a list of counts. I started by using “myCollection.map { $0.myCountProperty }.reduce(0, max)”. Then I thought I should really use the value closest to negative infinity as the base. The problem is how to get that value. The current hard-coded “0” works because the count type ultimately aliases “Int”, but shouldn’t have to count on that. I put in “MyCountType.min”, where “MyCountType” is hard coded from the docs of “myCountProperty”, but I shouldn’t have to do that either.

There is a “type(of:)” global function, which I did use. But not only did I have to make up an expression to go in there, its return value, some sort of meta-type stuff I don’t understand, can’t be used on the right side of a “typealias” construct. I ultimately used “let lowestCount = type(of: anElement.myCountProperty).min” to get what I needed.

Some queries/requests:

1. Is the expression within “type(of:)” evaluated?

Yes. Eg,

class Base {}
class Derived : Base {}

func foo() -> Base { return Derived() }

type(of: foo()) // this is Derived.self, not Base.self

2. I think we need the equivalent of "std::declval” from C++. Especially if the answer to (1) is yes.
3. Why isn’t the return type(?) of “type(of:)” compile-time enough to be used as a type-alias?

type(of:) is not a real function because it’s return type depends on the input type in a funny way. If the input type T is an existential, then type(of:) returns an existential metatype; otherwise, it returns a concrete metatype. So it’s almost as if the signature is (T) -> (T.Type), but not quite.

Slava

···

On Feb 8, 2017, at 12:09 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

4. Should we add something like the C++ type-traits collection of generic structures to give use type information as type-aliases or type-level instances?


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(Xiaodi Wu) #3

type(of:) is the Swift 3 spelling of what was known in Swift 2 as
dynamicType.

···

On Wed, Feb 8, 2017 at 14:09 Daryle Walker via swift-evolution < swift-evolution@swift.org> wrote:

I’ve been trying to get the maximum of a list of counts. I started by
using “myCollection.map { $0.myCountProperty }.reduce(0, max)”. Then I
thought I should really use the value closest to negative infinity as the
base. The problem is how to get that value. The current hard-coded “0”
works because the count type ultimately aliases “Int”, but shouldn’t have
to count on that. I put in “MyCountType.min”, where “MyCountType” is hard
coded from the docs of “myCountProperty”, but I shouldn’t have to do that
either.

There is a “type(of:)” global function, which I did use. But not only did
I have to make up an expression to go in there, its return value, some sort
of meta-type stuff I don’t understand, can’t be used on the right side of a
“typealias” construct. I ultimately used “let lowestCount = type(of:
anElement.myCountProperty).min” to get what I needed.

Some queries/requests:

1. Is the expression within “type(of:)” evaluated?
2. I think we need the equivalent of "std::declval” from C++. Especially
if the answer to (1) is yes.
3. Why isn’t the return type(?) of “type(of:)” compile-time enough to be
used as a type-alias?
4. Should we add something like the C++ type-traits collection of generic
structures to give use type information as type-aliases or type-level
instances?


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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


(Joe Groff) #4

type(of:) does evaluate its argument, since for things like classes you need to know the value you're asking of a type for. However, you can avoid hardcoding a type at all in this case by using contextual lookup:

myCollection.map { $0.myCountProperty }.reduce(.min, max)

`.foo` will look up static members inside the contextual type of the expression.

-Joe

···

On Feb 8, 2017, at 12:09 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

I’ve been trying to get the maximum of a list of counts. I started by using “myCollection.map { $0.myCountProperty }.reduce(0, max)”. Then I thought I should really use the value closest to negative infinity as the base. The problem is how to get that value. The current hard-coded “0” works because the count type ultimately aliases “Int”, but shouldn’t have to count on that. I put in “MyCountType.min”, where “MyCountType” is hard coded from the docs of “myCountProperty”, but I shouldn’t have to do that either.

There is a “type(of:)” global function, which I did use. But not only did I have to make up an expression to go in there, its return value, some sort of meta-type stuff I don’t understand, can’t be used on the right side of a “typealias” construct. I ultimately used “let lowestCount = type(of: anElement.myCountProperty).min” to get what I needed.