Skip to content

Commit

Permalink
Merge pull request #19702 from JuliaLang/ksh/manual
Browse files Browse the repository at this point in the history
More backticks/refs for manual and add docs about references
  • Loading branch information
kshyatt authored Dec 27, 2016
2 parents 0a0c41c + fbd4388 commit 6faf31e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 45 deletions.
4 changes: 2 additions & 2 deletions doc/src/manual/control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ julia> consume(p)
One way to think of this behavior is that `producer` was able to return multiple times. Between
calls to [`produce()`](@ref), the producer's execution is suspended and the consumer has control.

A Task can be used as an iterable object in a `for` loop, in which case the loop variable takes
A [`Task`](@ref) can be used as an iterable object in a `for` loop, in which case the loop variable takes
on all the produced values:

```julia
Expand Down Expand Up @@ -967,7 +967,7 @@ or [`@async`](@ref) macros (see [Parallel Computing](@ref) for more details).

### Task states

Tasks have a `state` field that describes their execution status. A task state is one of the following
Tasks have a `state` field that describes their execution status. A [`Task`](@ref) `state` is one of the following
symbols:

| Symbol | Meaning |
Expand Down
25 changes: 23 additions & 2 deletions doc/src/manual/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ As in the example above, we recommend following some simple conventions when wri

## Accessing Documentation

Documentation can be accessed at the REPL or in IJulia by typing `?` followed by the name of a
function or macro, and pressing `Enter`. For example,
Documentation can be accessed at the REPL or in [IJulia](https://github.com/JuliaLang/IJulia.jl)
by typing `?` followed by the name of a function or macro, and pressing `Enter`. For example,

```julia
?fft
Expand Down Expand Up @@ -585,6 +585,27 @@ parentheses, `( )`, is the URL.
A paragraph containing a link to [Julia](http://www.julialang.org).
```

It's also possible to add cross-references to other documented functions/methods/variables within
the Julia documentation itself. For example:

```julia
"""
eigvals!(A,[irange,][vl,][vu]) -> values
Same as [`eigvals`](@ref), but saves space by overwriting the input `A`, instead of creating a copy.
"""
```

This will create a link in the generated docs to the `eigvals` documentation
(which has more information about what this function actually does). It's good to include
cross references to mutating/non-mutating versions of a function, or to highlight a difference
between two similar-seeming functions.

!!! note
The above cross referencing is *not* a Markdown feature, and relies on
[Documenter.jl](https://github.com/JuliaDocs/Documenter.jl), which is
used to build base Julia's documentation.

#### Footnote references

Named and numbered footnote references can be written using the following syntax. A footnote name
Expand Down
56 changes: 28 additions & 28 deletions doc/src/manual/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ to generically build upon those behaviors.
| `next(iter, state)` |   | Returns the current item and the next state |
| `done(iter, state)` |   | Tests if there are any items remaining |
| **Important optional methods** | **Default definition** | **Brief description** |
| `iteratorsize(IterType)` | `HasLength()` | One of *HasLength()*, *HasShape()*, *IsInfinite()*, or *SizeUnknown()* as appropriate |
| `iteratoreltype(IterType)` | `HasEltype()` | Either *EltypeUnknown()* or *HasEltype()* as appropriate |
| `iteratorsize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape()`, `IsInfinite()`, or `SizeUnknown()` as appropriate |
| `iteratoreltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate |
| `eltype(IterType)` | `Any` | The type the items returned by `next()` |
| `length(iter)` | (*undefined*) | The number of items, if known |
| `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, if known |

| Value returned by `iteratorsize(IterType)` | Required Methods |
|:------------------------------------------ |:------------------------------------------ |
| *HasLength()* | `length(iter)` |
| *HasShape()* | `length(iter)` and `size(iter, [dim...])` |
| *IsInfinite()* | (*none*) |
| *SizeUnknown()* | (*none*) |
| `HasLength()` | `length(iter)` |
| `HasShape()` | `length(iter)` and `size(iter, [dim...])` |
| `IsInfinite()` | (*none*) |
| `SizeUnknown()` | (*none*) |

| Value returned by `iteratoreltype(IterType)` | Required Methods |
|:-------------------------------------------- |:------------------ |
| *HasEltype()* | `eltype(IterType)` |
| *EltypeUnknown()* | (*none*) |
| `HasEltype()` | `eltype(IterType)` |
| `EltypeUnknown()` | (*none*) |

Sequential iteration is implemented by the methods `start()`, `done()`, and `next()`. Instead
Sequential iteration is implemented by the methods [`start()`](@ref), [`done()`](@ref), and [`next()`](@ref). Instead
of mutating objects as they are iterated over, Julia provides these three methods to keep track
of the iteration state externally from the object. The `start(iter)` method returns the initial
state for the iterable object `iter`. That state gets passed along to `done(iter, state)`, which
Expand Down Expand Up @@ -71,7 +71,7 @@ julia> immutable Squares
Base.length(S::Squares) = S.count;
```

With only `start`, `next`, and `done` definitions, the `Squares` type is already pretty powerful.
With only [`start`](@ref), [`next`](@ref), and [`done`](@ref) definitions, the `Squares` type is already pretty powerful.
We can iterate over all the elements:

```julia
Expand All @@ -87,7 +87,7 @@ julia> for i in Squares(7)
49
```

We can use many of the builtin methods that work with iterables, like `in()`, `mean()` and `std()`:
We can use many of the builtin methods that work with iterables, like [`in()`](@ref), [`mean()`](@ref) and [`std()`](@ref):

```julia
julia> 25 in Squares(10)
Expand All @@ -99,12 +99,12 @@ julia> mean(Squares(100)), std(Squares(100))

There are a few more methods we can extend to give Julia more information about this iterable
collection. We know that the elements in a `Squares` sequence will always be `Int`. By extending
the `eltype()` method, we can give that information to Julia and help it make more specialized
the [`eltype()`](@ref) method, we can give that information to Julia and help it make more specialized
code in the more complicated methods. We also know the number of elements in our sequence, so
we can extend `length()`, too.
we can extend [`length()`](@ref), too.

Now, when we ask Julia to `collect()` all the elements into an array it can preallocate a `Vector{Int}`
of the right size instead of blindly `push!`ing each element into a `Vector{Any}`:
Now, when we ask Julia to [`collect()`](@ref) all the elements into an array it can preallocate a `Vector{Int}`
of the right size instead of blindly [`push!`](@ref)ing each element into a `Vector{Any}`:

```julia
julia> collect(Squares(100))' # transposed to save space
Expand Down Expand Up @@ -137,7 +137,7 @@ be used in their specific case.

For the `Squares` iterable above, we can easily compute the `i`th element of the sequence by squaring
it. We can expose this as an indexing expression `S[i]`. To opt into this behavior, `Squares`
simply needs to define `getindex()`:
simply needs to define [`getindex()`](@ref):

```julia
julia> function Base.getindex(S::Squares, i::Int)
Expand All @@ -148,7 +148,7 @@ julia> function Base.getindex(S::Squares, i::Int)
529
```

Additionally, to support the syntax `S[end]`, we must define `endof()` to specify the last valid
Additionally, to support the syntax `S[end]`, we must define [`endof()`](@ref) to specify the last valid
index:

```julia
Expand All @@ -157,9 +157,9 @@ julia> Base.endof(S::Squares) = length(S)
529
```

Note, though, that the above *only* defines `getindex()` with one integer index. Indexing with
anything other than an `Int` will throw a `MethodError` saying that there was no matching method.
In order to support indexing with ranges or vectors of Ints, separate methods must be written:
Note, though, that the above *only* defines [`getindex()`](@ref) with one integer index. Indexing with
anything other than an `Int` will throw a [`MethodError`](@ref) saying that there was no matching method.
In order to support indexing with ranges or vectors of `Int`s, separate methods must be written:

```julia
julia> Base.getindex(S::Squares, i::Number) = S[convert(Int, i)]
Expand Down Expand Up @@ -204,7 +204,7 @@ If a type is defined as a subtype of `AbstractArray`, it inherits a very large s
including iteration and multidimensional indexing built on top of single-element access. See
the [arrays manual page](@ref man-multi-dim-arrays) and [standard library section](@ref lib-arrays) for more supported methods.

A key part in defining an `AbstractArray` subtype is `Base.linearindexing()`. Since indexing is
A key part in defining an `AbstractArray` subtype is [`Base.linearindexing()`](@ref). Since indexing is
such an important part of an array and often occurs in hot loops, it's important to make both
indexing and indexed assignment as efficient as possible. Array data structures are typically
defined in one of two ways: either it most efficiently accesses its elements using just one index
Expand Down Expand Up @@ -234,7 +234,7 @@ julia> immutable SquaresVector <: AbstractArray{Int, 1}
```

Note that it's very important to specify the two parameters of the `AbstractArray`; the first
defines the `eltype()`, and the second defines the `ndims()`. That supertype and those three
defines the [`eltype()`](@ref), and the second defines the [`ndims()`](@ref). That supertype and those three
methods are all it takes for `SquaresVector` to be an iterable, indexable, and completely functional
array:

Expand All @@ -261,7 +261,7 @@ julia> s \ rand(7,2)
```

As a more complicated example, let's define our own toy N-dimensional sparse-like array type built
on top of `Dict`:
on top of [`Dict`](@ref):

```julia
julia> immutable SparseArray{T,N} <: AbstractArray{T,N}
Expand All @@ -279,8 +279,8 @@ julia> Base.size(A::SparseArray) = A.dims
Base.setindex!{T,N}(A::SparseArray{T,N}, v, I::Vararg{Int,N}) = (A.data[I] = v)
```

Notice that this is a `LinearSlow` array, so we must manually define `getindex()` and `setindex!()`
at the dimensionality of the array. Unlike the `SquaresVector`, we are able to define `setindex!()`,
Notice that this is a `LinearSlow` array, so we must manually define [`getindex()`](@ref) and [`setindex!()`](@ref)
at the dimensionality of the array. Unlike the `SquaresVector`, we are able to define [`setindex!()`](@ref),
and so we can mutate the array:

```julia
Expand All @@ -304,7 +304,7 @@ julia> A[:] = 1:length(A); A
```

The result of indexing an `AbstractArray` can itself be an array (for instance when indexing by
a `Range`). The `AbstractArray` fallback methods use `similar()` to allocate an `Array` of the
a `Range`). The `AbstractArray` fallback methods use [`similar()`](@ref) to allocate an `Array` of the
appropriate size and element type, which is filled in using the basic indexing method described
above. However, when implementing an array wrapper you often want the result to be wrapped as
well:
Expand All @@ -319,7 +319,7 @@ julia> A[1:2,:]
In this example it is accomplished by defining `Base.similar{T}(A::SparseArray, ::Type{T}, dims::Dims)`
to create the appropriate wrapped array. (Note that while `similar` supports 1- and 2-argument
forms, in most case you only need to specialize the 3-argument form.) For this to work it's important
that `SparseArray` is mutable (supports `setindex!`). `similar()` is also used to allocate result
that `SparseArray` is mutable (supports `setindex!`). [`similar()`](@ref) is also used to allocate result
arrays for arithmetic on `AbstractArrays`, for instance:

```julia
Expand All @@ -345,7 +345,7 @@ julia> dot(A[:,1],A[:,2])
```

If you are defining an array type that allows non-traditional indexing (indices that start at
something other than 1), you should specialize `indices`. You should also specialize `similar`
something other than 1), you should specialize `indices`. You should also specialize [`similar`](@ref)
so that the `dims` argument (ordinarily a `Dims` size-tuple) can accept `AbstractUnitRange` objects,
perhaps range-types `Ind` of your own design. For more information, see [Arrays with custom indices](@ref).

26 changes: 13 additions & 13 deletions doc/src/manual/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ Note that relative-import qualifiers are only valid in `using` and `import` stat

### Module file paths

The global variable LOAD_PATH contains the directories Julia searches for modules when calling
`require`. It can be extended using `push!`:
The global variable [`LOAD_PATH`](@ref) contains the directories Julia searches for modules when calling
`require`. It can be extended using [`push!`](@ref):

```julia
push!(LOAD_PATH, "/Path/To/My/Module/")
```

Putting this statement in the file `~/.juliarc.jl` will extend LOAD_PATH on every Julia startup.
Alternatively, the module load path can be extended by defining the environment variable JULIA_LOAD_PATH.
Putting this statement in the file `~/.juliarc.jl` will extend [`LOAD_PATH`](@ref) on every Julia startup.
Alternatively, the module load path can be extended by defining the environment variable `JULIA_LOAD_PATH`.

### Namespace miscellanea

Expand Down Expand Up @@ -334,9 +334,9 @@ Other known potential failure scenarios include:
from that same counter value.

Note that `object_id` (which works by hashing the memory pointer) has similar issues (see notes
on Dict usage below).
on `Dict` usage below).

One alternative is to store both `current_module()` and the current `counter` value, however,
One alternative is to store both [`current_module()`](@ref) and the current `counter` value, however,
it may be better to redesign the code to not depend on this global state.
2. Associative collections (such as `Dict` and `Set`) need to be re-hashed in `__init__`. (In the
future, a mechanism may be provided to register an initializer function.)
Expand All @@ -357,26 +357,26 @@ Other known potential failure scenarios include:
Several additional restrictions are placed on the operations that can be done while precompiling
code to help the user avoid other wrong-behavior situations:

1. Calling `eval` to cause a side-effect in another module. This will also cause a warning to be
1. Calling [`eval`](@ref) to cause a side-effect in another module. This will also cause a warning to be
emitted when the incremental precompile flag is set.
2. `global const` statements from local scope after `__init__()` has been started (see issue #12010
for plans to add an error for this)
3. Replacing a module (or calling `workspace()`) is a runtime error while doing an incremental precompile.
3. Replacing a module (or calling [`workspace()`](@ref)) is a runtime error while doing an incremental precompile.

A few other points to be aware of:

1. No code reload / cache invalidation is performed after changes are made to the source files themselves,
(including by `Pkg.update`), and no cleanup is done after `Pkg.rm`
(including by [`Pkg.update`](@ref)), and no cleanup is done after [`Pkg.rm`](@ref)
2. The memory sharing behavior of a reshaped array is disregarded by precompilation (each view gets
its own copy)
3. Expecting the filesystem to be unchanged between compile-time and runtime e.g. `@__FILE__`/`source_path()`
3. Expecting the filesystem to be unchanged between compile-time and runtime e.g. [`@__FILE__`](@ref)/`source_path()`
to find resources at runtime, or the BinDeps `@checked_lib` macro. Sometimes this is unavoidable.
However, when possible, it can be good practice to copy resources into the module at compile-time
so they won't need to be found at runtime.
4. WeakRef objects and finalizers are not currently handled properly by the serializer (this will
4. `WeakRef` objects and finalizers are not currently handled properly by the serializer (this will
be fixed in an upcoming release).
5. It is usually best to avoid capturing references to instances of internal metadata objects such
as Method, MethodInstance, MethodTable, TypeMapLevel, TypeMapEntry and fields of those objects,
as `Method`, `MethodInstance`, `MethodTable`, `TypeMapLevel`, `TypeMapEntry` and fields of those objects,
as this can confuse the serializer and may not lead to the outcome you desire. It is not necessarily
an error to do this, but you simply need to be prepared that the system will try to copy some
of these and to create a single unique instance of others.
Expand All @@ -386,5 +386,5 @@ command line flag `--compilecache={yes|no}` enables you to toggle module precomp
off. When Julia is started with `--compilecache=no` the serialized modules in the compile cache
are ignored when loading modules and module dependencies. `Base.compilecache()` can still be called
manually and it will respect `__precompile__()` directives for the module. The state of this command
line flag is passed to `Pkg.build()` to disable automatic precompilation triggering when installing,
line flag is passed to [`Pkg.build()`](@ref) to disable automatic precompilation triggering when installing,
updating, and explicitly building packages.

0 comments on commit 6faf31e

Please sign in to comment.