Welcome to the discourse!
Well that indeed looks very odd and had me stumped for moment What happens is that this is the syntax for adding documentation to a symbol!
So if you write:
julia> "My string" a
a
Then this string is used as documentation for the symbol a. You can see for example that it appears in the help prompt:
help?> a
search: a as any all abs ans Any axes atan asin asec any! all! acsc acot acos abs2 atanh atand asinh asind asech asecd ascii angle acsch acscd acoth acotd acosh acosd Array ARGS atomic
My string
It’s meant for functions/methods (which ARE also symbols?!), if not arbitrary symbols.
I’m not sure you would ever use this for variables, or rely on that possibility, should it then error?
EDIT: I recalled pi is a constant (irrational) “variable”, so at least used for help strings of such. Out of curiosity, does Julia have any (non-constant) global variables? I was trying to think of some, and could only think of a seed for rand, and rand is global, maybe the seed, though it’s strictly thread-local (at least with the new rand). Anyway this at least needs to be a possibility, and I suppose for package code too, even though globals are in general bad, with few exceptions. The REPL could still warn about it in case wrong…
So I was probably not fully correct above. The documentation is not really attached to the symbol (which I think is how Common Lisp does it) but to the global variable of that name.
The terminology is a bit confusing but I’d say it’s the other way: the documentation is attached to the binding (i.e. the symbol) and not the object. So you can have different docstrings for different aliases:
julia> "The type for a vector" const Vec = Vector
Vec
help?> Vec
search: Vec vec Vector VecOrMat VecElement eigvecs BitVector DenseVector DenseVecOrMat StridedVector StridedVecOrMat AbstractVector
The type for a vector
julia> "The type for a Point" const Point = Vector
Point
help?> Vec
search: Vec vec Vector VecOrMat VecElement eigvecs BitVector DenseVector DenseVecOrMat StridedVector StridedVecOrMat AbstractVector
The type for a vector
help?> Point
search: Point pointer pointer_from_objref codepoint unsafe_pointer_to_objref typejoin position ComposedFunction process_running
The type for a Point
or for two bindings to the same array object:
julia> "array A" A = [1, 2, 3]
A
julia> "array B" B = A
B
help?> A
search: A as Any any all abs ARGS ans axes atan asin asec any! all! acsc acot acos abs2 Array atanh atand asinh asind asech asecd ascii angle
array A
help?> B
search: B Bool big BLAS Base bind break begin bswap BitSet BigInt BitArray BigFloat binomial basename Broadcast BitVector BitMatrix bytes2hex
array B
julia> "foo docstring"
function foo(x)
return x
end
foo
julia> const f = foo
foo (generic function with 1 method)
julia> "another alias for foo" const f2 = foo
f2
help?> foo
search: foo floor fourthroot pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError @functionloc OutOfMemoryError UndefKeywordError
foo docstring
help?> f
search: f fd for fma fld foo fld1 fill fdio frexp foldr foldl flush floor float first fill! fetch fldmod filter falses finally foreach fldmod1 findmin findmax findall filter! function
foo docstring
help?> f2
search: Float32 f2 Inf32 ComplexF32
another alias for foo
So function appear to know about “their” docstrings. Which makes sense I guess, since we can document methods individually. So the documentation needs to be attached to the actual function objects and not their names.
But apart from that it is most likely the binding/name/symbol that is documented and not the object underneath.
This isn’t entirely accurate, in that if you make an alias for a value (such as a function) but don’t attach documentation, Julia will still find the original documentation. If you document the alias, it won’t.
julia> "a foo function" foo(a, b, c) = a * b * c
foo
help?> foo
search: foo floor fourthroot pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError @functionloc
a foo function
julia> bar = foo
foo (generic function with 1 method)
help?> bar
search: bar baremodule SubArray GlobalRef clipboard BitArray backtrace BasicREPL BitMatrix catch_backtrace AbstractREPL AbstractRange AbstractArray
a foo function
julia> "a bar function" bar
bar
help?> bar
search: bar baremodule SubArray GlobalRef clipboard BitArray backtrace BasicREPL BitMatrix catch_backtrace AbstractREPL AbstractRange AbstractArray
a bar function
Note that this isn’t function-specific behavior, it generalizes:
julia> "my struct" struct MyStruct end
MyStruct
help?> MyStruct
search: MyStruct
my struct
julia> AnAlias = MyStruct
MyStruct
help?> AnAlias
search: AnAlias rationalize CanonicalIndexError
my struct
julia> "with an alias" AnAlias
AnAlias
help?> AnAlias
search: AnAlias rationalize CanonicalIndexError
with an alias