fredrikekre / Runic.jl

A code formatter for Julia with rules set in stone.
MIT License
103 stars 3 forks source link

Recurse into if/try branches for explicit returns #52

Open fredrikekre opened 2 months ago

fredrikekre commented 2 months ago

Currently Runic will format something e.g.

function foo()
    if condition
        x
    else
        y
    end
end

into

function foo()
    return if condition
        x
    else
        y
    end
end

However, looking at some real world code examples of this it seems that about 50% of the time returning whatever value comes out of the if is not intended and adding return after the block is a better "fix". e.g.

function foo()
    if condition
        x
    else
        y
    end
    return
end

and around 50% or the time it is better to insert the returns inside the branches, e.g.

function foo()
    if condition
        return x
    else
        return y
    end
end

Some potential changes to the current setup:

The same discussion applies to try, but for try it can actually improve readability a bit too since it isn't obvious what the possible return values are in e.g.

function foo()
    try
        rand() < 0.5 && error("error")
        "try_value"
    catch err
        "catch_value"
    else
        "else_value"
    finally
        "finally_value"
    end
end

so making it explicit is a good idea, e.g.

function foo()
    try
        rand() < 0.5 && error("error")
        "try_value"
    catch err
        return "catch_value"
    else
        return "else_value"
    finally
        "finally_value"
    end
end
fredrikekre commented 2 months ago

For try I think the rules would be:

  1. If there is a finally branch with return this will override any other return so it is misleading to add return in any other branch (perhaps Runic should even remove existing ones?)
  2. If there is an else it can always have return except it is misleading to add if 1. or if the try block has a return.
  3. The catch block can always have it except misleading if 1.
  4. The try block can have it if there is no else and if not 1.