Is "lazy let" on the schedule anywhere?

It sure would be nice if the compiler supported lazy lets for structs. Any
idea when or if this will be supported?

Seems like a nice performance win, lazy var is a pain because you can't
access arguments passed into a function without mutation complaints.

Thanks, Ed

6 Likes

If you’re not passing the value type as an inout, how will the ‘lazy let’ property write back the new value?

Slava

···

On Jun 26, 2017, at 3:32 PM, Edward Connell via swift-users <swift-users@swift.org> wrote:

It sure would be nice if the compiler supported lazy lets for structs. Any idea when or if this will be supported?

Seems like a nice performance win, lazy var is a pain because you can't access arguments passed into a function without mutation complaints.

Thanks, Ed
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

I myself highly want lazy constants (I’m tired of writing something like file private private(set) lazy var propertyName: ReferenceType just to hide the setter from the rest of the codebase), but I don’t think this will ever happen in Swift, at least not as an improvement for the lazy keyword itself. Joe Groff had a really awesome proposal last year, which is currently in a deferred state but will be resurrected in the future.

It’s simply is a prioritization question, when this will happen.

That said, I’d expect some kind of readOnlyLazy property behavior that will match the mentioned lazy let.

···

--
Adrian Zubarev
Sent with Airmail

Am 26. Juni 2017 um 21:32:35, Edward Connell via swift-users (swift-users@swift.org) schrieb:

It sure would be nice if the compiler supported lazy lets for structs. Any idea when or if this will be supported?

Seems like a nice performance win, lazy var is a pain because you can't access arguments passed into a function without mutation complaints.

Thanks, Ed
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

1 Like

+1 for lazy lets. It would be very practical and efficient to be able to delay expensive initialization of a constant but then prevent its further mutation. private(set) does not facilitate this pattern internal to the defining type.

6 Likes

I think since Property Wrapper conversation we would like to move away from the lazy keyword, even though it's not fully possible, but we can at least create our own and easy to use LazyImmutable property wrapper now.

Isn't static let already sufficient? This should imply lazy as well.

You still can't use lazy for local things, or property wrappers. Although @anthonylatsis has a WIP PR for local lazy, which is a prereq of local property wrappers. Local lazy vars by AnthonyLatsis · Pull Request #27600 · apple/swift · GitHub

Well sure, but local property wrappers will eventually be implemented, that's a matter of time only. :slight_smile: lazy let wasn't really blessed yet as far as I remember.

Can swift add lazy let?
I want really to stop accessing the property.
Why can’t swift have this feature?

Maybe we should try for non-mutating wrapper, i.e., @Lazy let?

1 Like

A property wrapper would solve the problem at runtime sure but it would be great to have this feature enforced at compile time. In fact, I have a feeling that the async let foo is partly like a lazy let bar as the value is not accessible until we call await foo. Either that or I‘m completely imagine things.

cc @Douglas_Gregor and @John_McCall

5 Likes

how does @lazy let work?

@propertyWrapper
struct Lazy<T> {
    private var val: (() -> T)?
    private var storedVal: T!
    var wrappedValue: T {
        mutating get {
            if let closure = val {
                storedVal = closure()
                val = nil
            }
            return storedVal
        }
    }
    
    init(wrappedValue closure: @autoclosure @escaping () -> T) {
        val = closure
    }
}

i tried to write my own. but i got error:

class A {
    let x = 20
    
    @Lazy
    var val: Int = { self.x }() // Cannot find 'self' in scope
}

if i can't use self, what is the point in using lazy?

Has there been any more consideration for this? I realize this may not be straightforward to implement, and would need to be implemented more akin to how CoW masks the underlying operations.

Back in 2016 @anandabits Made some excellent points in this proposal :

I think a similar case could be made for lazy let, and more generally distinguishing the programmer model of immutability from the optimizer model which may need to rely on immutability of the underlying bits themselves. This distinction would allow the programmer model to be modified to allow for lazy let.

I think it is worth considering (after Swift 3) refining the programmer model to mean the value is always initialized before reading and is never written to after initialization. This allows for implementation flexibility while preserving the semantics visible to users of the type. In that respect it I believe it is similar in spirit to allowing internal references and CoW in the implementation of value semantic types.

I know I would use lazy lets all of the time if they were available. The programmer shouldn't have to know or care whether the compiler requires immutability in its implementation. By marking lazy properties that are never changed as var, it leaks the mutability to callers of the struct.

6 Likes