madlambda / nash

Nash stands for Nash shell.
Apache License 2.0
157 stars 11 forks source link

language: support to defer #160

Open katcipis opened 7 years ago

katcipis commented 7 years ago

Shell has a crappy support to cleanup using traps, a good use case is to remove temporary directories:

file=$(mktemp file.XXXXXXX)
trap "rm -f $file" EXIT

# Rest of the shell script

Nash can be more awesome:

file <= mktemp file.XXXXXXX
defer fn() {
    rm -f $file
}()
# Rest of the shell script
i4ki commented 7 years ago

Defer must works only with function? Or the code below should work also ?

fn somefunc() {
     file <= mktemp file.XXXXXXX
     defer rm -f $file

     # rest of the func
}

Every function will have a list of zero or more defer functions to execute after the surrounding function returns, right? And they will execute in the same order as Go does (Last in First Out) ?

The semantics of the syntax construct defer <statement> must be similar to Go semantics? The arguments of the defer function must be evaluated at defer declaration evaluation ?

The above is important to make the code below works as expected:

fn somefunc() {
    file <= mktemp file.XXXXXX

    defer fn(file) {
        rm -f $file
    }($file)

    file = ""

    # rest of the function
    return
}

And more importantly: Do you think it should work in the global scope also? Your first example appear to be the case.

i4ki commented 7 years ago

@katcipis

katcipis commented 7 years ago

1 - "Defer must works only with function?"

If it makes things simpler, sure, defining anonymous functions in nash is a breeze :-)

2 - "Every function will have a list of zero or more defer functions to execute after the surrounding function returns, right? And they will execute in the same order as Go does (Last in First Out) ?"

Yes and Yes. LIFO makes sense because of constructor/destructor relationship created by the ordering of the functions definitions.

3 - "The semantics of the syntax construct defer must be similar to Go semantics? The arguments of the defer function must be evaluated at defer declaration evaluation ?"

Yes, it makes sense to me at least, Go designers had made a lot of sensible choices, lets steal them :-).

4 - "Do you think it should work in the global scope also?"

Well, I can circumvent not having this by defining something like a main function and just calling it on the script. If it is horrible to implement, we can survive without, if it is trivial it seems cool as a perfect substitute for the trap thing. What you think ?