I recently read through BlueStyle (and YASGuide). There are a few items that feel strange to me. I’ll probably conform and get used to it, but I could use some more convincing on why my way is worse.
-
Why so vertical?
Characters per line is limited to 80 or 92, but that is only around 1/3 of my 16:9 monitor’s width. -
Is one tab per nest level really easier to read than vertical alignment?
I write containers so they vertically align to the nearest tab. (Aligning to the exact space would be visually better, but that is too finicky to type.) Did the nested container formatting decision drive the line length decision or vice versa?
-
Why limit inline comments?
The other place this character per line limit gets in the way is with inline comments. Within a function, I define sections with comments and use inline comments to clarify what is happening. If my inline comments need to move above the line to meet the line length requirement, then my inline and section comments are going to get jumbled together. Also, if I see a non-header comment within a code block, I will think it is code I commented out for debugging. When respecting BlueStyle, what is the best way to differentiate comment types?
-
Is that the best place for function definition closing parenthesis?
It really bugs me in the following code copied from BlueStyle for function definitions that the closing parenthesis is left-aligned but is not the end of the code block. I prefer the “No” version for that reason.
# Yes:
function foobar(
df::DataFrame,
id::Symbol,
variable::Symbol,
)
# code
end
# No: Indented too much.
function foobar(
df::DataFrame,
id::Symbol,
variable::Symbol,
)
# code
end
-
When to use
@assert
vs.throw(ArgumentError)
?
I didn’t know about@assert
before, but BlueStyle says not to use it. It seems like@assert
is made for input checking and thus could clean up that section of code from my last screenshot. Should I really avoid it? -
Should blank lines have strict rules?
I use blank lines to separate sections, so I don’t add them between related control flows, or methods linked to the same docstring. BlueStyle also says I should avoid the blank line afterfunction
but I sometimes do to make the section header stand out better.
-
Should Docstrings show a return variable?
I generally like this docstring template from BlueStyle except that it indicates to me thatInt
itself is returned from the function not a variable of type Int (result::Int
). I think you should have to list and name your Returns the same way you list and name your Arguments, especially for functions that return multiple values. What if I return twoInt
s? (The Throws section seems unnecessary too. The user can find out about errors, if they happen, in the thrown string.)
"""
mysearch(array::MyArray{T}, val::T; verbose=true) where {T} -> Int
Searches the `array` for the `val`. For some reason we don't want to use Julia's
builtin search :)
# Arguments
- `array::MyArray{T}`: the array to search
- `val::T`: the value to search for
# Keywords
- `verbose::Bool=true`: print out progress details
# Returns
- `Int`: the index where `val` is located in the `array`
# Throws
- `NotFoundError`: I guess we could throw an error if `val` isn't found.
"""
function mysearch(array::AbstractArray{T}, val::T) where T
...
end