chkn / Xamarin.SwiftUI

.NET bindings for SwiftUI
MIT License
98 stars 7 forks source link

Implement F# API for ViewBuilders #37

Closed chkn closed 4 years ago

chkn commented 4 years ago

Fixes #24

This enables a nice syntax for ViewBuilders in F# using computation expressions.

Example of the syntax:

open type SwiftUI.Views

let button = Button(fun () -> printfn "clicked") {
        Text("1")
        Text("2")
        Text("3")
        Text("4")
        Text("5")
        Text("6")
        Text("7")
        Text("8")
        Text("9")
        Text("10")
}

When compiled with optimization and then decompiled by ILSpy:

Button<TupleView<(Text, Text, Text, Text, Text, Text, Text, Text, Text, Text)>> button2 = new Button<TupleView<(Text, Text, Text, Text, Text, Text, Text, Text, Text, Text)>>(new $Views.button@16(this).Invoke, null);
Text item = Views.Text("1");
Text item2 = Views.Text("2");
Text item3 = Views.Text("3");
Text item4 = Views.Text("4");
Text item5 = Views.Text("5");
Text item6 = Views.Text("6");
Text item7 = Views.Text("7");
Text item8 = Views.Text("8");
Text item9 = Views.Text("9");
Text item10 = Views.Text("10");
// .. snip some unused locals ..
button2.Label = (TupleView<(Text, Text, Text, Text, Text, Text, Text, Text, Text, Text)>)(object)new TupleView<(Text, Text, Text, Text, Text, Text, Text, Text, Text, Text)>((item, item2, item3, item4, item5, item6, item7, item8, item9, item10));

See comments here for a description of the technique: https://github.com/chkn/Xamarin.SwiftUI/pull/37/files#diff-46c3c5ce9e0fa555d9f1c9eb0b89c5e4d8e320a5d50e4c9ed9450a196330ae99R1

TL;DR the CE is completely inlined and no reference to the new F#-specific assembly is emitted in release builds.

dsyme commented 4 years ago

Wow, great work!!