DSL, assign variables in closures

I'd like to create DSLs where you can use closures to assign structs/classes variables

struct X {
   var a = 0
}

and then simply

let x = X {
   a = 5
}

As far as I understood, right now I only have the following possibilities:

let x = X().a(5)

or

let x = X{
   $0.a = 5
}

Am I right? If not, how can I achieve that?

If yes, are there any other available routes?

Ps: relevant thread

struct X {
    public var a
    public var b
    public var c

    init(a: Int = 0, b: Int = 0, c: Int = 0)
    {
        self.a = a
        self.b = b
        self.c = c
    }
}

let x = X(a: 5)
let y = X(a:5, b:3)
let z = X(c:3, a: -1, b: 0)

or something similar. X is a struct, not a closure. It has to be initialized.

The thing is that I have tons of structs, whose most of fields I don't need to assign/change

Eg:

typedef struct VkApplicationInfo {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pApplicationName;
    uint32_t           applicationVersion;
    const char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
} VkApplicationInfo;

I'd like to

let appInfo = vk.ApplicationInfo {
    applicationName = "Hello Triangle"
    applicationVersion 1
}

That'd be defaulting them to zero (depending on the system/compiler). As of SE-0242, it should be relatively easy to do for Swift struct though I don't know how it'd work with C struct.

For your example, it looks like you want to copy vk into a constant appInfo translating arbitrary fields during the copy. Is this the case? If it can be done, I think it's going to need to use reflection (the Mirror protocols) and a lot of tricky coding. I don't think it's an "out-of-the-box" thing. Or, a lot of specialized init methods.

Also, you are showing a C-struct, not a Swift struct. Assuming you named your Swift struct equivalent the same, you could do:

var appInfo = vk.ApplicationInfo  // instance vk has a field 'ApplicationInfo'
appInfo.applicationName = "Hello Triangle"
appInfo.applicationVersion = 1

The downside is that ```appInfo`` is no longer a non-mutable constant.

I ended up using an init extension

In Swift 5.1 the auto-generated init plays well with properties with default values

Yeah, it looks so indeed, thanks