Line break and indentation with where

I find that I am writing long function signatures with where, and wondering about the proper formatting and style. Suppose one wants to put a linebreak in

function LongConstructorName(value::T, gradient::S) where {T <: Real, S <: AbstractVector{T}}
   1+1
end
  1. doing it before where is not allowed AFAICT,

  2. doing it after where

    function LongConstructorName(value::T, gradient::S)
        where {T <: Real, S <: AbstractVector{T}}
        1+1
    end
    

    which is how it is indented in Emacs merges the code visually with the where, should this be fixed?

  3. the indented version is slightly better

    function LongConstructorName(value::T, gradient::S)
            where {T <: Real, S <: AbstractVector{T}}
        1+1
    end
    

Is there a better approach?

What about?

function LongConstructorName(
    value::T, gradient::S
) where {T <: Real, S <: AbstractVector{T}}
    1+1
end

here doing

function LongConstructorName(
        value::T, gradient::S
    ) where {T <: Real, S <: AbstractVector{T}}
    1+1
end

would also probably be better.

A more extreme case, emacs indentation:

function LongConstructorName(
    value::T, gradient::S
) where {
    T <: Real, S <: AbstractVector{T}
}
    1+1
end

which should then also be:

function LongConstructorName(
        value::T, gradient::S
    ) where {
        T <: Real, S <: AbstractVector{T}
    }
    1+1
end

where must follow the closing ) of the function arglist on the same line as that closing paren. That ) itself can be on the line following the final arg of the arglist, or not.

the wherefores that follow where should be in { } (it looks better and is easier to read, although it is not now required). That part of the function signature does not have to be on the same line.

if function begins in column 1, then the function declaration/specification/definition ends with end in column 1. None of the lines of program source text between them should start in the first column. This is long standing practice, you may prefer stepping in with 4spaces [which is most commonly used (see Base)] or some other favorite indent. Doing so makes your code much more transparent to others.

Without thinking too long about it, I would probably be inclined to do

function LongConstructorName(value::T, gradient::S) where
                            {T <: Real, S <: AbstractVector{T}}
    1+1
end

although I could easily see myself doing

function LongConstructorName(value::T,
                             gradient::S) where {T <: Real,
                                                 S <: AbstractVector{T}}
    1+1
end

just because my editor would be helpful with it.