@@ -134,6 +134,32 @@ a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n)
134
134
In this case ` Vector{Any}(undef, n) ` is better. It is also more helpful to the compiler to annotate specific
135
135
uses (e.g. ` a[i]::Int ` ) than to try to pack many alternatives into one type.
136
136
137
+ ## Prefer exported methods over direct field access
138
+
139
+ Idiomatic Julia code should generally treat a module's exported methods as the
140
+ interface to its types. An object's fields are generally considered
141
+ implementation details and user code should only access them directly if this
142
+ is stated to be the API. This has several benefits:
143
+
144
+ - Package developers are freer to change the implementation without breaking
145
+ user code.
146
+ - Methods can be passed to higher-order constructs like [ ` map ` ] ( @ref ) (e.g.
147
+ ` map(imag, zs)) ` rather than ` [z.im for z in zs] ` ).
148
+ - Methods can be defined on abstract types.
149
+ - Methods can describe a conceptual operation that can be shared across
150
+ disparate types (e.g. ` real(z) ` works on Complex numbers or Quaternions).
151
+
152
+ Julia's dispatch system encourages this style because ` play(x::MyType) ` only
153
+ defines the ` play ` method on that particular type, leaving other types to
154
+ have their own implementation.
155
+
156
+ Similarly, non-exported functions are typically internal and subject to change,
157
+ unless the documentations states otherwise. Names sometimes are given a ` _ ` prefix
158
+ (or suffix) to further suggest that something is "internal" or an
159
+ implementation-detail, but it is not a rule.
160
+
161
+ Counter-examples to this rule include [ ` NamedTuple ` ] ( @ref ) , [ ` RegexMatch ` ] (@ref match), [ ` StatStruct ` ] (@ref stat).
162
+
137
163
## Use naming conventions consistent with Julia ` base/ `
138
164
139
165
* modules and type names use capitalization and camel case: ` module SparseArrays ` , ` struct UnitRange ` .
0 commit comments