Metaprogramming in Swift
Asked Answered
P

2

10

Coming from C++, I'm trying to do some metaprogramming in Swift. For example, I'd like to implement a metafunction that adds two numbers. I've tried something like this:

protocol IntWrapper {
    class var value: Int { get }
}

struct A: IntWrapper {
    static let value = 5
}

struct B: IntWrapper {
    static let value = 7
}

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper {
    static let value = T.value + U.value
}

This, however, doesn't work: Xcode complains that T.Type doesn't have a member value (or just crashes, sometimes.)

How can implement such functionality?

Partlow answered 14/11, 2014 at 21:46 Comment(1)
Hey sir´s .... Almost one year later... Do we have any news about Swift and Metaprogramming?Renfro
D
8

static stored properties are not (currently) supported on generic objects. When I put your code in a playground, I actually get this error:

Playground execution failed: <EXPR>:23:5: error: static variables not yet supported in generic types
    static let value = T.value + U.value
    ^~~~~~

You can get around that by using a computed property instead (which may have been what you wanted in the first place anyway):

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper {
    static var value: Int {
        return T.value + U.value
    }
}

Note: Since it's a computed property, you need to declare value with var and not let.

With those changes, println(Sum<A, B>.value) prints 12 like you'd expect.

Dicks answered 14/11, 2014 at 21:57 Comment(1)
To be honest, I'm not really sure what I wanted (in the language semantics sense). The final goal is that once all optimizations are enabled, Sum<A, B>.value will be reduced to a constant in the resulting binary code.Partlow
L
0

It seems to me that you need to match your definitions and implement the protocol differently. (I'm not a swift developer, but I've been learning as I help people on stackoverflow.)

protocol IntWrapper {
  static var value : Int { get }
}
struct A: IntWrapper {
  static var value : Int { get { 5 } }
}

You were calling for a class var, but then you defined a static let. Subtle difference, but I think it matters here.

Limitless answered 14/11, 2014 at 21:55 Comment(1)
Protocols cannot have static properties, the compiler throws an error message if you try.Partlow

© 2022 - 2024 — McMap. All rights reserved.