Include a function for sugaring IIFEs

Like many languages, Swift supports IIFEs (Immediately Invoked Function Expressions), and uses the same grammar (trailing, empty parens):

let invader: SpaceInvader = {
    let invader = SpaceInvader()
    invaders.append(invader)
    return invader
}()

This grammar is weird. The trailing parens are easy overlooked, and when they are seen, they tend to be seen after the body of the closure has been read, which is a problem, as the parens completely change the context of the closure's body.

Ideally, the grammar would somehow indicate that the closure is immediately invoked before the body of the closure.

I raised this issue (in this forum) when I began learning Swift, and was advised to use something like this:

func iife<T>(_ lambda: () -> T) -> T { lambda() }

This allows you to lead the closure with iife, and omit the trailing parens:

let invader: SpaceInvader = iife {
    let invader = SpaceInvader()
    invaders.append(invader)
    return invader
}

I've used iife ever since, and find it really useful.

I also experimented with using a prefix operator (instead of a function), but it looked as weird as the trailing parens (with any spelling I could think of), so I abandoned that idea:

let invader: SpaceInvader = --{
    let invader = SpaceInvader()
    invaders.append(invader)
    return invader
}

It's just not Swift.

Ultimately, the advice solved the problem (very neatly), and I was still new to Swift back then, so I just left it there. However, I really think Swift should include something like iife out-the-box, then promote it (in official docs etc) as the modern convention for IIFEs.

Before bike-shedding a spelling etc, we obviously need to establish whether or not the community agree that this would be better (and worth the effort).

What do you think? This...

let invader: SpaceInvader = {
    let invader = SpaceInvader()
    invaders.append(invader)
    return invader
}()

...or (something like) this...

let invader: SpaceInvader = iife {
    let invader = SpaceInvader()
    invaders.append(invader)
    return invader
}

...??

2 Likes

This has been recently pitched as do expressions:

9 Likes

Thanks, @xwu. That's awesome.

I actually proposed using do in my original post, but that wasn't popular at the time, so I never mentioned it this time.