[swift-evolution] Idea for Restricted "Pseudo-Dynamic" Typing
davesweeris at mac.com
davesweeris at mac.com
Tue Jan 12 17:40:09 CST 2016
(Disclaimer: This might actually just be a slightly disguised subset of the “allow non-type generic parameters” idea, depending on whether that includes stuff like this:
> var foo = 2
> var bar = Vector<foo>()
or if it only addresses this:
> var bar = Vector<2>()
)
Building on “pure" from: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003684.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003684.html>
Consider this function:
> func @pure foo<T,U,V>(_: T.Type, _: U.Type) -> V.Type {…}
Since @pure prevents foo from accessing global/static variables, since it can only call other @pure functions, and since its only parameters are themselves other types, then the return type of V must solely depend on the *types* T and U (and what can be gotten from T & U using @pure functions). While this is not the same thing as “known at compile time”, it does (I think) guarantee that V can be deduced only using what is known about T and U *at compile time*. If the return value of such a function could used as a “proper” type (i.e., it could be used like “var bar: foo(Int.self, String.self)”, for instance), it wouldn’t so much remove the “types must be known at compile time” restriction, as it would give the programmer a powerful way to tell the compiler *how* to figure out what the type is.
The use case I’m thinking of is admittedly pretty narrow… I personally want this feature to help with a work-around I’m using for Swift not having non-type generic parameters:
> protocol IVAT { //Integer Value As Type
> static var integerValue:Int {get}
> }
> struct _0 : IVAT { static let integerValue = 0 }
> struct _1 : IVAT { static let integerValue = 1 }
> struct _2 : IVAT { static let integerValue = 2 }
> //…etc
>
> struct Matrix<M:IVAT, N:IVAT> {
> private var backing = [[Double]](count: M.integerValue, repeatedValue: [Double](count: N.integerValue, repeatedValue: 0.0))
> subscript(row: Int, col: Int) -> Double {}
> }
If we allowed pure functions to return “usable” types, then Matrices could be joined like this:
> func @pure + <T: IVAT, U: IVAT, V: IVAT> (_: T.Type, _: U.Type) -> V.Type {
> switch (T, U) {
> case (_0, _0): return _0.self
> case (_0, _1): return _1.self
> …
> default: return _0.self
> }
> // joins two matrices… join([[1,2],[3,4]], [[5],[6]]) would return [[1,2,5],[3,4,6]]
> func join <M:IVAT, N1:IVAT, N2:IVAT> (lhs: Matrix<M,N1>, rhs: Matrix<M, N2>) -> Matrix<M, N1.self + N2.self> {…}
Again, I realize the use case I’ve presented is pretty narrow (and one that’ll hopefully become a moot point later), but it seems like this would be a *very* expressive way to expand the power of generic types.
Anyway… Yay? Nay? Implementation-wise, my first thought is to embed the REPL in the generic specialization system then use the function in question as its input to extend the generic specialization system, but I don’t know if that’s the right place to handle it, let alone if that’s a feasible idea.
-Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160112/7a1ab1fd/attachment.html>
More information about the swift-evolution
mailing list