Why are open and close parens needed "()" on line 7, please? (Newbie Question) (Closures)

Apologies for the newbie question.

I really do try and figure things out for myself before coming here.

Why are open and close parens "()" needed after the close curly brace "}" on line 7, please?

The error message mentions a "function" but I don't know which function it is referring to - (Which function is it referring to?) - alls I see is a structure and a variable.

... and ... Why is there a "return" keyword in the middle of this variable in the middle of a structure.

As a bit of back story, I found this code in a bunch of instructor provided code that I was attempting to read and understand.

I do know that every character is important in code, and I came across these open and close parens and was wondering what syntactic service they were providing here.

(File: "Processing Data.playground" as part of the "teacher" zip file as part of "Develop in Swift Explorations.")

I tired to isolate the code as much as I could to pare down the issue, and I renamed "ShowsBuilder" to "ShowsBuilder2" to get rid of a redeclaration error.

Screen shots for reference :

...


...


Am I dealing with a "closure"? (This is my best guess at the moment.)

I looked up closures, but wasn't able to pattern match against them with this issue.

Thank you for your time.

:rainbow::pray::rainbow:

The block of code you are creating to initialize this property is indeed a closure. If you don't call the closure you would be trying to assign something that is of type () -> [String] (your closure) to a property that's supposed to be a [String]. The compiler suggests you call the closure instead which means that you assign the return value of the closure to your property.

I haven't come across a formal name for initializing properties through closures yet, but that's what you're doing here.

I have an article on this topic on my website right here

2 Likes

Addressing the terminology here…

What we commonly call "functions" and "closures" are both just functions to the compiler. The only important difference is that a function declared via the func … { … } syntax is a named function, and a closure is an unnamed function.

Let's say you have a named function in your struct:

struct ShowsBuilder2 {
    static func showsInitialValue() -> [String] {
        return [
            "100 Stories About OneNight",
            "Ocean Express"
        ]
    }
    static var showsLiteral: [String] = showsInitialValue()
}

If you think of the syntax static func showInitialValue() -> [String] as the "name" of the function and then set that aside for a moment, you'll see that what's left is the part in the braces, which is the same as the closure that you originally wrote.

This is not an accident. Using a named function is really the same as using a closure, apart from a bit of ceremony in writing the name of the function.

That's also why you needed () after the closure. If you tried to write this:

    static var showsLiteral: [String] = showsInitialValue // <- no parens

you'd get the same compiler error, but in this case your intuition about using functions would make it clear why you need the parens β€” you want to apply the function here, to determine its returned value, not just mention the function.

Incidentally, I think it's a kind of bug in the compiler (in the wording of the error message) to use "function" indiscriminately for named and unnamed functions, since we normally use the informal "function"/"closure" terms instead. Might actually be worth a bug report.

Understood, and nobody here minds that you ask. Your questions are on-topic for this forum, so it's right that you come here for information like this.

1 Like

It will save you a lot of time, and make it easier to get help, if you use screenshots instead of taking a photo of a screen. Command-shift-4, and then dragging out a rectangle, is one of my favorites.

2 Likes

Thank you, @donny_wals .

Your page and your site looks awesome and super helpful.

The sample code on your page pattern-matched for my issue better than anything I found on:

https://docs.swift.org/swift-book/LanguageGuide/Closures.html

If you made Swift Programming Tutorial videos, I would surely watch them.

:rainbow::pray::rainbow:

P.S. How would you compare and contrast a "Swift closure" with a "Scheme lambda" which I learned about long ago?

Thank you, @QuinceyMorris, for your clear explanation!

You should write text books!

:rainbow::pray::rainbow:

Thank you, @anon9791410 !

:rainbow::pray::rainbow:

1 Like

Follow-up question:

So, I did a bit of thinking and "developed" some code:

struct ShowsBuilder3 {
    static var showsLiteral: [String] = [
            "100 Stories About One Night",
            "Ocean Express"
        ]
}

And when I look at the value of

ShowsBuilder3.showsLiteral

It looks exactly the same as

ShowsBuilder2.showsLiteral

From above. Here is ShowsBuilder2 again, for reference:

struct ShowsBuilder2 {
    static var showsLiteral: [String] = {
        return [
            "100 Stories About One Night",
            "Ocean Express"
        ]
    }()
}

Now, please note that this code was all behind-the-scenes code written to make the exercise work. None of this was part of the "exercise" of this lesson. It probably wasn't meant to be read at all.

My question: Isn't the closure in this case totally superfluous?

Why did they make a closure with a single line of code - that just returns an array of string literals?

It just a block of code that returns an array of strings.

Why not just feed the array of strings directly into the assignment operator? ("=") (Like I did in ShowsBuilder3.)

No need for a closure at all in this case, right?

Thank you for your time.

:rainbow::pray::rainbow:

No, I don't think there's any difference in this case.

1 Like