[Pitch] Permit self in type-inferred property initializers


(Marc Prud'hommeaux) #1

I propose that it should be possible to declare type-inferred properties that derive from the required properties of a class or struct.

struct SignedSequences<S: SequenceType where S.Generator.Element : SignedIntegerType> {
    let seq: S
    let absoluteEvens: self.seq.lazy.filter({ x in x % 2 == 0 }).map({ x in abs(x) })
    let positiveOdds: self.seq.lazy.filter({ x in x > 0 }).filter({ x in x % 2 == 1 })
    let brutePrimes: self.positiveOdds.lazy.filter({ $0 >= 2 }).filter({ s in (2..<s).filter({ x in s % x == 0 }).isEmpty })

    init(sequence: S) {
        self.seq = sequence
    }
}

Currently, to accomplish this, you need to explicitly declare the types for each of the derived properties, which can be tedious, and which requires the separation of the declaration from the invariant logic.

struct SignedSequences<S: SequenceType where S.Generator.Element : SignedIntegerType> {
    let seq: S
    let absoluteEvens: LazyMapSequence<LazyFilterSequence<S>, S.Generator.Element>
    let positiveOdds: LazyFilterSequence<LazyFilterSequence<S>>
    let brutePrimes: LazyFilterSequence<LazyFilterSequence<LazyFilterSequence<LazyFilterSequence<S>>>>

    init(sequence: S) {
        self.seq = sequence
        self.absoluteEvens = seq.lazy.filter({ x in x % 2 == 0 }).map({ x in abs(x) })
        self.positiveOdds = seq.lazy.filter({ x in x > 0 }).filter({ x in x % 2 == 1 })
        self.brutePrimes = positiveOdds.lazy.filter({ $0 >= 2 }).filter({ s in (2..<s).filter({ x in s % x == 0 }).isEmpty })
    }
}

This would just be a compiler enhancement, since the generated SIL would be identical in the two examples.

What do people think?