SciML Style Guide for Julia
The SciML Style Guide is a style guide for the Julia programming language. It is used by the SciML Open Source Scientific Machine Learning Organization. As such, it is open to discussion with the community. Please file an issue or open a PR to discuss changes to the style guide.
Table of Contents
- SciML Style Guide for Julia
- Code Style Badge
- Overarching Dogmas of the SciML Style
- Consistency vs Adherence
- Community Contribution Guidelines
- Open source contributions are allowed to start small and grow over time
- Generic code is preferred unless code is known to be specific
- Internal types should match the types used by users when possible
- Trait definition and adherence to generic interface is preferred when possible
- Macros should be limited and only be used for syntactic sugar
- Errors should be caught as high as possible, and error messages should be contextualized for newcomers
- Subpackaging and interface packages is preferred over conditional modules via Requires.jl
- Functions should either attempt to be non-allocating and reuse caches, or treat inputs as immutable
- Out-Of-Place and Immutability is preferred when sufficient performant
- Tests should attempt to cover a wide gamut of input types
- When in doubt, a submodule should become a subpackage or separate package
- Globals should be avoided whenever possible
- Type-stable and Type-grounded code is preferred wherever possible
- Closures should be avoided whenever possible
- Numerical functionality should use the appropriate generic numerical interfaces
- Functions should capture one underlying principle
- Internal choices should be exposed as options whenever possible
- Prefer code reuse over rewrites whenever possible
- Prefer to not shadow functions
- Avoid unmaintained dependencies
- Avoid unsafe operations
- Avoid non public operations in Julia Base and packages
- Always default to constructs which initialize data
- Use extra precaution when running external processes
- Avoid eval whenever possible
- Avoid bounds check removal, and if done, add appropriate manual checks
- Avoid ccall unless necessary, and use safe ccall practices when required
- Validate all user inputs to avoid code injection
- Ensure secure random number generators are used when required
- Be aware of distributed computing encryption principles
- Always immediately flush secret data after handling
- Specific Rules
- High Level Rules
- General Naming Principles
- Comments
- Modules
- Functions
- Function Argument Precedence
- Tests and Continuous Integration
- Whitespace
- NamedTuples
- Numbers
- Ternary Operator
- For loops
- Function Type Annotations
- Struct Type Annotations
- Macros
- Types and Type Annotations
- Package version specifications
- Documentation
- Error Handling
- Arrays
- Line Endings
- VS-Code Settings
- JuliaFormatter
- References
Code Style Badge
Let contributors know your project is following the SciML Style Guide by adding the badge to your README.md
.
[![SciML Code Style](https://img.shields.io/static/v1?label=code%20style&message=SciML&color=9558b2&labelColor=389826)](https://github.com/SciML/SciMLStyle)
Overarching Dogmas of the SciML Style
Consistency vs Adherence
According to PEP8:
A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is the most important.
But most importantly: know when to be inconsistent – sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!
Some code within the SciML organization is old, on life support, donated by researchers to be maintained. Consistency is the number one goal, so updating to match the style guide should happen on a repo-by-repo basis, i.e. do not update one file to match the style guide (leaving all other files behind).
Community Contribution Guidelines
For a comprehensive set of community contribution guidelines, refer to ColPrac. A relevant point to highlight PRs should do one thing. In the context of style, this means that PRs that update the style of a package's code should not be mixed with fundamental code contributions. This separation makes it easier to ensure that large style improvements are isolated from substantive (and potentially breaking) code changes.
Open source contributions are allowed to start small and grow over time
If the standard for code contributions is that every PR needs to support every possible input type that anyone can think of, the barrier would be too high for newcomers. Instead, the principle is to be as correct as possible to begin with, and grow the generic support over time. All recommended functionality should be tested, and any known generality issues should be documented in an issue (and with a @test_broken
test when possible). However, a function that is known to not be GPU-compatible is not grounds to block merging, rather it is encouraged for a follow-up PR to improve the general type support!
Generic code is preferred unless code is known to be specific
For example, the code:
function f(A, B)
+SciML Style Guide for Julia · SciML Style Guide for Julia SciML Style Guide for Julia
The SciML Style Guide is a style guide for the Julia programming language. It is used by the SciML Open Source Scientific Machine Learning Organization. As such, it is open to discussion with the community. Please file an issue or open a PR to discuss changes to the style guide.
Table of Contents
- SciML Style Guide for Julia
- Code Style Badge
- Overarching Dogmas of the SciML Style
- Consistency vs Adherence
- Community Contribution Guidelines
- Open source contributions are allowed to start small and grow over time
- Generic code is preferred unless code is known to be specific
- Internal types should match the types used by users when possible
- Trait definition and adherence to generic interface is preferred when possible
- Macros should be limited and only be used for syntactic sugar
- Errors should be caught as high as possible, and error messages should be contextualized for newcomers
- Subpackaging and interface packages is preferred over conditional modules via Requires.jl
- Functions should either attempt to be non-allocating and reuse caches, or treat inputs as immutable
- Out-Of-Place and Immutability is preferred when sufficient performant
- Tests should attempt to cover a wide gamut of input types
- When in doubt, a submodule should become a subpackage or separate package
- Globals should be avoided whenever possible
- Type-stable and Type-grounded code is preferred wherever possible
- Closures should be avoided whenever possible
- Numerical functionality should use the appropriate generic numerical interfaces
- Functions should capture one underlying principle
- Internal choices should be exposed as options whenever possible
- Prefer code reuse over rewrites whenever possible
- Prefer to not shadow functions
- Avoid unmaintained dependencies
- Avoid unsafe operations
- Avoid non public operations in Julia Base and packages
- Always default to constructs which initialize data
- Use extra precaution when running external processes
- Avoid eval whenever possible
- Avoid bounds check removal, and if done, add appropriate manual checks
- Avoid ccall unless necessary, and use safe ccall practices when required
- Validate all user inputs to avoid code injection
- Ensure secure random number generators are used when required
- Be aware of distributed computing encryption principles
- Always immediately flush secret data after handling
- Specific Rules
- High Level Rules
- General Naming Principles
- Comments
- Modules
- Functions
- Function Argument Precedence
- Tests and Continuous Integration
- Whitespace
- NamedTuples
- Numbers
- Ternary Operator
- For loops
- Function Type Annotations
- Struct Type Annotations
- Macros
- Types and Type Annotations
- Package version specifications
- Documentation
- Error Handling
- Arrays
- Line Endings
- VS-Code Settings
- JuliaFormatter
- References
Code Style Badge
Let contributors know your project is following the SciML Style Guide by adding the badge to your README.md
.
[![SciML Code Style](https://img.shields.io/static/v1?label=code%20style&message=SciML&color=9558b2&labelColor=389826)](https://github.com/SciML/SciMLStyle)
Overarching Dogmas of the SciML Style
Consistency vs Adherence
According to PEP8:
A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is the most important.
But most importantly: know when to be inconsistent – sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!
Some code within the SciML organization is old, on life support, donated by researchers to be maintained. Consistency is the number one goal, so updating to match the style guide should happen on a repo-by-repo basis, i.e. do not update one file to match the style guide (leaving all other files behind).
Community Contribution Guidelines
For a comprehensive set of community contribution guidelines, refer to ColPrac. A relevant point to highlight PRs should do one thing. In the context of style, this means that PRs that update the style of a package's code should not be mixed with fundamental code contributions. This separation makes it easier to ensure that large style improvements are isolated from substantive (and potentially breaking) code changes.
Open source contributions are allowed to start small and grow over time
If the standard for code contributions is that every PR needs to support every possible input type that anyone can think of, the barrier would be too high for newcomers. Instead, the principle is to be as correct as possible to begin with, and grow the generic support over time. All recommended functionality should be tested, and any known generality issues should be documented in an issue (and with a @test_broken
test when possible). However, a function that is known to not be GPU-compatible is not grounds to block merging, rather it is encouraged for a follow-up PR to improve the general type support!
Generic code is preferred unless code is known to be specific
For example, the code:
function f(A, B)
for i in 1:length(A)
A[i] = A[i] + B[i]
end
@@ -261,4 +261,4 @@
"files.eol": "\n"
},
}
Additionally, you may find the Julia VS-Code plugin useful.
JuliaFormatter
Note: the sciml
style is only available in JuliaFormatter v1.0
or later
One can add .JuliaFormatter.toml
with the content
style = "sciml"
in the root of a repository, and run
using JuliaFormatter, SomePackage
-format(joinpath(dirname(pathof(SomePackage)), ".."))
to format the package automatically.
Add FormatCheck.yml to enable the formatting CI. The CI will fail if the repository needs additional formatting. Thus, one should run format
before committing.
References
Many of these style choices were derived from the Julia style guide, the YASGuide, and the Blue style guide. Additionally, many tips and requirements from the JuliaHub Secure Coding Practices manual were incorporated into this style.
Settings
This document was generated with Documenter.jl version 1.1.2 on Sunday 19 November 2023. Using Julia version 1.9.4.
+format(joinpath(dirname(pathof(SomePackage)), ".."))
to format the package automatically.
Add FormatCheck.yml to enable the formatting CI. The CI will fail if the repository needs additional formatting. Thus, one should run format
before committing.
References
Many of these style choices were derived from the Julia style guide, the YASGuide, and the Blue style guide. Additionally, many tips and requirements from the JuliaHub Secure Coding Practices manual were incorporated into this style.