I like to suggest relaxing ordering restriction of nested functions. In short, 
just allow nested functions to be defined below its call site. ("Use of local 
variable ‘b’ before its declaration.” error)

Here’s more explanation.

In Swift, we can define nested functions.

    func a() {
        func b() {
        }
        func c() {
        }
    }

It’s quiet flexible, so we actually can call functions regardless order of 
their declaration.

    func a() {
        func b() {
            c() // Calling `c` which is defined below is allowed.
        }
        func c() {
        }
    }

This is possible because `c` does not have any order-sensitive dependency.

But unfortunately, calling `b` before its declaration is not allowed. Although 
it has no dependency.

    func a() {
        b() // Use of local variable ‘b’ before its declaration.
        func b() {
            c()
        }
        func c() {
        }
    }

It doesn’t make sense to me that `b` is disallowed while `c` is allowed. It’d 
be nice if this restriction goes away. Because that allows me to do some code 
“outlining” layout. Please consider this sample.
    
    func work1() {
        // Illustrates big outlines first...
        bigStep1()
        bigStep2()

        func bigStep1() {
            sharedSmallStep1()
            sharedSmallStep2()
        }
        func bigStep2() {
            sharedSmallStep2()
            sharedSmallStep3()
        }

        // Describe details later...
        func sharedSmallStep1() {
            // Complex and long code...
        }
        func sharedSmallStep2() {
            // Complex and long code...
        }
        func sharedSmallStep3() {
            // Complex and long code...
        }
    }

Of course you can do this in reverse order, but in that case, we have to read 
them backward — from bottom to top. It’s easier to read if larger outline if on 
top.

I can do this with (1) un-nested free functions, or (2) enum/class/struct 
member functions. But this is still better because nested functions provides 
lexical scopes which can reduce amount of code greatly.

    func a(_ v1: Int) { // `v1` is available to all nested scopes.
        print(v1)
        b(333)
        func b(_ v2: Int) { // `v2` is available to all nested scopes.
            print(v1 + v2)
            c(555)
            func c(_ v3: Int) { // `v3` is available to all nested scopes.
                print(v1 + v2 + v3)
            }
        }
    }

In the above example, `b` and `c` automatically captures `v1`, so we don’t need 
to pass these values here and there. If `c` was a free function, it should have 
three arguments. Also, this capture does not introduce any extra 
order-dependency.

— Hoon H.





_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to