Roslyn: Proposal: language support for lazy initialization and modification

Created on 2 Dec 2016  路  7Comments  路  Source: dotnet/roslyn

With lazy initialization, creation of objects can be delayed until these object are really needed, potentially saving performance and memory.

Example:

Class C1
    Public Delayed Property Dict As New Dictionary(Of Integer, String) ' delay create until first read access
    Public Delayed Property Dict2 As Dictionary(Of Integer, Integer)

    Public Sub Init()
        Dim d As New Dictionary(Of Integer, Integer)
        d.Add(1, 1)
        Dict2 = d
        d.Add(1, 2)
        Dict.Add(1, "1")
    End Sub
End Class

Properties defined with Delayed keyword, will have implemented call to initializers before returning value. Compiler must be smart to extract right piece of code that will be injected into initializer. Method Init execute really only last line of code, while first four are used to create initializer for Dict2 property. If such code cannot be extracted, then property is modified immediately.
This feature should also support multiple initializations (operator =) and modification (operators +=, -=, and others). Initialization always clear list of initializers, and insert new initializer. Modification add new initializer to the list of initializers.

Area-Language Design Discussion

Most helpful comment

All 7 comments

@dsaf
These proposals rely only on first read. My proposal is richer as it delays of evaluation of multiple writes, and automatically extract code responsible for evaluation.

I don't understand why would something like this make sense.

VB (and C#) is an imperative language: when I create an object, I expect an object to be created now (including any potential side-effects of its constructor), not at some point in the future.

This would either introduce magic that would make code hard to understand, or it would require some sort of tracking which operations are side-effect-free (and so can be safely delayed). Side-effect tracking would require careful (and likely complicated) design, if it would be possible at all, and I don't think that would be worth it just for this proposal.

If you really want this, I think writing a library makes the most sense. It would require you to explicitly decide which operations can be delayed (though I'm not sure that's a bad thing), e.g.:

```vb.net
Class C1
Public Property Dict2 As MyLazy(Of Dictionary(Of Integer, Integer))

Public Sub Init()
    Dict2.Init(
        Sub(ByRef value)
            Dim d As New Dictionary(Of Integer, Integer)
            d.Add(1, 1)
            value = d
            d.Add(1, 2)
        End Sub)
End Sub

End Class
```

Lazy<T>?

@svick

VB (and C#) is an imperative language

Languages VB and C# are not only imperative but also declarative. Features like Inheritance, polymorphism, LINQ, async and many other rely on enormous amount of 'magical' code generated by compiler and CLR. Thanks to this magic, you can stay at high level of abstraction.

it would require some sort of tracking

Editor may highlight code that will be used to initializer, or there may be introduced additional keywords mo more explicitly state which code will be used to initializer.

@Joe4evr
Lazy<T>, @svick example and most proposals are limited only to first initlialization.

@vbcodec

Features like Inheritance, polymorphism, LINQ, async and many other rely on enormous amount of 'magical' code generated by compiler and CLR.

None of these change how a sequence of statements execute, they build on top of that, usually using new and very explicit syntax.

@svick example [is] limited only to first initlialization.

Not necessarily. If you call Init, multiple times, it could store all the delegates you gave to it and execute them all once the value is actually required.

But I think that multiple initialization is not a very common problem. It's probably not worth adding a new clear language feature for it and IMO is definitely not worth adding the very confusing and likely very complicated feature that's proposed here.

I'd absolutely hate for the compiler to bless one particular mechanism, like Lazy<> or ??= or CAS. They each have their strengths for different applications. It would be terribly imbalanced for the language itself to decide that one way of doing lazy loading was the idiomatic way.

Was this page helpful?
0 / 5 - 0 ratings