<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Unless I'm missing something, this should give you the results you are looking for:</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">class</span> MyClass {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> foreignKey: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int64</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""> didSet<span style="color: rgb(0, 0, 0);" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""> <span style="color: rgb(187, 44, 162);" class="">self</span><span style="color: rgb(0, 0, 0);" class="">.</span>foreignObject<span style="color: rgb(0, 0, 0);" class=""> = </span><span style="color: rgb(187, 44, 162);" class="">nil</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">lazy</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> foreignObject: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">ForeignClass</span>! = {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""> <span style="color: rgb(187, 44, 162);" class="">return</span><span style="color: rgb(0, 0, 0);" class=""> </span>Database<span style="color: rgb(0, 0, 0);" class="">.</span><span style="color: rgb(49, 89, 93);" class="">expensiveSelect</span><span style="color: rgb(0, 0, 0);" class="">(</span><span style="color: rgb(187, 44, 162);" class="">self</span><span style="color: rgb(0, 0, 0);" class="">.</span>foreignKey<span style="color: rgb(0, 0, 0);" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div class=""><br class=""></div><div class="">Using an Implicitly Unwrapped Optional instead of an Optional allows you to set <span style="font-family: Menlo; font-size: 11px;" class="">foreignObject</span> to <span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">nil</span> which will give you the same behavior you use in Objective-C (a.k.a. null_resettable).</div><div class=""><br class=""></div><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""></pre></div><blockquote type="cite" class=""><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">To me this actually feels more like something that might fit better as an additional type of optional, rather than a language feature.
Setting this optional to nil could work normally, and any attempt to access the value when nil would cause the reload to occur. The initialization semantics might be a tad ugly though.
var myLazyOpt = ReloadingOptional<ForeignClass>({
return Database.expensiveSelect(self.foreignKey)
})
You could probably implement something like this yourself, though I'm not sure how elegant that would be without full language support.
Thanks for your time,
Cole Kurkowski
><i class=""> On Dec 4, 2015, at 07:40, David Hart <<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">david at hartbit.com</a>> wrote:
</i>><i class="">
</i>><i class=""> In Objective-C, I often used the lazy initialization pattern to implement a cache for expensive operations. For exemple, here is an often used scenario in a project where objects behind foreign keys in a database ORM are only fetched when necessary:
</i>><i class="">
</i>><i class=""> @interface MyClass : NSObject
</i>><i class="">
</i>><i class=""> @property (nonatomic) ForeignClass* foreignObject;
</i>><i class=""> @property (nonatomic) int64_t foreignKey;
</i>><i class="">
</i>><i class=""> @end
</i>><i class="">
</i>><i class=""> @implementation MyClass
</i>><i class="">
</i>><i class=""> - (void)setForeignKey:(int64_t)foreignKey {
</i>><i class=""> _foreignKey = foreignKey;
</i>><i class=""> _foreignObject = nil;
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> - (ForeignClass*)foreignObject {
</i>><i class=""> if (!_foreignObject) {
</i>><i class=""> _foreignObject = [Database expensiveSelect:_foreignKey];
</i>><i class=""> }
</i>><i class=""> return _foreignObject;
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> @end
</i>><i class="">
</i>><i class=""> Unfortunately, the lazy keyword in Swift, which was supposed to make the lazy initialization pattern more concsive does not work in this case:
</i>><i class="">
</i>><i class=""> class MyClass {
</i>><i class=""> var foreignKey: Int64 {
</i>><i class=""> didSet {
</i>><i class=""> self.foreignObject = nil
</i>><i class=""> }
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> lazy var foreignObject: ForeignClass? = {
</i>><i class=""> return Database.expensiveSelect(self.foreignKey)
</i>><i class=""> }()
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> I'm forced to rewrite it this way:
</i>><i class="">
</i>><i class=""> class MyClass {
</i>><i class=""> var foreignKey: Int64 {
</i>><i class=""> didSet {
</i>><i class=""> self.foreignObject = nil
</i>><i class=""> }
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> private var _foreignObject: ForeignClass? = nil
</i>><i class=""> var foreignObject: ForeignClass? {
</i>><i class=""> if _foreignObject == nil {
</i>><i class=""> _foreignObject = Database.expensiveSelect(self.foreignKey)
</i>><i class=""> }
</i>><i class=""> return _foreignObject
</i>><i class=""> }
</i>><i class=""> }
</i>><i class="">
</i>><i class=""> When thinking about it, I came to the conclusion that the use cases of lazy seem very narrow compared to how useful the lazy initialization pattern was in Objective-C.
</i>><i class=""> I want your opinion on three alternatives:
</i>><i class="">
</i>><i class=""> 1- Do nothing, and use the slightly uglier Swift example when using a cache.
</i>><i class=""> 2- Modify lazy semantics to re-calculates when nil (I think this is the worst solution).
</i>><i class=""> 3- Add a cache modifier that re-calcualtes when nil.
</i>><i class=""> _______________________________________________
</i>><i class=""> swift-evolution mailing list
</i>><i class=""> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">swift-evolution at swift.org</a>
</i>><i class=""> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a>
</i></pre></div></blockquote><div class=""><br class=""></div></body></html>